|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.ujmp.core.calculation.AbstractCalculation
org.ujmp.core.doublematrix.calculation.AbstractDoubleCalculation
org.ujmp.core.doublematrix.calculation.general.decomposition.Ginv
public class Ginv
This class implements some matrix operations that I need for other things I'm doing. Why not use existing packages? Well, I've tried, but they seem to not have simple linear algebra things like inverting singular or non-square inverses. Maybe I've just been looking in the wrong places.
Anyway I wrote this algorithm in 1989 using Ada and Fortran77. In 1992 I converted it to C++, and in 2003 I made it a C++ template to be used for absolutely anything that you'd want.
I attempted to convert this to a Java template, but I need to make objects of the parameter type, and without doing some inspection or copy tricks, I can't get there from here. I only use this for doubles anyway, so here's the version that I use. The C++ version is still available.
The matrix inversion was in from the start, as the only really useful part of the Class. I added the bandwidth reduction routine in 1991 - I was stuck in SOS (USAF school) at the time and was thinking about optimizing the bandwidth of a matrix made from a finite-element grid by renumbering the nodes of the grid.
Changes by Holger Arndt: The original code has been adapted for the Universal Java Matrix Package. Methods for different matrix implementations have been added.
Nested Class Summary |
---|
Nested classes/interfaces inherited from interface org.ujmp.core.calculation.Calculation |
---|
Calculation.Ret |
Field Summary |
---|
Fields inherited from interface org.ujmp.core.calculation.Calculation |
---|
ALL, COLUMN, LINK, NEW, NONE, ORIG, ROW |
Constructor Summary | |
---|---|
Ginv(Matrix source)
|
Method Summary | |
---|---|
static void |
addColTimes(DenseDoubleMatrix2D matrix,
long diag,
long fromRow,
long col,
double factor)
Add a factor times one column to another column |
static void |
addColTimes(double[][] matrix,
int diag,
int fromRow,
int col,
double factor)
Add a factor times one column to another column |
static void |
addColTimes(Matrix matrix,
long diag,
long fromRow,
long col,
double factor)
Add a factor times one column to another column |
static void |
addRowTimes(DenseDoubleMatrix2D matrix,
long diag,
long fromCol,
long row,
double factor)
Add a factor times one row to another row |
static void |
addRowTimes(double[][] matrix,
int diag,
int fromCol,
int row,
double factor)
Add a factor times one row to another row |
static void |
addRowTimes(Matrix matrix,
long diag,
long fromCol,
long row,
double factor)
Add a factor times one row to another row |
static Matrix |
arbitrariness(Matrix source,
Matrix inverse)
Calculate the arbitrariness of the solution. |
DenseDoubleMatrix2D |
calcLink()
|
DenseDoubleMatrix2D |
calcNew()
|
DenseDoubleMatrix2D |
calcOrig()
|
static boolean |
canSwapCols(Matrix matrix,
int col1,
int col2,
int row1)
Check to see if columns can be swapped - part of the bandwidth reduction algorithm. |
static boolean |
canSwapRows(Matrix matrix,
int row1,
int row2,
int col1)
Check to see if a non-zero and a zero value in the rows leading up to this column can be swapped. |
static void |
divideRowBy(DenseDoubleMatrix2D matrix,
long aRow,
long fromCol,
double value)
Divide the row from this column position by this value |
static void |
divideRowBy(double[][] matrix,
int aRow,
int fromCol,
double value)
Divide the row from this column position by this value |
static void |
divideRowBy(Matrix matrix,
long aRow,
long fromCol,
double value)
Divide the row from this column position by this value |
double |
getDouble(long... coordinates)
|
static DenseDoubleMatrix2D |
inverse(DenseDoubleMatrix2D matrix)
Same as inverse(Matrix) but optimized for 2D dense double
matrices |
static DenseDoubleMatrix2D |
inverse(double[][] matrix)
Same as inverse(Matrix) but optimized for 2D double arrays |
static DenseDoubleMatrix2D |
inverse(Matrix matrix)
Matrix inversion is the reason this Class exists - this method creates a generalized matrix inverse of the current matrix. |
static Matrix |
reduce(Matrix source)
Mathematical operator to reduce the bandwidth of a HusoMatrix. |
static Matrix |
reduce(Matrix source,
Matrix response)
|
static void |
swapCols(DenseDoubleMatrix2D matrix,
long col1,
long col2)
Swap components in the two columns. |
static void |
swapCols(double[][] matrix,
int col1,
int col2)
Swap components in the two columns. |
static void |
swapCols(Matrix matrix,
long col1,
long col2)
Swap components in the two columns. |
static void |
swapPivot(DenseDoubleMatrix2D source,
long diag,
DenseDoubleMatrix2D s,
DenseDoubleMatrix2D t)
Swap the matrices so that the largest value is on the pivot |
static void |
swapPivot(double[][] source,
int diag,
double[][] s,
double[][] t)
Swap the matrices so that the largest value is on the pivot |
static void |
swapPivot(Matrix source,
long diag,
Matrix s,
Matrix t)
Swap the matrices so that the largest value is on the pivot |
static void |
swapRows(DenseDoubleMatrix2D matrix,
long row1,
long row2)
Swap components in the two rows. |
static void |
swapRows(double[][] matrix,
int row1,
int row2)
Swap components in the two rows. |
static void |
swapRows(Matrix matrix,
long row1,
long row2)
Swap components in the two rows. |
static DenseDoubleMatrix2D |
times(DenseDoubleMatrix2D matrix1,
DenseDoubleMatrix2D matrix2,
long timesInner)
This routine performs the matrix multiplication. |
static double[][] |
times(double[][] matrix1,
double[][] matrix2,
int timesInner)
This routine performs the matrix multiplication. |
Methods inherited from class org.ujmp.core.doublematrix.calculation.AbstractDoubleCalculation |
---|
getValueType, setDouble |
Methods inherited from class org.ujmp.core.calculation.AbstractCalculation |
---|
allCoordinates, availableCoordinates, calc, calcMulti, contains, getAnnotation, getDimension, getSize, getSource, getSources, getStorageType, getValueCount, isSparse, setAnnotation, setDimension, setSources |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Methods inherited from interface org.ujmp.core.calculation.Calculation |
---|
allCoordinates, availableCoordinates, calc, calcMulti, contains, getAnnotation, getDimension, getSize, getSource, getSources, getStorageType, getValueCount, isSparse, setAnnotation, setDimension, setSources |
Constructor Detail |
---|
public Ginv(Matrix source)
Method Detail |
---|
public static DenseDoubleMatrix2D times(DenseDoubleMatrix2D matrix1, DenseDoubleMatrix2D matrix2, long timesInner)
matrix1
- the first matrixmatrix2
- the second matrixtimesInner
- number of rows/columns to process
public static double[][] times(double[][] matrix1, double[][] matrix2, int timesInner)
matrix1
- the first matrixmatrix2
- the second matrixtimesInner
- number of rows/columns to process
public static void swapCols(Matrix matrix, long col1, long col2)
matrix
- the matrix to modifycol1
- the first rowcol2
- the second rowpublic static void swapCols(DenseDoubleMatrix2D matrix, long col1, long col2)
matrix
- the matrix to modifycol1
- the first rowcol2
- the second rowpublic static void swapCols(double[][] matrix, int col1, int col2)
matrix
- the matrix to modifycol1
- the first rowcol2
- the second rowpublic static void swapRows(Matrix matrix, long row1, long row2)
matrix
- the matrix to modifyrow1
- the first rowrow2
- the second rowpublic static void swapRows(DenseDoubleMatrix2D matrix, long row1, long row2)
matrix
- the matrix to modifyrow1
- the first rowrow2
- the second rowpublic static void swapRows(double[][] matrix, int row1, int row2)
matrix
- the matrix to modifyrow1
- the first rowrow2
- the second rowpublic static DenseDoubleMatrix2D inverse(Matrix matrix)
Matrix inversion is the reason this Class exists - this method creates a generalized matrix inverse of the current matrix. The result is returned in a new matrix.
Matrices may be square, non-square, or singular. The operations will be identical. If the matrix has a single possible inverse, there will be no arbitrariness to the solution. The method here was suggested to me by John Jones Jr. at AFIT in the 1980s, and this algorithm is an original creation of mine to implement his method.
A matrix inverse has some properties described here. Let
A
be the original matrix. Let the inverse, as
calculated here be A12
(an inverse with properties 1
and 2 - being left side inverse and right side inverse). An inverse times
the original matrix should yield an identity matrix.
A x = b
is the usual equation where
A
is the matrix, x
is a vector of
the unknowns and b
is a vector of the constant
values:
Given these equations:
C x + D y + E z = b1 F x + G y + H z = b1
(The usual programs available don't handle more unknowns than equations, and will stop at this point)
The A
matrix is:
| C D E | | F G H |
The x
vector is:
| x | | y | | z |
The b
vector is: | b1 | | b2 |
A * x = b
The generalized inverse A12
in this case will be of
size (3,2): | J K | | L M | | N P |
The left-hand inverse is defined such that the product of the
(generalized) inverse times the original matrix times the (generalized)
inverse will yield the (generalized) inverse again:
A12 * (A * A12) = A12
The right-hand inverse is defined similarly:
(A * A12) * A = A
If a matrix (A12
) meets these criteria, it's
considered to be a generalized inverse of the A
matrix, even though it may not be square, or the product of
A * A12
or A12 * A
may not be the
identity matrix! (Won't be if the input A
matrix is
non-square or singular)
In the case of (A * A12)
being the identity matrix,
the product of (A12 *
A)
will also be the identity matrix, and the solution will be
unique: A12
will be the exact and only solution to
the equation.
Refer to http://mjollnir.com/matrix/
for the best description.
matrix
- matrix to invert
public static DenseDoubleMatrix2D inverse(DenseDoubleMatrix2D matrix)
inverse(Matrix)
but optimized for 2D dense double
matrices
matrix
- the matrix to invert
public static DenseDoubleMatrix2D inverse(double[][] matrix)
inverse(Matrix)
but optimized for 2D double arrays
matrix
- the matrix to invert
public static void addColTimes(Matrix matrix, long diag, long fromRow, long col, double factor)
matrix
- the matrix to modifydiag
- coordinate on the diagonalfromRow
- first row to processcol
- column to processfactor
- factor to multiplypublic static void addColTimes(double[][] matrix, int diag, int fromRow, int col, double factor)
matrix
- the matrix to modifydiag
- coordinate on the diagonalfromRow
- first row to processcol
- column to processfactor
- factor to multiplypublic static void addColTimes(DenseDoubleMatrix2D matrix, long diag, long fromRow, long col, double factor)
matrix
- the matrix to modifydiag
- coordinate on the diagonalfromRow
- first row to processcol
- column to processfactor
- factor to multiplypublic static void addRowTimes(DenseDoubleMatrix2D matrix, long diag, long fromCol, long row, double factor)
matrix
- the matrix to modifydiag
- coordinate on the diagonalfromCol
- first column to processrow
- row to processfactor
- factor to multiplypublic static void addRowTimes(double[][] matrix, int diag, int fromCol, int row, double factor)
matrix
- the matrix to modifydiag
- coordinate on the diagonalfromCol
- first column to processrow
- row to processfactor
- factor to multiplypublic static void addRowTimes(Matrix matrix, long diag, long fromCol, long row, double factor)
matrix
- the matrix to modifydiag
- coordinate on the diagonalfromCol
- first column to processrow
- row to processfactor
- factor to multiplypublic static void divideRowBy(Matrix matrix, long aRow, long fromCol, double value)
matrix
- the matrix to modifyaRow
- the row to processfromCol
- starting from columnvalue
- the value to dividepublic static void divideRowBy(DenseDoubleMatrix2D matrix, long aRow, long fromCol, double value)
matrix
- the matrix to modifyaRow
- the row to processfromCol
- starting from columnvalue
- the value to dividepublic static void divideRowBy(double[][] matrix, int aRow, int fromCol, double value)
matrix
- the matrix to modifyaRow
- the row to processfromCol
- starting from columnvalue
- the value to dividepublic static void swapPivot(Matrix source, long diag, Matrix s, Matrix t)
source
- the matrix to modifydiag
- the position on the diagonals
- the matrix st
- the matrix tpublic static void swapPivot(DenseDoubleMatrix2D source, long diag, DenseDoubleMatrix2D s, DenseDoubleMatrix2D t)
source
- the matrix to modifydiag
- the position on the diagonals
- the matrix st
- the matrix tpublic static void swapPivot(double[][] source, int diag, double[][] s, double[][] t)
source
- the matrix to modifydiag
- the position on the diagonals
- the matrix st
- the matrix tpublic static boolean canSwapRows(Matrix matrix, int row1, int row2, int col1)
matrix
- the matrix to checkrow1
- the first rowrow2
- the second rowcol1
- the column
public static boolean canSwapCols(Matrix matrix, int col1, int col2, int row1)
matrix
- the matrix to checkcol1
- the first columncol2
- the second columnrow1
- the row
public static Matrix reduce(Matrix source, Matrix response)
public static Matrix reduce(Matrix source)
public static Matrix arbitrariness(Matrix source, Matrix inverse)
public double getDouble(long... coordinates) throws MatrixException
MatrixException
public DenseDoubleMatrix2D calcLink() throws MatrixException
calcLink
in interface Calculation
calcLink
in class AbstractDoubleCalculation
MatrixException
public DenseDoubleMatrix2D calcNew() throws MatrixException
calcNew
in interface Calculation
calcNew
in class AbstractDoubleCalculation
MatrixException
public DenseDoubleMatrix2D calcOrig() throws MatrixException
calcOrig
in interface Calculation
calcOrig
in class AbstractDoubleCalculation
MatrixException
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |