Orbital library

orbital.math
Interface Matrix

All Superinterfaces:
Arithmetic, Normed, Tensor

public interface Matrix
extends 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
See Also:
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.
See Also:
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.
See Also:
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)).
See Also:
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

||.|| is compatible or conform with the vector norms ||.||Cn, ||.||Cm if ||.|| is induced by the vector norms ||.||Cn, ||.||Cm if 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

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

add

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.

See Also:
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.

A,B∈Rn×m,C∈Rm×l ∀λ∈R

Returns:
the m×n matrix tM=(ti,j) with elements ti,j = mj,i.
See Also:
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∈Rn×m,C∈Rm×l ∀λ∈R.

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

Returns:
the m×n matrix M=tM.
See Also:
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

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.

See Also:
Object.clone()
Postconditions:
RES[i][j] == get(i, j) && RES != RES

Orbital library
1.3.0: 11 Apr 2009

Copyright © 1996-2009 André Platzer
All Rights Reserved.