Orbital library

## orbital.math Interface Matrix

All Superinterfaces:
Arithmetic, Normed, Tensor

`public interface Matrixextends Tensor`

Represents a matrix of any dimension n×m.

Rn×m = { M=(mi,j) ¦ mi,j∈R} ≅ RnR Rm where

 M = (mi,j) = [ m0,0 , m0,1 , m0,2 , …, m0,m-1 ] m1,0 , m1,1 , m1,2 , …, m1,m-1 ⋮ ⋮ mn-1,0, mn-1,1, mn-1,2, …, mn-1,m-1
If the dimension is height×width then the matrix has height rows and width columns.

The components mi,j∈R are any arithmetic objects. If R is a true ring with 1, the square matrices (Rn×n,+,·,∙) form a unital, associative R-algebra with the laws of composition + and ∙ and the law of action ·. But it is non-commutative and has zero divisors for n≥2. The general matrices (Rn×m,+,·) form an R-module, at least, with the law of composition + and the law of action ·. If R is a field, the matrices even form an R-vector space.

If you intend to use mutable arithmetic elements, note the discussion of mutations per reference vs. explicit cloning in `Tensor.set(int[],Arithmetic)` which generally holds for all operations that set component values.

Also note that some few methods will change its instance and explicitly `return this` to allow chaining of structural changes, whilst arithmetic methods will leave a matrix unchanged but return a modified version. Refer to the documentation of the individual methods for details.

Author:
André Platzer
`ValueFactory.tensor(Arithmetic[][])`, `ValueFactory.valueOf(Arithmetic[][])`, `ValueFactory.valueOf(double[][])`
Invariants:
super ∧ rank()==2
Structure:
extends Tensor

Field Summary

Fields inherited from interface orbital.math.Arithmetic
`numerical`

Method Summary
` Matrix` `add(Matrix B)`
Adds two matrices returning a matrix.
` Matrix` `conjugate()`
Returns this matrix conjugate transposed.
.:Rn×m→Rm×n; MM:=tM = (ti,j) with ti,j = mj,i.
` Arithmetic` `det()`
Returns the determinant of the matrix representation.
` java.awt.Dimension` `dimension()`
Returns the dimension of the matrix.
` Arithmetic` ```get(int i, int j)```
Returns the component value at a position (i|j).
` Vector` `getColumn(int c)`
Returns the column vector view of a column.
` java.util.ListIterator` `getColumns()`
Returns an iterator over the column vectors.
` Vector` `getDiagonal()`
Returns the main-diagonal-vector of this square matrix.
` Vector` `getRow(int r)`
Returns the row vector view of a row.
` java.util.ListIterator` `getRows()`
Returns an iterator over the row vectors.
` Matrix` ```insertColumns(int index, Matrix cols)```
Insert columns into this matrix.
` Matrix` `insertColumns(Matrix cols)`
Append columns to this matrix.
` Matrix` ```insertRows(int index, Matrix rows)```
Insert rows into this matrix.
` Matrix` `insertRows(Matrix rows)`
Append rows to this matrix.
` int` `isDefinite()`
Checks how definite this square matrix is.
` boolean` `isInvertible()`
Checks whether this square matrix is regular.
` boolean` `isRegular()`
Deprecated. Since Orbital1.1 use `isInvertible()` instead.
` boolean` `isSquare()`
Checks whether this matrix is a square matrix of size n×n.
` boolean` `isSymmetric()`
Checks whether this square matrix is symmetric.
` java.util.ListIterator` `iterator()`
Returns an iterator over all components (row-wise).
` int` `linearRank()`
(linear) rank of this matrix.
` Matrix` `multiply(Matrix B)`
Multiplies two matrices returning a matrix.
` Matrix` `multiply(Scalar s)`
Multiplies a matrix with a scalar returning a matrix.
` Vector` `multiply(Vector B)`
Multiplies a matrix with a vector returning a vector.
` Real` `norm()`
Returns a norm ||.|| of this arithmetic object. Returns the sub-multiplicative Frobenius norm of this matrix.
` Real` `norm(double p)`
Returns the norm || ||p of this matrix.
` Matrix` `pseudoInverse()`
Returns the pseudo inverse matrix A+.
` Matrix` `removeColumn(int c)`
Remove a column from this matrix.
` Matrix` `removeRow(int r)`
Remove a row from this matrix.
` Matrix` `scale(Scalar s)`
Multiplies a matrix with a scalar returning a matrix.
` void` ```set(int i, int j, Arithmetic mij)```
Sets a component value at a position (i|j).
` void` ```setColumn(int c, Vector col)```
Sets the column vector at a column.
` void` ```setRow(int r, Vector row)```
Sets the row vector at a row.
` Matrix` ```subMatrix(int i1, int i2, int j1, int j2)```
Get a sub-matrix view ranging (i1:i2,j1:j2) inclusive.
` Matrix` `subtract(Matrix B)`
Subtracts two matrices returning a matrix.
` Arithmetic[][]` `toArray()`
Returns an array containing all the elements in this matrix.
` Arithmetic` `trace()`
Returns the trace of the matrix representation.
` Matrix` `transpose()`
Returns this matrix transposed.

