source: src/main/java/agents/org/apache/commons/math/linear/RealMatrixImpl.java

Last change on this file was 1, checked in by Wouter Pasman, 7 years ago

Initial import : Genius 9.0.0

File size: 22.2 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package agents.org.apache.commons.math.linear;
19
20import java.io.Serializable;
21
22import agents.org.apache.commons.math.MathRuntimeException;
23import agents.org.apache.commons.math.exception.util.LocalizedFormats;
24import agents.org.apache.commons.math.linear.MatrixVisitorException;
25
26/**
27 * Implementation of RealMatrix using a double[][] array to store entries and
28 * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
29 * LU decomposition</a> to support linear system
30 * solution and inverse.
31 * <p>
32 * The LU decomposition is performed as needed, to support the following operations: <ul>
33 * <li>solve</li>
34 * <li>isSingular</li>
35 * <li>getDeterminant</li>
36 * <li>inverse</li> </ul></p>
37 * <p>
38 * <strong>Usage notes</strong>:<br>
39 * <ul><li>
40 * The LU decomposition is cached and reused on subsequent calls.
41 * If data are modified via references to the underlying array obtained using
42 * <code>getDataRef()</code>, then the stored LU decomposition will not be
43 * discarded. In this case, you need to explicitly invoke
44 * <code>LUDecompose()</code> to recompute the decomposition
45 * before using any of the methods above.</li>
46 * <li>
47 * As specified in the {@link RealMatrix} interface, matrix element indexing
48 * is 0-based -- e.g., <code>getEntry(0, 0)</code>
49 * returns the element in the first row, first column of the matrix.</li></ul>
50 * </p>
51 *
52 * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
53 * @deprecated as of 2.0 replaced by {@link Array2DRowRealMatrix}
54 */
55@Deprecated
56public class RealMatrixImpl extends AbstractRealMatrix implements Serializable {
57
58 /** Serializable version identifier */
59 private static final long serialVersionUID = -1067294169172445528L;
60
61 /** Entries of the matrix */
62 protected double data[][];
63
64 /**
65 * Creates a matrix with no data
66 */
67 public RealMatrixImpl() {
68 }
69
70 /**
71 * Create a new RealMatrix with the supplied row and column dimensions.
72 *
73 * @param rowDimension the number of rows in the new matrix
74 * @param columnDimension the number of columns in the new matrix
75 * @throws IllegalArgumentException if row or column dimension is not
76 * positive
77 */
78 public RealMatrixImpl(final int rowDimension, final int columnDimension)
79 throws IllegalArgumentException {
80 super(rowDimension, columnDimension);
81 data = new double[rowDimension][columnDimension];
82 }
83
84 /**
85 * Create a new RealMatrix using the input array as the underlying
86 * data array.
87 * <p>The input array is copied, not referenced. This constructor has
88 * the same effect as calling {@link #RealMatrixImpl(double[][], boolean)}
89 * with the second argument set to <code>true</code>.</p>
90 *
91 * @param d data for new matrix
92 * @throws IllegalArgumentException if <code>d</code> is not rectangular
93 * (not all rows have the same length) or empty
94 * @throws NullPointerException if <code>d</code> is null
95 * @see #RealMatrixImpl(double[][], boolean)
96 */
97 public RealMatrixImpl(final double[][] d)
98 throws IllegalArgumentException, NullPointerException {
99 copyIn(d);
100 }
101
102 /**
103 * Create a new RealMatrix using the input array as the underlying
104 * data array.
105 * <p>If an array is built specially in order to be embedded in a
106 * RealMatrix and not used directly, the <code>copyArray</code> may be
107 * set to <code>false</code. This will prevent the copying and improve
108 * performance as no new array will be built and no data will be copied.</p>
109 * @param d data for new matrix
110 * @param copyArray if true, the input array will be copied, otherwise
111 * it will be referenced
112 * @throws IllegalArgumentException if <code>d</code> is not rectangular
113 * (not all rows have the same length) or empty
114 * @throws NullPointerException if <code>d</code> is null
115 * @see #RealMatrixImpl(double[][])
116 */
117 public RealMatrixImpl(final double[][] d, final boolean copyArray)
118 throws IllegalArgumentException, NullPointerException {
119 if (copyArray) {
120 copyIn(d);
121 } else {
122 if (d == null) {
123 throw new NullPointerException();
124 }
125 final int nRows = d.length;
126 if (nRows == 0) {
127 throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
128 }
129 final int nCols = d[0].length;
130 if (nCols == 0) {
131 throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
132 }
133 for (int r = 1; r < nRows; r++) {
134 if (d[r].length != nCols) {
135 throw MathRuntimeException.createIllegalArgumentException(
136 LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
137 nCols, d[r].length);
138 }
139 }
140 data = d;
141 }
142 }
143
144 /**
145 * Create a new (column) RealMatrix using <code>v</code> as the
146 * data for the unique column of the <code>v.length x 1</code> matrix
147 * created.
148 * <p>The input array is copied, not referenced.</p>
149 *
150 * @param v column vector holding data for new matrix
151 */
152 public RealMatrixImpl(final double[] v) {
153 final int nRows = v.length;
154 data = new double[nRows][1];
155 for (int row = 0; row < nRows; row++) {
156 data[row][0] = v[row];
157 }
158 }
159
160 /** {@inheritDoc} */
161 @Override
162 public RealMatrix createMatrix(final int rowDimension, final int columnDimension)
163 throws IllegalArgumentException {
164 return new RealMatrixImpl(rowDimension, columnDimension);
165 }
166
167 /** {@inheritDoc} */
168 @Override
169 public RealMatrix copy() {
170 return new RealMatrixImpl(copyOut(), false);
171 }
172
173 /** {@inheritDoc} */
174 @Override
175 public RealMatrix add(final RealMatrix m)
176 throws IllegalArgumentException {
177 try {
178 return add((RealMatrixImpl) m);
179 } catch (ClassCastException cce) {
180 return super.add(m);
181 }
182 }
183
184 /**
185 * Compute the sum of this and <code>m</code>.
186 *
187 * @param m matrix to be added
188 * @return this + m
189 * @throws IllegalArgumentException if m is not the same size as this
190 */
191 public RealMatrixImpl add(final RealMatrixImpl m)
192 throws IllegalArgumentException {
193
194 // safety check
195 MatrixUtils.checkAdditionCompatible(this, m);
196
197 final int rowCount = getRowDimension();
198 final int columnCount = getColumnDimension();
199 final double[][] outData = new double[rowCount][columnCount];
200 for (int row = 0; row < rowCount; row++) {
201 final double[] dataRow = data[row];
202 final double[] mRow = m.data[row];
203 final double[] outDataRow = outData[row];
204 for (int col = 0; col < columnCount; col++) {
205 outDataRow[col] = dataRow[col] + mRow[col];
206 }
207 }
208
209 return new RealMatrixImpl(outData, false);
210
211 }
212
213 /** {@inheritDoc} */
214 @Override
215 public RealMatrix subtract(final RealMatrix m)
216 throws IllegalArgumentException {
217 try {
218 return subtract((RealMatrixImpl) m);
219 } catch (ClassCastException cce) {
220 return super.subtract(m);
221 }
222 }
223
224 /**
225 * Compute this minus <code>m</code>.
226 *
227 * @param m matrix to be subtracted
228 * @return this + m
229 * @throws IllegalArgumentException if m is not the same size as this
230 */
231 public RealMatrixImpl subtract(final RealMatrixImpl m)
232 throws IllegalArgumentException {
233
234 // safety check
235 MatrixUtils.checkSubtractionCompatible(this, m);
236
237 final int rowCount = getRowDimension();
238 final int columnCount = getColumnDimension();
239 final double[][] outData = new double[rowCount][columnCount];
240 for (int row = 0; row < rowCount; row++) {
241 final double[] dataRow = data[row];
242 final double[] mRow = m.data[row];
243 final double[] outDataRow = outData[row];
244 for (int col = 0; col < columnCount; col++) {
245 outDataRow[col] = dataRow[col] - mRow[col];
246 }
247 }
248
249 return new RealMatrixImpl(outData, false);
250
251 }
252
253 /** {@inheritDoc} */
254 @Override
255 public RealMatrix multiply(final RealMatrix m)
256 throws IllegalArgumentException {
257 try {
258 return multiply((RealMatrixImpl) m);
259 } catch (ClassCastException cce) {
260 return super.multiply(m);
261 }
262 }
263
264 /**
265 * Returns the result of postmultiplying this by <code>m</code>.
266 * @param m matrix to postmultiply by
267 * @return this*m
268 * @throws IllegalArgumentException
269 * if columnDimension(this) != rowDimension(m)
270 */
271 public RealMatrixImpl multiply(final RealMatrixImpl m)
272 throws IllegalArgumentException {
273
274 // safety check
275 MatrixUtils.checkMultiplicationCompatible(this, m);
276
277 final int nRows = this.getRowDimension();
278 final int nCols = m.getColumnDimension();
279 final int nSum = this.getColumnDimension();
280 final double[][] outData = new double[nRows][nCols];
281 for (int row = 0; row < nRows; row++) {
282 final double[] dataRow = data[row];
283 final double[] outDataRow = outData[row];
284 for (int col = 0; col < nCols; col++) {
285 double sum = 0;
286 for (int i = 0; i < nSum; i++) {
287 sum += dataRow[i] * m.data[i][col];
288 }
289 outDataRow[col] = sum;
290 }
291 }
292
293 return new RealMatrixImpl(outData, false);
294
295 }
296
297 /** {@inheritDoc} */
298 @Override
299 public double[][] getData() {
300 return copyOut();
301 }
302
303 /**
304 * Returns a reference to the underlying data array.
305 * <p>
306 * Does <strong>not</strong> make a fresh copy of the underlying data.</p>
307 *
308 * @return 2-dimensional array of entries
309 */
310 public double[][] getDataRef() {
311 return data;
312 }
313
314 /** {@inheritDoc} */
315 @Override
316 public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
317 throws MatrixIndexException {
318 if (data == null) {
319 if (row > 0) {
320 throw MathRuntimeException.createIllegalStateException(
321 LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET,
322 row);
323 }
324 if (column > 0) {
325 throw MathRuntimeException.createIllegalStateException(
326 LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET,
327 column);
328 }
329 final int nRows = subMatrix.length;
330 if (nRows == 0) {
331 throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
332 }
333
334 final int nCols = subMatrix[0].length;
335 if (nCols == 0) {
336 throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
337 }
338 data = new double[subMatrix.length][nCols];
339 for (int i = 0; i < data.length; ++i) {
340 if (subMatrix[i].length != nCols) {
341 throw MathRuntimeException.createIllegalArgumentException(
342 LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
343 nCols, subMatrix[i].length);
344 }
345 System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
346 }
347 } else {
348 super.setSubMatrix(subMatrix, row, column);
349 }
350
351 }
352
353 /** {@inheritDoc} */
354 @Override
355 public double getEntry(final int row, final int column)
356 throws MatrixIndexException {
357 try {
358 return data[row][column];
359 } catch (ArrayIndexOutOfBoundsException e) {
360 throw new MatrixIndexException(
361 LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
362 row, column, getRowDimension(), getColumnDimension());
363 }
364 }
365
366 /** {@inheritDoc} */
367 @Override
368 public void setEntry(final int row, final int column, final double value)
369 throws MatrixIndexException {
370 try {
371 data[row][column] = value;
372 } catch (ArrayIndexOutOfBoundsException e) {
373 throw new MatrixIndexException(
374 LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
375 row, column, getRowDimension(), getColumnDimension());
376 }
377 }
378
379 /** {@inheritDoc} */
380 @Override
381 public void addToEntry(final int row, final int column, final double increment)
382 throws MatrixIndexException {
383 try {
384 data[row][column] += increment;
385 } catch (ArrayIndexOutOfBoundsException e) {
386 throw new MatrixIndexException(
387 LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
388 row, column, getRowDimension(), getColumnDimension());
389 }
390 }
391
392 /** {@inheritDoc} */
393 @Override
394 public void multiplyEntry(final int row, final int column, final double factor)
395 throws MatrixIndexException {
396 try {
397 data[row][column] *= factor;
398 } catch (ArrayIndexOutOfBoundsException e) {
399 throw new MatrixIndexException(
400 LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
401 row, column, getRowDimension(), getColumnDimension());
402 }
403 }
404
405 /** {@inheritDoc} */
406 @Override
407 public int getRowDimension() {
408 return (data == null) ? 0 : data.length;
409 }
410
411 /** {@inheritDoc} */
412 @Override
413 public int getColumnDimension() {
414 return ((data == null) || (data[0] == null)) ? 0 : data[0].length;
415 }
416
417 /** {@inheritDoc} */
418 @Override
419 public double[] operate(final double[] v)
420 throws IllegalArgumentException {
421 final int nRows = this.getRowDimension();
422 final int nCols = this.getColumnDimension();
423 if (v.length != nCols) {
424 throw MathRuntimeException.createIllegalArgumentException(
425 LocalizedFormats.VECTOR_LENGTH_MISMATCH,
426 v.length, nCols);
427 }
428 final double[] out = new double[nRows];
429 for (int row = 0; row < nRows; row++) {
430 final double[] dataRow = data[row];
431 double sum = 0;
432 for (int i = 0; i < nCols; i++) {
433 sum += dataRow[i] * v[i];
434 }
435 out[row] = sum;
436 }
437 return out;
438 }
439
440 /** {@inheritDoc} */
441 @Override
442 public double[] preMultiply(final double[] v)
443 throws IllegalArgumentException {
444
445 final int nRows = getRowDimension();
446 final int nCols = getColumnDimension();
447 if (v.length != nRows) {
448 throw MathRuntimeException.createIllegalArgumentException(
449 LocalizedFormats.VECTOR_LENGTH_MISMATCH,
450 v.length, nRows);
451 }
452
453 final double[] out = new double[nCols];
454 for (int col = 0; col < nCols; ++col) {
455 double sum = 0;
456 for (int i = 0; i < nRows; ++i) {
457 sum += data[i][col] * v[i];
458 }
459 out[col] = sum;
460 }
461
462 return out;
463
464 }
465
466 /** {@inheritDoc} */
467 @Override
468 public double walkInRowOrder(final RealMatrixChangingVisitor visitor)
469 throws MatrixVisitorException {
470 final int rows = getRowDimension();
471 final int columns = getColumnDimension();
472 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
473 for (int i = 0; i < rows; ++i) {
474 final double[] rowI = data[i];
475 for (int j = 0; j < columns; ++j) {
476 rowI[j] = visitor.visit(i, j, rowI[j]);
477 }
478 }
479 return visitor.end();
480 }
481
482 /** {@inheritDoc} */
483 @Override
484 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor)
485 throws MatrixVisitorException {
486 final int rows = getRowDimension();
487 final int columns = getColumnDimension();
488 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
489 for (int i = 0; i < rows; ++i) {
490 final double[] rowI = data[i];
491 for (int j = 0; j < columns; ++j) {
492 visitor.visit(i, j, rowI[j]);
493 }
494 }
495 return visitor.end();
496 }
497
498 /** {@inheritDoc} */
499 @Override
500 public double walkInRowOrder(final RealMatrixChangingVisitor visitor,
501 final int startRow, final int endRow,
502 final int startColumn, final int endColumn)
503 throws MatrixIndexException, MatrixVisitorException {
504 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
505 visitor.start(getRowDimension(), getColumnDimension(),
506 startRow, endRow, startColumn, endColumn);
507 for (int i = startRow; i <= endRow; ++i) {
508 final double[] rowI = data[i];
509 for (int j = startColumn; j <= endColumn; ++j) {
510 rowI[j] = visitor.visit(i, j, rowI[j]);
511 }
512 }
513 return visitor.end();
514 }
515
516 /** {@inheritDoc} */
517 @Override
518 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
519 final int startRow, final int endRow,
520 final int startColumn, final int endColumn)
521 throws MatrixIndexException, MatrixVisitorException {
522 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
523 visitor.start(getRowDimension(), getColumnDimension(),
524 startRow, endRow, startColumn, endColumn);
525 for (int i = startRow; i <= endRow; ++i) {
526 final double[] rowI = data[i];
527 for (int j = startColumn; j <= endColumn; ++j) {
528 visitor.visit(i, j, rowI[j]);
529 }
530 }
531 return visitor.end();
532 }
533
534 /** {@inheritDoc} */
535 @Override
536 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor)
537 throws MatrixVisitorException {
538 final int rows = getRowDimension();
539 final int columns = getColumnDimension();
540 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
541 for (int j = 0; j < columns; ++j) {
542 for (int i = 0; i < rows; ++i) {
543 final double[] rowI = data[i];
544 rowI[j] = visitor.visit(i, j, rowI[j]);
545 }
546 }
547 return visitor.end();
548 }
549
550 /** {@inheritDoc} */
551 @Override
552 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor)
553 throws MatrixVisitorException {
554 final int rows = getRowDimension();
555 final int columns = getColumnDimension();
556 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
557 for (int j = 0; j < columns; ++j) {
558 for (int i = 0; i < rows; ++i) {
559 visitor.visit(i, j, data[i][j]);
560 }
561 }
562 return visitor.end();
563 }
564
565 /** {@inheritDoc} */
566 @Override
567 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor,
568 final int startRow, final int endRow,
569 final int startColumn, final int endColumn)
570 throws MatrixIndexException, MatrixVisitorException {
571 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
572 visitor.start(getRowDimension(), getColumnDimension(),
573 startRow, endRow, startColumn, endColumn);
574 for (int j = startColumn; j <= endColumn; ++j) {
575 for (int i = startRow; i <= endRow; ++i) {
576 final double[] rowI = data[i];
577 rowI[j] = visitor.visit(i, j, rowI[j]);
578 }
579 }
580 return visitor.end();
581 }
582
583 /** {@inheritDoc} */
584 @Override
585 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor,
586 final int startRow, final int endRow,
587 final int startColumn, final int endColumn)
588 throws MatrixIndexException, MatrixVisitorException {
589 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
590 visitor.start(getRowDimension(), getColumnDimension(),
591 startRow, endRow, startColumn, endColumn);
592 for (int j = startColumn; j <= endColumn; ++j) {
593 for (int i = startRow; i <= endRow; ++i) {
594 visitor.visit(i, j, data[i][j]);
595 }
596 }
597 return visitor.end();
598 }
599
600 /**
601 * Returns a fresh copy of the underlying data array.
602 *
603 * @return a copy of the underlying data array.
604 */
605 private double[][] copyOut() {
606 final int nRows = this.getRowDimension();
607 final double[][] out = new double[nRows][this.getColumnDimension()];
608 // can't copy 2-d array in one shot, otherwise get row references
609 for (int i = 0; i < nRows; i++) {
610 System.arraycopy(data[i], 0, out[i], 0, data[i].length);
611 }
612 return out;
613 }
614
615 /**
616 * Replaces data with a fresh copy of the input array.
617 * <p>
618 * Verifies that the input array is rectangular and non-empty.</p>
619 *
620 * @param in data to copy in
621 * @throws IllegalArgumentException if input array is empty or not
622 * rectangular
623 * @throws NullPointerException if input array is null
624 */
625 private void copyIn(final double[][] in) {
626 setSubMatrix(in, 0, 0);
627 }
628
629}
Note: See TracBrowser for help on using the repository browser.