]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/function/estimate/jama/Matrix.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / function / estimate / jama / Matrix.java
diff --git a/src/tim/prune/function/estimate/jama/Matrix.java b/src/tim/prune/function/estimate/jama/Matrix.java
new file mode 100644 (file)
index 0000000..face1a9
--- /dev/null
@@ -0,0 +1,259 @@
+package tim.prune.function.estimate.jama;\r
+\r
+/**\r
+ * The Java Matrix Class provides the fundamental operations of numerical linear algebra.\r
+ * Original authors The MathWorks, Inc. and the National Institute of Standards and Technology\r
+ * The original public domain code has now been modified and reduced to only contain\r
+ * the use of QR Decomposition of rectangular matrices, to solve least squares regression,\r
+ * and is placed under GPL2 with the rest of the GpsPrune code.\r
+ */\r
+public class Matrix\r
+{\r
+\r
+       /** Array for internal storage of elements */\r
+       private double[][] _matrix;\r
+\r
+       /** Row and column dimensions */\r
+       private int _m, _n;\r
+\r
+\r
+       /**\r
+        * Construct an m-by-n matrix of zeros\r
+        * @param inM  Number of rows\r
+        * @param inN  Number of colums\r
+        */\r
+       public Matrix(int inM, int inN)\r
+       {\r
+               _m = inM;\r
+               _n = inN;\r
+               _matrix = new double[inM][inN];\r
+       }\r
+\r
+       /**\r
+        * Construct a matrix from a 2-D array\r
+        * @param A   Two-dimensional array of doubles.\r
+        * @exception IllegalArgumentException All rows must have the same length\r
+        */\r
+       public Matrix(double[][] A)\r
+       {\r
+               _m = A.length;\r
+               _n = A[0].length;\r
+               for (int i = 0; i < _m; i++) {\r
+                       if (A[i].length != _n) {\r
+                               throw new IllegalArgumentException("All rows must have the same length.");\r
+                       }\r
+               }\r
+               _matrix = A;\r
+       }\r
+\r
+       /**\r
+        * Construct a matrix quickly without checking arguments.\r
+        * @param inA   Two-dimensional array of doubles.\r
+        * @param inM   Number of rows\r
+        * @param inN   Number of columns\r
+        */\r
+       public Matrix(double[][] inA, int inM, int inN)\r
+       {\r
+               _matrix = inA;\r
+               _m = inM;\r
+               _n = inN;\r
+       }\r
+\r
+       /*\r
+        * ------------------------ Public Methods ------------------------\r
+        */\r
+\r
+\r
+       /**\r
+        * Set a value in a cell of the matrix\r
+        * @param inRow row index\r
+        * @param inCol column index\r
+        * @param inValue value to set\r
+        */\r
+       public void setValue(int inRow, int inCol, double inValue)\r
+       {\r
+               _matrix[inRow][inCol] = inValue;\r
+       }\r
+\r
+       /**\r
+        * Access the internal two-dimensional array.\r
+        * @return Pointer to the two-dimensional array of matrix elements.\r
+        */\r
+       public double[][] getArray() {\r
+               return _matrix;\r
+       }\r
+\r
+       /**\r
+        * Copy the internal two-dimensional array.\r
+        * @return Two-dimensional array copy of matrix elements.\r
+        */\r
+       public double[][] getArrayCopy()\r
+       {\r
+               double[][] C = new double[_m][_n];\r
+               for (int i = 0; i < _m; i++) {\r
+                       for (int j = 0; j < _n; j++) {\r
+                               C[i][j] = _matrix[i][j];\r
+                       }\r
+               }\r
+               return C;\r
+       }\r
+\r
+       /**\r
+        * Get a single element.\r
+        * @param inRow   Row index\r
+        * @param inCol   Column index\r
+        * @return A(inRow,inCol)\r
+        * @exception ArrayIndexOutOfBoundsException\r
+        */\r
+       public double get(int inRow, int inCol) {\r
+               return _matrix[inRow][inCol];\r
+       }\r
+\r
+       /** @return number of rows _m */\r
+       public int getNumRows() {\r
+               return _m;\r
+       }\r
+\r
+       /** @return number of columns _n */\r
+       public int getNumColumns() {\r
+               return _n;\r
+       }\r
+\r
+       /**\r
+        * Get a submatrix\r
+        * @param i0  Initial row index\r
+        * @param i1  Final row index\r
+        * @param j0  Initial column index\r
+        * @param j1  Final column index\r
+        * @return A(i0:i1,j0:j1)\r
+        * @exception ArrayIndexOutOfBoundsException\r
+        */\r
+       public Matrix getMatrix(int i0, int i1, int j0, int j1)\r
+       {\r
+               Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);\r
+               double[][] B = X.getArray();\r
+               try {\r
+                       for (int i = i0; i <= i1; i++) {\r
+                               for (int j = j0; j <= j1; j++) {\r
+                                       B[i - i0][j - j0] = _matrix[i][j];\r
+                               }\r
+                       }\r
+               } catch (ArrayIndexOutOfBoundsException e) {\r
+                       throw new ArrayIndexOutOfBoundsException("Submatrix indices");\r
+               }\r
+               return X;\r
+       }\r
+\r
+\r
+       /**\r
+        * Linear algebraic matrix multiplication, A * B\r
+        * @param B   another matrix\r
+        * @return Matrix product, A * B\r
+        * @exception IllegalArgumentException if matrix dimensions don't agree\r
+        */\r
+       public Matrix times(Matrix B)\r
+       {\r
+               if (B._m != _n) {\r
+                       throw new IllegalArgumentException("Matrix inner dimensions must agree.");\r
+               }\r
+               Matrix X = new Matrix(_m, B._n);\r
+               double[][] C = X.getArray();\r
+               double[] Bcolj = new double[_n];\r
+               for (int j = 0; j < B._n; j++) {\r
+                       for (int k = 0; k < _n; k++) {\r
+                               Bcolj[k] = B._matrix[k][j];\r
+                       }\r
+                       for (int i = 0; i < _m; i++) {\r
+                               double[] Arowi = _matrix[i];\r
+                               double s = 0;\r
+                               for (int k = 0; k < _n; k++) {\r
+                                       s += Arowi[k] * Bcolj[k];\r
+                               }\r
+                               C[i][j] = s;\r
+                       }\r
+               }\r
+               return X;\r
+       }\r
+\r
+       /**\r
+        * Subtract the other matrix from this one\r
+        * @param B   another matrix\r
+        * @return difference this - B\r
+        * @exception IllegalArgumentException if matrix dimensions don't agree\r
+        */\r
+       public Matrix minus(Matrix B)\r
+       {\r
+               if (B._m != _m || B._n != _n) {\r
+                       throw new IllegalArgumentException("Matrix dimensions must agree.");\r
+               }\r
+               Matrix result = new Matrix(_m, _n);\r
+               for (int i = 0; i < _m; i++) {\r
+                       for (int j = 0; j < _n; j++) {\r
+                               result.setValue(i, j, get(i, j) - B.get(i, j));\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+\r
+       /**\r
+        * Divide each element of this matrix by the corresponding element in the other one\r
+        * @param B   another matrix\r
+        * @return this[i,j]/other[i,j]\r
+        * @exception IllegalArgumentException if matrix dimensions don't agree\r
+        */\r
+       public Matrix divideEach(Matrix B)\r
+       {\r
+               if (B._m != _m || B._n != _n) {\r
+                       throw new IllegalArgumentException("Matrix dimensions must agree.");\r
+               }\r
+               Matrix result = new Matrix(_m, _n);\r
+               for (int i = 0; i < _m; i++) {\r
+                       for (int j = 0; j < _n; j++) {\r
+                               result.setValue(i, j, get(i, j) / B.get(i, j));\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+\r
+       /**\r
+        * Solve A*X = B\r
+        * @param B   right hand side\r
+        * @return least squares solution\r
+        */\r
+       public Matrix solve(Matrix B) {\r
+               return new QRDecomposition(this).solve(B);\r
+       }\r
+\r
+       /**\r
+        * @return the average absolute value of all the elements in the matrix\r
+        */\r
+       public double getAverageAbsValue()\r
+       {\r
+               double total = 0.0;\r
+               for (int i = 0; i < _m; i++) {\r
+                       for (int j = 0; j < _n; j++) {\r
+                               total += Math.abs(_matrix[i][j]);\r
+                       }\r
+               }\r
+               return total / _m / _n;\r
+       }\r
+\r
+       /**\r
+        * Primitive output for debugging\r
+        */\r
+       public String toString()\r
+       {\r
+               StringBuilder builder = new StringBuilder();\r
+               builder.append('(');\r
+               for (int i = 0; i < _m; i++) {\r
+                       builder.append('(');\r
+                       for (int j = 0; j < _n; j++) {\r
+                               builder.append((_matrix[i][j]));\r
+                               builder.append(", ");\r
+                       }\r
+                       builder.append(") ");\r
+               }\r
+               builder.append(')');\r
+               return builder.toString();\r
+       }\r
+}\r