Methods inherited from interface orbital.math.Tensor
`add, clone, dimensions, entries, get, indices, multiply, rank, set, setSubTensor, subTensor, subTensor, subTensorTransposed, subtract, tensor`

Methods inherited from interface orbital.math.Arithmetic
`add, divide, equals, inverse, isOne, isZero, minus, multiply, one, power, scale, subtract, toString, valueFactory, zero`

Method Detail

### dimension

`java.awt.Dimension dimension()`
Returns the dimension of the matrix.

### get

```Arithmetic get(int i,
int j)```
Returns the component value at a position (i|j).

Of course, this method only has a meaning for free modules like vector spaces.

Parameters:
`i` - the row of the value to get.
`j` - the column of the value to get.
Returns:
mi,j.

### set

```void set(int i,
int j,
Arithmetic mij)
throws java.lang.UnsupportedOperationException```
Sets a component value at a position (i|j).

Of course, this method only has a meaning for free modules like vector spaces.

Parameters:
`i` - the row of the value to set.
`j` - the column of the value to set.
`mij` - the value to set for the element mi,j at position (i|j)
Throws:
`java.lang.UnsupportedOperationException` - if this matrix is constant and does not allow this operation.

### getColumns

`java.util.ListIterator getColumns()`
Returns an iterator over the column vectors.

### getRows

`java.util.ListIterator getRows()`
Returns an iterator over the row vectors.

### iterator

`java.util.ListIterator iterator()`
Returns an iterator over all components (row-wise).

If you cannot avoid it, call transpose().iterator() to get an iterator over all components, column by column.

Specified by:
`iterator` in interface `Tensor`
Returns:
an iterator that iterates over {m0,0,…,m0,m-1, m1,0,…,m1,m-1,…, mn-1,0,…,mn-1,m-1}.

### getColumn

`Vector getColumn(int c)`
Returns the column vector view of a column.

The returned vector is a structurally unmodifiable view.

For Mi,j, bindSecond(c).

Returns:
a vector view of the specified column M(0:n-1,c:c) in this matrix.
`Functionals.bindSecond(orbital.logic.functor.BinaryFunction, Object)`

### setColumn

```void setColumn(int c,
Vector col)
throws java.lang.UnsupportedOperationException```
Sets the column vector at a column.

Throws:
`java.lang.UnsupportedOperationException`
Preconditions:
col.dimension() == dimension().height

### getRow

`Vector getRow(int r)`
Returns the row vector view of a row.

The returned vector is a structurally unmodifiable view.

For Mi,j bindFirst(r).

