--- /dev/null
+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