1 package tim.prune.function.estimate.jama;
\r
4 * The Java Matrix Class provides the fundamental operations of numerical linear algebra.
\r
5 * Original authors The MathWorks, Inc. and the National Institute of Standards and Technology
\r
6 * The original public domain code has now been modified and reduced to only contain
\r
7 * the use of QR Decomposition of rectangular matrices, to solve least squares regression,
\r
8 * and is placed under GPL2 with the rest of the GpsPrune code.
\r
13 /** Array for internal storage of elements */
\r
14 private double[][] _matrix;
\r
16 /** Row and column dimensions */
\r
21 * Construct an m-by-n matrix of zeros
\r
22 * @param inM Number of rows
\r
23 * @param inN Number of colums
\r
25 public Matrix(int inM, int inN)
\r
29 _matrix = new double[inM][inN];
\r
33 * Construct a matrix from a 2-D array
\r
34 * @param A Two-dimensional array of doubles.
\r
35 * @exception IllegalArgumentException All rows must have the same length
\r
37 public Matrix(double[][] A)
\r
41 for (int i = 0; i < _m; i++) {
\r
42 if (A[i].length != _n) {
\r
43 throw new IllegalArgumentException("All rows must have the same length.");
\r
50 * Construct a matrix quickly without checking arguments.
\r
51 * @param inA Two-dimensional array of doubles.
\r
52 * @param inM Number of rows
\r
53 * @param inN Number of columns
\r
55 public Matrix(double[][] inA, int inM, int inN)
\r
63 * ------------------------ Public Methods ------------------------
\r
68 * Set a value in a cell of the matrix
\r
69 * @param inRow row index
\r
70 * @param inCol column index
\r
71 * @param inValue value to set
\r
73 public void setValue(int inRow, int inCol, double inValue)
\r
75 _matrix[inRow][inCol] = inValue;
\r
79 * Access the internal two-dimensional array.
\r
80 * @return Pointer to the two-dimensional array of matrix elements.
\r
82 public double[][] getArray() {
\r
87 * Copy the internal two-dimensional array.
\r
88 * @return Two-dimensional array copy of matrix elements.
\r
90 public double[][] getArrayCopy()
\r
92 double[][] C = new double[_m][_n];
\r
93 for (int i = 0; i < _m; i++) {
\r
94 for (int j = 0; j < _n; j++) {
\r
95 C[i][j] = _matrix[i][j];
\r
102 * Get a single element.
\r
103 * @param inRow Row index
\r
104 * @param inCol Column index
\r
105 * @return A(inRow,inCol)
\r
106 * @exception ArrayIndexOutOfBoundsException
\r
108 public double get(int inRow, int inCol) {
\r
109 return _matrix[inRow][inCol];
\r
112 /** @return number of rows _m */
\r
113 public int getNumRows() {
\r
117 /** @return number of columns _n */
\r
118 public int getNumColumns() {
\r
124 * @param i0 Initial row index
\r
125 * @param i1 Final row index
\r
126 * @param j0 Initial column index
\r
127 * @param j1 Final column index
\r
128 * @return A(i0:i1,j0:j1)
\r
129 * @exception ArrayIndexOutOfBoundsException
\r
131 public Matrix getMatrix(int i0, int i1, int j0, int j1)
\r
133 Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);
\r
134 double[][] B = X.getArray();
\r
136 for (int i = i0; i <= i1; i++) {
\r
137 for (int j = j0; j <= j1; j++) {
\r
138 B[i - i0][j - j0] = _matrix[i][j];
\r
141 } catch (ArrayIndexOutOfBoundsException e) {
\r
142 throw new ArrayIndexOutOfBoundsException("Submatrix indices");
\r
149 * Linear algebraic matrix multiplication, A * B
\r
150 * @param B another matrix
\r
151 * @return Matrix product, A * B
\r
152 * @exception IllegalArgumentException if matrix dimensions don't agree
\r
154 public Matrix times(Matrix B)
\r
157 throw new IllegalArgumentException("Matrix inner dimensions must agree.");
\r
159 Matrix X = new Matrix(_m, B._n);
\r
160 double[][] C = X.getArray();
\r
161 double[] Bcolj = new double[_n];
\r
162 for (int j = 0; j < B._n; j++) {
\r
163 for (int k = 0; k < _n; k++) {
\r
164 Bcolj[k] = B._matrix[k][j];
\r
166 for (int i = 0; i < _m; i++) {
\r
167 double[] Arowi = _matrix[i];
\r
169 for (int k = 0; k < _n; k++) {
\r
170 s += Arowi[k] * Bcolj[k];
\r
179 * Subtract the other matrix from this one
\r
180 * @param B another matrix
\r
181 * @return difference this - B
\r
182 * @exception IllegalArgumentException if matrix dimensions don't agree
\r
184 public Matrix minus(Matrix B)
\r
186 if (B._m != _m || B._n != _n) {
\r
187 throw new IllegalArgumentException("Matrix dimensions must agree.");
\r
189 Matrix result = new Matrix(_m, _n);
\r
190 for (int i = 0; i < _m; i++) {
\r
191 for (int j = 0; j < _n; j++) {
\r
192 result.setValue(i, j, get(i, j) - B.get(i, j));
\r
199 * Divide each element of this matrix by the corresponding element in the other one
\r
200 * @param B another matrix
\r
201 * @return this[i,j]/other[i,j]
\r
202 * @exception IllegalArgumentException if matrix dimensions don't agree
\r
204 public Matrix divideEach(Matrix B)
\r
206 if (B._m != _m || B._n != _n) {
\r
207 throw new IllegalArgumentException("Matrix dimensions must agree.");
\r
209 Matrix result = new Matrix(_m, _n);
\r
210 for (int i = 0; i < _m; i++) {
\r
211 for (int j = 0; j < _n; j++) {
\r
212 result.setValue(i, j, get(i, j) / B.get(i, j));
\r
220 * @param B right hand side
\r
221 * @return least squares solution
\r
223 public Matrix solve(Matrix B) {
\r
224 return new QRDecomposition(this).solve(B);
\r
228 * @return the average absolute value of all the elements in the matrix
\r
230 public double getAverageAbsValue()
\r
232 double total = 0.0;
\r
233 for (int i = 0; i < _m; i++) {
\r
234 for (int j = 0; j < _n; j++) {
\r
235 total += Math.abs(_matrix[i][j]);
\r
238 return total / _m / _n;
\r
242 * Primitive output for debugging
\r
244 public String toString()
\r
246 StringBuilder builder = new StringBuilder();
\r
247 builder.append('(');
\r
248 for (int i = 0; i < _m; i++) {
\r
249 builder.append('(');
\r
250 for (int j = 0; j < _n; j++) {
\r
251 builder.append((_matrix[i][j]));
\r
252 builder.append(", ");
\r
254 builder.append(") ");
\r
256 builder.append(')');
\r
257 return builder.toString();
\r