Returns:
a vector view of the specified row M(r:r,0:m-1) in this matrix.
`Functionals.bindFirst(orbital.logic.functor.BinaryFunction, Object)`

### setRow

```void setRow(int r,
Vector row)
throws java.lang.UnsupportedOperationException```
Sets the row vector at a row.

Throws:
`java.lang.UnsupportedOperationException`
Preconditions:
row.dimension() == dimension().width

### subMatrix

```Matrix subMatrix(int i1,
int i2,
int j1,
int j2)```
Get a sub-matrix view ranging (i1:i2,j1:j2) inclusive. That is Moeler notation.

The returned matrix is a structurally unmodifiable view.

Parameters:
`i1` - the top-most row index of the sub matrix view to get.
`i2` - the bottom-most row index of the sub matrix view to get.
`j1` - the left-most column index of the sub matrix view to get.
`j2` - the right-most column index of the sub matrix view to get.
Returns:
a matrix view of the specified part of this matrix.
 M(i1:i2,j1:j2) = (mi,j)i∈{i1,…,i2},j∈{j1,…,j2} = [ mi1,j1, …, mi1,j2 ] ⋮ ⋮ mi2,j1, …, mi2,j2
Preconditions:
i1≤i2 && j1≤j2 && valid(i1, j1) && valid(i2, j2)

### getDiagonal

`Vector getDiagonal()`
Returns the main-diagonal-vector of this square matrix. The vector that consists of mi,i.

Preconditions:
isSquare()

### isSquare

`boolean isSquare()`
Checks whether this matrix is a square matrix of size n×n.

Preconditions:
true
Postconditions:
RES == (dimension().width == dimension().height)

### isSymmetric

```boolean isSymmetric()
throws java.lang.ArithmeticException```
Checks whether this square matrix is symmetric. Symmetric matrices are those that satisfy MT = M alias mi,j=mj,i ∀i,j∈N.

In Rn×m, symmetric is the same as self-adjoint.

Throws:
`java.lang.ArithmeticException` - if this is not a square matrix since only square matrices can be symmetric.
Preconditions:
isSquare()
Postconditions:
RES.equals(transpose().equals(this))

### isInvertible

```boolean isInvertible()
throws java.lang.ArithmeticException```
Checks whether this square matrix is regular. Invertible matrices are also called regular, which are those with invertible determinant.

Returns:
`true` if this matrix is invertible and `false` if it is singular (linear rank<n).
Throws:
`java.lang.ArithmeticException` - if this is not a square matrix since only square matrices can be regular.
Preconditions:
isSquare()
Postconditions:
RES ⇔ det()∈R×

### isRegular

```boolean isRegular()
throws java.lang.ArithmeticException```
Deprecated. Since Orbital1.1 use `isInvertible()` instead.

Throws:
`java.lang.ArithmeticException`

### isDefinite

```int isDefinite()
throws java.lang.ArithmeticException```
Checks how definite this square matrix is.

f.ex. a symmetric matrix is positive definite iff every main minor is > 0. i.e. ∀i∈{0,…,n-1} det A(0:i,0:i) > 0. This means that every square submatrix that includes the element a0,0 has a strictly positive determinant.

C.f. Sylvester-normal form of quadratic forms.

Returns:
• d>0 if this matrix is positive definite, i.e. ∀x∈V∖{0} ⟨x,Ax⟩ > 0.
• d≥0 if this matrix is positive semi-definite, i.e. ∀x∈V ⟨x,Ax⟩ ≥ 0.
• d=0 if this matrix is indefinite, i.e. ∃x∈V ⟨x,Ax⟩ >0 ∧ ∃y∈V ⟨y,Ay⟩ <0.
• d≤0 if this matrix is negative semi-definite, i.e. ∀x∈V ⟨x,Ax⟩ ≤ 0.
• d<0 if this matrix is negative definite, i.e. ∀x∈V∖{0} ⟨x,Ax⟩ < 0.
Throws:
`java.lang.ArithmeticException` - if this is not a square matrix since only square matrices can be symmetric.
Preconditions:
isSquare() ∧ isSymmetric()?

