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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
18
package org.apache.commons.math.linear;
20
import java.lang.reflect.Array;
21
import java.util.Arrays;
23
import org.apache.commons.math.Field;
24
import org.apache.commons.math.FieldElement;
25
import org.apache.commons.math.MathRuntimeException;
28
* Basic implementation of {@link FieldMatrix} methods regardless of the underlying storage.
29
* <p>All the methods implemented here use {@link #getEntry(int, int)} to access
30
* matrix elements. Derived class can provide faster implementations. </p>
32
* @param <T> the type of the field elements
33
* @version $Revision: 783702 $ $Date: 2009-06-11 04:54:02 -0400 (Thu, 11 Jun 2009) $
36
public abstract class AbstractFieldMatrix<T extends FieldElement<T>> implements FieldMatrix<T> {
38
/** Field to which the elements belong. */
39
private final Field<T> field;
42
* Get the elements type from an array.
43
* @param <T> the type of the field elements
45
* @return field to which array elements belong
46
* @exception IllegalArgumentException if array is empty
48
protected static <T extends FieldElement<T>> Field<T> extractField(final T[][] d)
49
throws IllegalArgumentException {
51
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row");
53
if (d[0].length == 0) {
54
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column");
56
return d[0][0].getField();
60
* Get the elements type from an array.
61
* @param <T> the type of the field elements
63
* @return field to which array elements belong
64
* @exception IllegalArgumentException if array is empty
66
protected static <T extends FieldElement<T>> Field<T> extractField(final T[] d)
67
throws IllegalArgumentException {
69
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row");
71
return d[0].getField();
74
/** Build an array of elements.
76
* Complete arrays are filled with field.getZero()
78
* @param <T> the type of the field elements
79
* @param field field to which array elements belong
80
* @param rows number of rows
81
* @param columns number of columns (may be negative to build partial
82
* arrays in the same way <code>new Field[rows][]</code> works)
85
@SuppressWarnings("unchecked")
86
protected static <T extends FieldElement<T>> T[][] buildArray(final Field<T> field,
90
T[] dummyRow = (T[]) Array.newInstance(field.getZero().getClass(), 0);
91
return (T[][]) Array.newInstance(dummyRow.getClass(), rows);
94
(T[][]) Array.newInstance(field.getZero().getClass(), new int[] { rows, columns });
95
for (int i = 0; i < array.length; ++i) {
96
Arrays.fill(array[i], field.getZero());
101
/** Build an array of elements.
103
* Arrays are filled with field.getZero()
105
* @param <T> the type of the field elements
106
* @param field field to which array elements belong
107
* @param length of the array
108
* @return a new array
110
@SuppressWarnings("unchecked")
111
protected static <T extends FieldElement<T>> T[] buildArray(final Field<T> field,
113
T[] array = (T[]) Array.newInstance(field.getZero().getClass(), length);
114
Arrays.fill(array, field.getZero());
119
* Constructor for use with Serializable
121
protected AbstractFieldMatrix() {
126
* Creates a matrix with no data
127
* @param field field to which the elements belong
129
protected AbstractFieldMatrix(final Field<T> field) {
134
* Create a new FieldMatrix<T> with the supplied row and column dimensions.
136
* @param field field to which the elements belong
137
* @param rowDimension the number of rows in the new matrix
138
* @param columnDimension the number of columns in the new matrix
139
* @throws IllegalArgumentException if row or column dimension is not positive
141
protected AbstractFieldMatrix(final Field<T> field,
142
final int rowDimension, final int columnDimension)
143
throws IllegalArgumentException {
144
if (rowDimension <= 0 ) {
145
throw MathRuntimeException.createIllegalArgumentException(
146
"invalid row dimension {0} (must be positive)",
149
if (columnDimension <= 0) {
150
throw MathRuntimeException.createIllegalArgumentException(
151
"invalid column dimension {0} (must be positive)",
158
public Field<T> getField() {
163
public abstract FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension)
164
throws IllegalArgumentException;
167
public abstract FieldMatrix<T> copy();
170
public FieldMatrix<T> add(FieldMatrix<T> m) throws IllegalArgumentException {
173
checkAdditionCompatible(m);
175
final int rowCount = getRowDimension();
176
final int columnCount = getColumnDimension();
177
final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
178
for (int row = 0; row < rowCount; ++row) {
179
for (int col = 0; col < columnCount; ++col) {
180
out.setEntry(row, col, getEntry(row, col).add(m.getEntry(row, col)));
189
public FieldMatrix<T> subtract(final FieldMatrix<T> m) throws IllegalArgumentException {
192
checkSubtractionCompatible(m);
194
final int rowCount = getRowDimension();
195
final int columnCount = getColumnDimension();
196
final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
197
for (int row = 0; row < rowCount; ++row) {
198
for (int col = 0; col < columnCount; ++col) {
199
out.setEntry(row, col, getEntry(row, col).subtract(m.getEntry(row, col)));
208
public FieldMatrix<T> scalarAdd(final T d) {
210
final int rowCount = getRowDimension();
211
final int columnCount = getColumnDimension();
212
final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
213
for (int row = 0; row < rowCount; ++row) {
214
for (int col = 0; col < columnCount; ++col) {
215
out.setEntry(row, col, getEntry(row, col).add(d));
224
public FieldMatrix<T> scalarMultiply(final T d) {
226
final int rowCount = getRowDimension();
227
final int columnCount = getColumnDimension();
228
final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
229
for (int row = 0; row < rowCount; ++row) {
230
for (int col = 0; col < columnCount; ++col) {
231
out.setEntry(row, col, getEntry(row, col).multiply(d));
240
public FieldMatrix<T> multiply(final FieldMatrix<T> m)
241
throws IllegalArgumentException {
244
checkMultiplicationCompatible(m);
246
final int nRows = getRowDimension();
247
final int nCols = m.getColumnDimension();
248
final int nSum = getColumnDimension();
249
final FieldMatrix<T> out = createMatrix(nRows, nCols);
250
for (int row = 0; row < nRows; ++row) {
251
for (int col = 0; col < nCols; ++col) {
252
T sum = field.getZero();
253
for (int i = 0; i < nSum; ++i) {
254
sum = sum.add(getEntry(row, i).multiply(m.getEntry(i, col)));
256
out.setEntry(row, col, sum);
265
public FieldMatrix<T> preMultiply(final FieldMatrix<T> m)
266
throws IllegalArgumentException {
267
return m.multiply(this);
271
public T[][] getData() {
273
final T[][] data = buildArray(field, getRowDimension(), getColumnDimension());
275
for (int i = 0; i < data.length; ++i) {
276
final T[] dataI = data[i];
277
for (int j = 0; j < dataI.length; ++j) {
278
dataI[j] = getEntry(i, j);
287
public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow,
288
final int startColumn, final int endColumn)
289
throws MatrixIndexException {
291
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
293
final FieldMatrix<T> subMatrix =
294
createMatrix(endRow - startRow + 1, endColumn - startColumn + 1);
295
for (int i = startRow; i <= endRow; ++i) {
296
for (int j = startColumn; j <= endColumn; ++j) {
297
subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j));
306
public FieldMatrix<T> getSubMatrix(final int[] selectedRows, final int[] selectedColumns)
307
throws MatrixIndexException {
310
checkSubMatrixIndex(selectedRows, selectedColumns);
313
final FieldMatrix<T> subMatrix =
314
createMatrix(selectedRows.length, selectedColumns.length);
315
subMatrix.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor<T>(field.getZero()) {
319
public T visit(final int row, final int column, final T value) {
320
return getEntry(selectedRows[row], selectedColumns[column]);
330
public void copySubMatrix(final int startRow, final int endRow,
331
final int startColumn, final int endColumn,
332
final T[][] destination)
333
throws MatrixIndexException, IllegalArgumentException {
336
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
337
final int rowsCount = endRow + 1 - startRow;
338
final int columnsCount = endColumn + 1 - startColumn;
339
if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) {
340
throw MathRuntimeException.createIllegalArgumentException(
341
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
342
destination.length, destination[0].length,
343
rowsCount, columnsCount);
347
walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) {
349
/** Initial row index. */
350
private int startRow;
352
/** Initial column index. */
353
private int startColumn;
357
public void start(final int rows, final int columns,
358
final int startRow, final int endRow,
359
final int startColumn, final int endColumn) {
360
this.startRow = startRow;
361
this.startColumn = startColumn;
366
public void visit(final int row, final int column, final T value) {
367
destination[row - startRow][column - startColumn] = value;
370
}, startRow, endRow, startColumn, endColumn);
375
public void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination)
376
throws MatrixIndexException, IllegalArgumentException {
379
checkSubMatrixIndex(selectedRows, selectedColumns);
380
if ((destination.length < selectedRows.length) ||
381
(destination[0].length < selectedColumns.length)) {
382
throw MathRuntimeException.createIllegalArgumentException(
383
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
384
destination.length, destination[0].length,
385
selectedRows.length, selectedColumns.length);
389
for (int i = 0; i < selectedRows.length; i++) {
390
final T[] destinationI = destination[i];
391
for (int j = 0; j < selectedColumns.length; j++) {
392
destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]);
399
public void setSubMatrix(final T[][] subMatrix, final int row, final int column)
400
throws MatrixIndexException {
402
final int nRows = subMatrix.length;
404
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row");
407
final int nCols = subMatrix[0].length;
409
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column");
412
for (int r = 1; r < nRows; ++r) {
413
if (subMatrix[r].length != nCols) {
414
throw MathRuntimeException.createIllegalArgumentException(
415
"some rows have length {0} while others have length {1}",
416
nCols, subMatrix[r].length);
421
checkColumnIndex(column);
422
checkRowIndex(nRows + row - 1);
423
checkColumnIndex(nCols + column - 1);
425
for (int i = 0; i < nRows; ++i) {
426
for (int j = 0; j < nCols; ++j) {
427
setEntry(row + i, column + j, subMatrix[i][j]);
434
public FieldMatrix<T> getRowMatrix(final int row)
435
throws MatrixIndexException {
438
final int nCols = getColumnDimension();
439
final FieldMatrix<T> out = createMatrix(1, nCols);
440
for (int i = 0; i < nCols; ++i) {
441
out.setEntry(0, i, getEntry(row, i));
449
public void setRowMatrix(final int row, final FieldMatrix<T> matrix)
450
throws MatrixIndexException, InvalidMatrixException {
453
final int nCols = getColumnDimension();
454
if ((matrix.getRowDimension() != 1) ||
455
(matrix.getColumnDimension() != nCols)) {
456
throw new InvalidMatrixException(
457
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
458
matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols);
460
for (int i = 0; i < nCols; ++i) {
461
setEntry(row, i, matrix.getEntry(0, i));
467
public FieldMatrix<T> getColumnMatrix(final int column)
468
throws MatrixIndexException {
470
checkColumnIndex(column);
471
final int nRows = getRowDimension();
472
final FieldMatrix<T> out = createMatrix(nRows, 1);
473
for (int i = 0; i < nRows; ++i) {
474
out.setEntry(i, 0, getEntry(i, column));
482
public void setColumnMatrix(final int column, final FieldMatrix<T> matrix)
483
throws MatrixIndexException, InvalidMatrixException {
485
checkColumnIndex(column);
486
final int nRows = getRowDimension();
487
if ((matrix.getRowDimension() != nRows) ||
488
(matrix.getColumnDimension() != 1)) {
489
throw new InvalidMatrixException(
490
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
491
matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1);
493
for (int i = 0; i < nRows; ++i) {
494
setEntry(i, column, matrix.getEntry(i, 0));
500
public FieldVector<T> getRowVector(final int row)
501
throws MatrixIndexException {
502
return new ArrayFieldVector<T>(getRow(row), false);
506
public void setRowVector(final int row, final FieldVector<T> vector)
507
throws MatrixIndexException, InvalidMatrixException {
510
final int nCols = getColumnDimension();
511
if (vector.getDimension() != nCols) {
512
throw new InvalidMatrixException(
513
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
514
1, vector.getDimension(), 1, nCols);
516
for (int i = 0; i < nCols; ++i) {
517
setEntry(row, i, vector.getEntry(i));
523
public FieldVector<T> getColumnVector(final int column)
524
throws MatrixIndexException {
525
return new ArrayFieldVector<T>(getColumn(column), false);
529
public void setColumnVector(final int column, final FieldVector<T> vector)
530
throws MatrixIndexException, InvalidMatrixException {
532
checkColumnIndex(column);
533
final int nRows = getRowDimension();
534
if (vector.getDimension() != nRows) {
535
throw new InvalidMatrixException(
536
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
537
vector.getDimension(), 1, nRows, 1);
539
for (int i = 0; i < nRows; ++i) {
540
setEntry(i, column, vector.getEntry(i));
546
public T[] getRow(final int row)
547
throws MatrixIndexException {
550
final int nCols = getColumnDimension();
551
final T[] out = buildArray(field, nCols);
552
for (int i = 0; i < nCols; ++i) {
553
out[i] = getEntry(row, i);
561
public void setRow(final int row, final T[] array)
562
throws MatrixIndexException, InvalidMatrixException {
565
final int nCols = getColumnDimension();
566
if (array.length != nCols) {
567
throw new InvalidMatrixException(
568
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
569
1, array.length, 1, nCols);
571
for (int i = 0; i < nCols; ++i) {
572
setEntry(row, i, array[i]);
578
public T[] getColumn(final int column)
579
throws MatrixIndexException {
581
checkColumnIndex(column);
582
final int nRows = getRowDimension();
583
final T[] out = buildArray(field, nRows);
584
for (int i = 0; i < nRows; ++i) {
585
out[i] = getEntry(i, column);
593
public void setColumn(final int column, final T[] array)
594
throws MatrixIndexException, InvalidMatrixException {
596
checkColumnIndex(column);
597
final int nRows = getRowDimension();
598
if (array.length != nRows) {
599
throw new InvalidMatrixException(
600
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
601
array.length, 1, nRows, 1);
603
for (int i = 0; i < nRows; ++i) {
604
setEntry(i, column, array[i]);
610
public abstract T getEntry(int row, int column)
611
throws MatrixIndexException;
614
public abstract void setEntry(int row, int column, T value)
615
throws MatrixIndexException;
618
public abstract void addToEntry(int row, int column, T increment)
619
throws MatrixIndexException;
622
public abstract void multiplyEntry(int row, int column, T factor)
623
throws MatrixIndexException;
626
public FieldMatrix<T> transpose() {
628
final int nRows = getRowDimension();
629
final int nCols = getColumnDimension();
630
final FieldMatrix<T> out = createMatrix(nCols, nRows);
631
walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) {
635
public void visit(final int row, final int column, final T value) {
636
out.setEntry(column, row, value);
646
public boolean isSquare() {
647
return (getColumnDimension() == getRowDimension());
651
public abstract int getRowDimension();
654
public abstract int getColumnDimension();
658
throws NonSquareMatrixException {
659
final int nRows = getRowDimension();
660
final int nCols = getColumnDimension();
661
if (nRows != nCols) {
662
throw new NonSquareMatrixException(nRows, nCols);
664
T trace = field.getZero();
665
for (int i = 0; i < nRows; ++i) {
666
trace = trace.add(getEntry(i, i));
672
public T[] operate(final T[] v)
673
throws IllegalArgumentException {
675
final int nRows = getRowDimension();
676
final int nCols = getColumnDimension();
677
if (v.length != nCols) {
678
throw MathRuntimeException.createIllegalArgumentException(
679
"vector length mismatch: got {0} but expected {1}",
683
final T[] out = buildArray(field, nRows);
684
for (int row = 0; row < nRows; ++row) {
685
T sum = field.getZero();
686
for (int i = 0; i < nCols; ++i) {
687
sum = sum.add(getEntry(row, i).multiply(v[i]));
697
public FieldVector<T> operate(final FieldVector<T> v)
698
throws IllegalArgumentException {
700
return new ArrayFieldVector<T>(operate(((ArrayFieldVector<T>) v).getDataRef()), false);
701
} catch (ClassCastException cce) {
702
final int nRows = getRowDimension();
703
final int nCols = getColumnDimension();
704
if (v.getDimension() != nCols) {
705
throw MathRuntimeException.createIllegalArgumentException(
706
"vector length mismatch: got {0} but expected {1}",
707
v.getDimension(), nCols);
710
final T[] out = buildArray(field, nRows);
711
for (int row = 0; row < nRows; ++row) {
712
T sum = field.getZero();
713
for (int i = 0; i < nCols; ++i) {
714
sum = sum.add(getEntry(row, i).multiply(v.getEntry(i)));
719
return new ArrayFieldVector<T>(out, false);
724
public T[] preMultiply(final T[] v)
725
throws IllegalArgumentException {
727
final int nRows = getRowDimension();
728
final int nCols = getColumnDimension();
729
if (v.length != nRows) {
730
throw MathRuntimeException.createIllegalArgumentException(
731
"vector length mismatch: got {0} but expected {1}",
735
final T[] out = buildArray(field, nCols);
736
for (int col = 0; col < nCols; ++col) {
737
T sum = field.getZero();
738
for (int i = 0; i < nRows; ++i) {
739
sum = sum.add(getEntry(i, col).multiply(v[i]));
749
public FieldVector<T> preMultiply(final FieldVector<T> v)
750
throws IllegalArgumentException {
752
return new ArrayFieldVector<T>(preMultiply(((ArrayFieldVector<T>) v).getDataRef()), false);
753
} catch (ClassCastException cce) {
755
final int nRows = getRowDimension();
756
final int nCols = getColumnDimension();
757
if (v.getDimension() != nRows) {
758
throw MathRuntimeException.createIllegalArgumentException(
759
"vector length mismatch: got {0} but expected {1}",
760
v.getDimension(), nRows);
763
final T[] out = buildArray(field, nCols);
764
for (int col = 0; col < nCols; ++col) {
765
T sum = field.getZero();
766
for (int i = 0; i < nRows; ++i) {
767
sum = sum.add(getEntry(i, col).multiply(v.getEntry(i)));
772
return new ArrayFieldVector<T>(out);
778
public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor)
779
throws MatrixVisitorException {
780
final int rows = getRowDimension();
781
final int columns = getColumnDimension();
782
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
783
for (int row = 0; row < rows; ++row) {
784
for (int column = 0; column < columns; ++column) {
785
final T oldValue = getEntry(row, column);
786
final T newValue = visitor.visit(row, column, oldValue);
787
setEntry(row, column, newValue);
790
return visitor.end();
794
public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor)
795
throws MatrixVisitorException {
796
final int rows = getRowDimension();
797
final int columns = getColumnDimension();
798
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
799
for (int row = 0; row < rows; ++row) {
800
for (int column = 0; column < columns; ++column) {
801
visitor.visit(row, column, getEntry(row, column));
804
return visitor.end();
808
public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
809
final int startRow, final int endRow,
810
final int startColumn, final int endColumn)
811
throws MatrixIndexException, MatrixVisitorException {
812
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
813
visitor.start(getRowDimension(), getColumnDimension(),
814
startRow, endRow, startColumn, endColumn);
815
for (int row = startRow; row <= endRow; ++row) {
816
for (int column = startColumn; column <= endColumn; ++column) {
817
final T oldValue = getEntry(row, column);
818
final T newValue = visitor.visit(row, column, oldValue);
819
setEntry(row, column, newValue);
822
return visitor.end();
826
public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
827
final int startRow, final int endRow,
828
final int startColumn, final int endColumn)
829
throws MatrixIndexException, MatrixVisitorException {
830
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
831
visitor.start(getRowDimension(), getColumnDimension(),
832
startRow, endRow, startColumn, endColumn);
833
for (int row = startRow; row <= endRow; ++row) {
834
for (int column = startColumn; column <= endColumn; ++column) {
835
visitor.visit(row, column, getEntry(row, column));
838
return visitor.end();
842
public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor)
843
throws MatrixVisitorException {
844
final int rows = getRowDimension();
845
final int columns = getColumnDimension();
846
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
847
for (int column = 0; column < columns; ++column) {
848
for (int row = 0; row < rows; ++row) {
849
final T oldValue = getEntry(row, column);
850
final T newValue = visitor.visit(row, column, oldValue);
851
setEntry(row, column, newValue);
854
return visitor.end();
858
public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor)
859
throws MatrixVisitorException {
860
final int rows = getRowDimension();
861
final int columns = getColumnDimension();
862
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
863
for (int column = 0; column < columns; ++column) {
864
for (int row = 0; row < rows; ++row) {
865
visitor.visit(row, column, getEntry(row, column));
868
return visitor.end();
872
public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor,
873
final int startRow, final int endRow,
874
final int startColumn, final int endColumn)
875
throws MatrixIndexException, MatrixVisitorException {
876
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
877
visitor.start(getRowDimension(), getColumnDimension(),
878
startRow, endRow, startColumn, endColumn);
879
for (int column = startColumn; column <= endColumn; ++column) {
880
for (int row = startRow; row <= endRow; ++row) {
881
final T oldValue = getEntry(row, column);
882
final T newValue = visitor.visit(row, column, oldValue);
883
setEntry(row, column, newValue);
886
return visitor.end();
890
public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor,
891
final int startRow, final int endRow,
892
final int startColumn, final int endColumn)
893
throws MatrixIndexException, MatrixVisitorException {
894
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
895
visitor.start(getRowDimension(), getColumnDimension(),
896
startRow, endRow, startColumn, endColumn);
897
for (int column = startColumn; column <= endColumn; ++column) {
898
for (int row = startRow; row <= endRow; ++row) {
899
visitor.visit(row, column, getEntry(row, column));
902
return visitor.end();
906
public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor)
907
throws MatrixVisitorException {
908
return walkInRowOrder(visitor);
912
public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor)
913
throws MatrixVisitorException {
914
return walkInRowOrder(visitor);
918
public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor,
919
final int startRow, final int endRow,
920
final int startColumn, final int endColumn)
921
throws MatrixIndexException, MatrixVisitorException {
922
return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
926
public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor,
927
final int startRow, final int endRow,
928
final int startColumn, final int endColumn)
929
throws MatrixIndexException, MatrixVisitorException {
930
return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
934
* Get a string representation for this matrix.
935
* @return a string representation for this matrix
938
public String toString() {
939
final int nRows = getRowDimension();
940
final int nCols = getColumnDimension();
941
final StringBuffer res = new StringBuffer();
942
String fullClassName = getClass().getName();
943
String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
944
res.append(shortClassName).append("{");
946
for (int i = 0; i < nRows; ++i) {
951
for (int j = 0; j < nCols; ++j) {
955
res.append(getEntry(i, j));
961
return res.toString();
966
* Returns true iff <code>object</code> is a
967
* <code>FieldMatrix</code> instance with the same dimensions as this
968
* and all corresponding matrix entries are equal.
970
* @param object the object to test equality against.
971
* @return true if object equals this
973
@SuppressWarnings("unchecked")
975
public boolean equals(final Object object) {
976
if (object == this ) {
979
if (object instanceof FieldMatrix == false) {
982
FieldMatrix<T> m = (FieldMatrix<T>) object;
983
final int nRows = getRowDimension();
984
final int nCols = getColumnDimension();
985
if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) {
988
for (int row = 0; row < nRows; ++row) {
989
for (int col = 0; col < nCols; ++col) {
990
if (!getEntry(row, col).equals(m.getEntry(row, col))) {
999
* Computes a hashcode for the matrix.
1001
* @return hashcode for matrix
1004
public int hashCode() {
1006
final int nRows = getRowDimension();
1007
final int nCols = getColumnDimension();
1008
ret = ret * 31 + nRows;
1009
ret = ret * 31 + nCols;
1010
for (int row = 0; row < nRows; ++row) {
1011
for (int col = 0; col < nCols; ++col) {
1012
ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * getEntry(row, col).hashCode();
1019
* Check if a row index is valid.
1020
* @param row row index to check
1021
* @exception MatrixIndexException if index is not valid
1023
protected void checkRowIndex(final int row) {
1024
if (row < 0 || row >= getRowDimension()) {
1025
throw new MatrixIndexException("row index {0} out of allowed range [{1}, {2}]",
1026
row, 0, getRowDimension() - 1);
1031
* Check if a column index is valid.
1032
* @param column column index to check
1033
* @exception MatrixIndexException if index is not valid
1035
protected void checkColumnIndex(final int column)
1036
throws MatrixIndexException {
1037
if (column < 0 || column >= getColumnDimension()) {
1038
throw new MatrixIndexException("column index {0} out of allowed range [{1}, {2}]",
1039
column, 0, getColumnDimension() - 1);
1044
* Check if submatrix ranges indices are valid.
1045
* Rows and columns are indicated counting from 0 to n-1.
1047
* @param startRow Initial row index
1048
* @param endRow Final row index
1049
* @param startColumn Initial column index
1050
* @param endColumn Final column index
1051
* @exception MatrixIndexException if the indices are not valid
1053
protected void checkSubMatrixIndex(final int startRow, final int endRow,
1054
final int startColumn, final int endColumn) {
1055
checkRowIndex(startRow);
1056
checkRowIndex(endRow);
1057
if (startRow > endRow) {
1058
throw new MatrixIndexException("initial row {0} after final row {1}",
1062
checkColumnIndex(startColumn);
1063
checkColumnIndex(endColumn);
1064
if (startColumn > endColumn) {
1065
throw new MatrixIndexException("initial column {0} after final column {1}",
1066
startColumn, endColumn);
1073
* Check if submatrix ranges indices are valid.
1074
* Rows and columns are indicated counting from 0 to n-1.
1076
* @param selectedRows Array of row indices.
1077
* @param selectedColumns Array of column indices.
1078
* @exception MatrixIndexException if row or column selections are not valid
1080
protected void checkSubMatrixIndex(final int[] selectedRows, final int[] selectedColumns) {
1081
if (selectedRows.length * selectedColumns.length == 0) {
1082
if (selectedRows.length == 0) {
1083
throw new MatrixIndexException("empty selected row index array");
1085
throw new MatrixIndexException("empty selected column index array");
1088
for (final int row : selectedRows) {
1091
for (final int column : selectedColumns) {
1092
checkColumnIndex(column);
1097
* Check if a matrix is addition compatible with the instance
1098
* @param m matrix to check
1099
* @exception IllegalArgumentException if matrix is not addition compatible with instance
1101
protected void checkAdditionCompatible(final FieldMatrix<T> m) {
1102
if ((getRowDimension() != m.getRowDimension()) ||
1103
(getColumnDimension() != m.getColumnDimension())) {
1104
throw MathRuntimeException.createIllegalArgumentException(
1105
"{0}x{1} and {2}x{3} matrices are not addition compatible",
1106
getRowDimension(), getColumnDimension(),
1107
m.getRowDimension(), m.getColumnDimension());
1112
* Check if a matrix is subtraction compatible with the instance
1113
* @param m matrix to check
1114
* @exception IllegalArgumentException if matrix is not subtraction compatible with instance
1116
protected void checkSubtractionCompatible(final FieldMatrix<T> m) {
1117
if ((getRowDimension() != m.getRowDimension()) ||
1118
(getColumnDimension() != m.getColumnDimension())) {
1119
throw MathRuntimeException.createIllegalArgumentException(
1120
"{0}x{1} and {2}x{3} matrices are not subtraction compatible",
1121
getRowDimension(), getColumnDimension(),
1122
m.getRowDimension(), m.getColumnDimension());
1127
* Check if a matrix is multiplication compatible with the instance
1128
* @param m matrix to check
1129
* @exception IllegalArgumentException if matrix is not multiplication compatible with instance
1131
protected void checkMultiplicationCompatible(final FieldMatrix<T> m) {
1132
if (getColumnDimension() != m.getRowDimension()) {
1133
throw MathRuntimeException.createIllegalArgumentException(
1134
"{0}x{1} and {2}x{3} matrices are not multiplication compatible",
1135
getRowDimension(), getColumnDimension(),
1136
m.getRowDimension(), m.getColumnDimension());