### linearRank

`int linearRank()`
(linear) rank of this matrix. i.e. the maximum number of column vectors (or row vectors) that are linear independent.

Returns:
(linear) rank M := dimK(im(M)).
`Tensor.rank()`

### norm

`Real norm(double p)`
Returns the norm || ||p of this matrix.

||.||:Cn×m→[0,∞) is a matrix norm or consistent if it is a (vector) norm and

• xCn×m,yCm×l ||xy|| ≤ ||x||⋅||y|| (sub multiplicative)
||.|| is compatible or conform with the vector norms ||.||Cn, ||.||Cm if
• ACn×m, xCm ||Ax||Cn ≤ ||A||⋅||x||Cm
||.|| is induced by the vector norms ||.||Cn, ||.||Cm if
• ACn×m, xCm ||A|| = max {||Ax||Cn / ||x||Cm ¦ x≠0} = max {||Ax||Cn ¦ ||x||Cm=1}
which is a measure for how much A stretches vectors. Induced norms are compatible with the corresponding vector norm. Further, induced norms are sub-multiplicative if the same norm is used on Cn and Cm (and n=m).

This method should at least implement the following induced p-norms

• ||A||1 = max {∑i=1n|aij| ¦ 1≤j≤m} is the norm of column sums.
• ||A|| = max {∑j=1m|aij| ¦ 1≤i≤n} is the norm of row sums.
• ||A||2 = sqrt max Eigenvalues(A*A) is the spectral norm. (optional operation)

Preconditions:
p>=1

### norm

`Real norm()`
Returns a norm ||.|| of this arithmetic object. Returns the sub-multiplicative Frobenius norm of this matrix.
||A|| = √(∑i=1nj=1m |aij|2) = tr(AA*)

Note that the Frobenius norm is not a p-norm. It is a norm got by `identifying matrices with vectors`.

Specified by:
`norm` in interface `Normed`
Returns:
the norm of this object, or perhaps `Double.NaN` if it is symbolic and really does not have a numeric norm or a useful symbolic norm.

### trace

```Arithmetic trace()
throws java.lang.ArithmeticException```
Returns the trace of the matrix representation.

The trace is invariant to conjugation (similar matrices): Tr (T-1AT) = Tr A.

Returns:
sum of the main-diagonal-vectors components.
Throws:
`java.lang.ArithmeticException` - if this is not a square matrix, since only square matrix have a trace.
Preconditions:
isSquare()

### det

```Arithmetic det()
throws java.lang.ArithmeticException```
Returns the determinant of the matrix representation. The determinant is useful to determine if a matrix is `invertible`. The determinant is the universal alternating map Rn×n≅(Rn)n→Λn(Rn)≅R of the exterior product Λn(Rn). It is denoted as |M| := det M.

det:Rn×n→R exists and is uniquely defined by
(ml)
 det [ a0 ] = α·det [ a0 ] + β·det [ a0 ] ⋮ ⋮ ⋮ αai + βbi ai bi ⋮ ⋮ ⋮ an-1 an-1 an-1
"multi-linear" (linear in each row)
( ) rank M < n ⇔ det(M)=0 "≈alternating"
(1) det(I) = 1
⇒ Properties
( )
 det [ a0 ] = -det [ a0 ] ⋮ ⋮ ai aj ⋮ ⋮ aj ai ⋮ ⋮ an-1 an-1
"skew symmetric"
( ) det(MT) = det(M) "invariant to transposition"
( ) det(MN) = det(M)⋅det(N)
( ) M∈(Rn×n)× ⇔ det(M)∈R×
⇒ det(M-1) = det(M)-1

( )
 det [ a0 ] = det [ a0 ] ⋮ ⋮ ai + ∑k≠i λkak aj ⋮ ⋮ an-1 an-1
"invariant to EOP"
( )
 det [ a0 ] = ∑σ∈Sn sign σ ⋅ a1σ(1) ⋅ …⋅ anσ(n) ⋮ ai ⋮ an
"determinant formula of Leibniz"

The determinant is invariant to conjugation (similar matrices): det (T-1AT) = det A. A matrix is invertible if and only if its determinant is invertible. However, if the determinant is approximately zero then inverse transform operations might not carry enough numerical precision to produce meaningful results.

(det A)' = ∑i=0n-1 det (a0…ai'…an-1) where ai = (a0,i,…,an-1,i)t is the i-th column of A.

Returns:
det A = |A|
Throws:
`java.lang.ArithmeticException` - if this is not a square matrix, since determinant is only defined for square matrices.
Preconditions:
isSquare()
Postconditions:
det() multilinear && (rank() < dimension().width ⇔ det() = 0) && IDENTITY(n).det() = 1

`Matrix add(Matrix B)`
Adds two matrices returning a matrix.

Preconditions:
dimension().equals(B.dimension())
Postconditions:
RES.dimension().equals(dimension()) && RES.get(i, j) == get(i,j) + B.get(i,j)
Attributes:
associative, neutral (O), inverse (-A), commutative

### subtract

`Matrix subtract(Matrix B)`
Subtracts two matrices returning a matrix.

Preconditions:
dimension().equals(B.dimension())
Postconditions:
RES.dimension().equals(dimension()) && RES.get(i, j) == get(i,j) - B.get(i,j)
Attributes:
associative

### multiply

`Matrix multiply(Matrix B)`
Multiplies two matrices returning a matrix. If A∈Rn×m and B∈Rm×l the resulting matrix AB∈Rn×l. This is the ring multiplication of matrices, and an inner product.

Returns:
the n×l matrix AB.
Preconditions:
dimension().width == B.dimension().height
Postconditions:
RES.dimension().height == dimension().height && RES.dimension().width == B.dimension().width && RES.get(i, j) == getRow(i) ⋅ B.getColumn(j)
Attributes:
associative, neutral (I)

### scale

`Matrix scale(Scalar s)`
Multiplies a matrix with a scalar returning a matrix. This is the scalar multiplication.

Returns:
A
Preconditions:
true
Postconditions:
RES.dimension().equals(dimension()) && RES.get(i, j) == s ⋅ get(i,j)

### multiply

`Matrix multiply(Scalar s)`
Multiplies a matrix with a scalar returning a matrix.

`scale(Scalar)`

### multiply

`Vector multiply(Vector B)`
Multiplies a matrix with a vector returning a vector. If A∈Rn×m and v∈Rm is a column vector of dimension m, the resulting column vector A∙v∈Rn has dimension n. This is an inner product.

Returns:
the n-dimensional column vector A∙v.
Preconditions:
dimension().width == B.dimension()
Postconditions:
RES.dimension() == dimension().height && RES.get(i) == getRow(i) ⋅ B

### transpose

`Matrix transpose()`
Returns this matrix transposed.
t·:Rn×m→Rm×n; MtM:=MT:=(ti,j) with ti,j = mj,i.

• t(A+B) = tA + tB
• t(λ·A) = λ·tA
• t(AC) = tCtA
• t(tA) = A
A,B∈Rn×m,C∈Rm×l ∀λ∈R

Returns:
the m×n matrix tM=(ti,j) with elements ti,j = mj,i.
`conjugate()`
Postconditions:
RES.get(j,i) == get(i,j) && RES.dimension().width == dimension().height && RES.dimension().height == dimension().width

### conjugate

`Matrix conjugate()`
Returns this matrix conjugate transposed.
.:Rn×m→Rm×n; MM:=tM = (ti,j) with ti,j = mj,i.

• (A+B) = A + B
• (λ·A) = λ·A = λ*A
• (AC) = CA
• (A) = A
• . = .T on Rn×m
A,B∈Rn×m,C∈Rm×l ∀λ∈R.

Relative to a finite orthonormal basis . is the adjoint operator.

Returns:
the m×n matrix M=tM.
`Complex.conjugate()`, `transpose()`
Postconditions:
RES.get(j,i) == get(i,j).conjugate() RES.dimension().width == dimension().height && RES.dimension().height == dimension().width

### pseudoInverse

`Matrix pseudoInverse()`
Returns the pseudo inverse matrix A+.

The pseudo inverse of ARn×m is the matrix A+Rm×n that satisfies

• xRn A+x∈NullSpace(A)
• xRn ||x - AA+x|| minimal
It is uniquely characterized by the Penrose axioms
1. (A+A)T = A+A
2. (AA+)T = AA+
3. A+AA+ = A+
4. AA+A = A

Let A = DA into a diagonal matrix U,A+ = D-1AA+ - I is minimal)

Returns:
the pseudo inverse A+Rm×n of this matrix ARn×m.
Preconditions:
true
Postconditions:
RES.dimension().equals(transpose().dimension()) && RES.multiply(this).transpose().equals(RES.multiply(this)) && this.multiply(RES).transpose().equals(this.multiply(RES)) && RES.multiply(this).multiply(RES).equals(RES) && this.multiply(RES).multiply(this).equals(this)

### insertColumns

```Matrix insertColumns(int index,
Matrix cols)```
Insert columns into this matrix.

Parameters:
`cols` - a n×l matrix containing l columns to be added at the end.
Returns:
this.
Preconditions:
dimension().height == cols.dimension().height
Postconditions:
RES == this && RES.dimension().height == OLD(dimension().height) && RES.dimension().width == OLD(dimension().width) + cols.dimension().width

### insertRows

```Matrix insertRows(int index,
Matrix rows)```
Insert rows into this matrix.

Parameters:
`rows` - a x×m matrix containing x rows to be added at the end.
Returns:
this.
Preconditions:
dimension().width == rows.dimension().width
Postconditions:
RES == this && RES.dimension().width == OLD(dimension().width) && RES.dimension().height == OLD(dimension().height) + rows.dimension().height

### insertColumns

`Matrix insertColumns(Matrix cols)`
Append columns to this matrix.

Parameters:
`cols` - a n×x matrix containing x columns to be added at the end.
Returns:
this.
Preconditions:
dimension().height == cols.dimension().height
Postconditions:
RES == this && RES.dimension().height == OLD(dimension().height) && RES.dimension().width == OLD(dimension().width) + cols.dimension().width

### insertRows

`Matrix insertRows(Matrix rows)`
Append rows to this matrix.

Parameters:
`rows` - a x×m matrix containing x rows to be added at the end.
Returns:
this.
Preconditions:
dimension().width == rows.dimension().width
Postconditions:
RES == this && RES.dimension().width == OLD(dimension().width) && RES.dimension().height == OLD(dimension().height) + rows.dimension().height

### removeColumn

`Matrix removeColumn(int c)`
Remove a column from this matrix.

Returns:
this.
Preconditions:
c∈[0, dimension().width)
Postconditions:
RES == this && RES.dimension().height == OLD(dimension().height) && RES.dimension().width == OLD(dimension().width) - 1

### removeRow

`Matrix removeRow(int r)`
Remove a row from this matrix.

Returns:
this.
Preconditions:
r∈[0, dimension().height)
Postconditions:
RES == this && RES.dimension().width == OLD(dimension().width) && RES.dimension().height == OLD(dimension().height) - 1

### toArray

`Arithmetic[][] toArray()`
Returns an array containing all the elements in this matrix. The first index in this array specifies the row, the second is for column.

`Object.clone()`