1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.linear;
24
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import org.hipparchus.Field;
29 import org.hipparchus.FieldElement;
30 import org.hipparchus.exception.LocalizedCoreFormats;
31 import org.hipparchus.exception.MathIllegalArgumentException;
32 import org.hipparchus.exception.NullArgumentException;
33 import org.hipparchus.util.MathArrays;
34
35
36
37
38
39
40
41
42
43 public abstract class AbstractFieldMatrix<T extends FieldElement<T>>
44 implements FieldMatrix<T> {
45
46 private final Field<T> field;
47
48
49
50
51 protected AbstractFieldMatrix() {
52 field = null;
53 }
54
55
56
57
58
59 protected AbstractFieldMatrix(final Field<T> field) {
60 this.field = field;
61 }
62
63
64
65
66
67
68
69
70
71
72 protected AbstractFieldMatrix(final Field<T> field,
73 final int rowDimension,
74 final int columnDimension)
75 throws MathIllegalArgumentException {
76 if (rowDimension <= 0) {
77 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSION,
78 rowDimension);
79 }
80 if (columnDimension <= 0) {
81 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSION,
82 columnDimension);
83 }
84 this.field = field;
85 }
86
87
88
89
90
91
92
93
94
95
96 protected static <T extends FieldElement<T>> Field<T> extractField(final T[][] d)
97 throws MathIllegalArgumentException, NullArgumentException {
98 if (d == null) {
99 throw new NullArgumentException();
100 }
101 if (d.length == 0) {
102 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_ROW);
103 }
104 if (d[0].length == 0) {
105 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_COLUMN);
106 }
107 return d[0][0].getField();
108 }
109
110
111
112
113
114
115
116
117
118 protected static <T extends FieldElement<T>> Field<T> extractField(final T[] d)
119 throws MathIllegalArgumentException {
120 if (d.length == 0) {
121 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_ROW);
122 }
123 return d[0].getField();
124 }
125
126
127 @Override
128 public Field<T> getField() {
129 return field;
130 }
131
132
133 @Override
134 public abstract FieldMatrix<T> createMatrix(int rowDimension, int columnDimension)
135 throws MathIllegalArgumentException;
136
137
138 @Override
139 public abstract FieldMatrix<T> copy();
140
141
142 @Override
143 public FieldMatrix<T> add(FieldMatrix<T> m)
144 throws MathIllegalArgumentException {
145
146 checkAdditionCompatible(m);
147
148 final int rowCount = getRowDimension();
149 final int columnCount = getColumnDimension();
150 final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
151 for (int row = 0; row < rowCount; ++row) {
152 for (int col = 0; col < columnCount; ++col) {
153 out.setEntry(row, col, getEntry(row, col).add(m.getEntry(row, col)));
154 }
155 }
156
157 return out;
158 }
159
160
161 @Override
162 public FieldMatrix<T> subtract(final FieldMatrix<T> m)
163 throws MathIllegalArgumentException {
164
165 checkSubtractionCompatible(m);
166
167 final int rowCount = getRowDimension();
168 final int columnCount = getColumnDimension();
169 final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
170 for (int row = 0; row < rowCount; ++row) {
171 for (int col = 0; col < columnCount; ++col) {
172 out.setEntry(row, col, getEntry(row, col).subtract(m.getEntry(row, col)));
173 }
174 }
175
176 return out;
177 }
178
179
180 @Override
181 public FieldMatrix<T> scalarAdd(final T d) {
182
183 final int rowCount = getRowDimension();
184 final int columnCount = getColumnDimension();
185 final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
186 for (int row = 0; row < rowCount; ++row) {
187 for (int col = 0; col < columnCount; ++col) {
188 out.setEntry(row, col, getEntry(row, col).add(d));
189 }
190 }
191
192 return out;
193 }
194
195
196 @Override
197 public FieldMatrix<T> scalarMultiply(final T d) {
198 final int rowCount = getRowDimension();
199 final int columnCount = getColumnDimension();
200 final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
201 for (int row = 0; row < rowCount; ++row) {
202 for (int col = 0; col < columnCount; ++col) {
203 out.setEntry(row, col, getEntry(row, col).multiply(d));
204 }
205 }
206
207 return out;
208 }
209
210
211 @Override
212 public FieldMatrix<T> multiply(final FieldMatrix<T> m)
213 throws MathIllegalArgumentException {
214
215 checkMultiplicationCompatible(m);
216
217 final int nRows = getRowDimension();
218 final int nCols = m.getColumnDimension();
219 final int nSum = getColumnDimension();
220 final FieldMatrix<T> out = createMatrix(nRows, nCols);
221 for (int row = 0; row < nRows; ++row) {
222 for (int col = 0; col < nCols; ++col) {
223 T sum = field.getZero();
224 for (int i = 0; i < nSum; ++i) {
225 sum = sum.add(getEntry(row, i).multiply(m.getEntry(i, col)));
226 }
227 out.setEntry(row, col, sum);
228 }
229 }
230
231 return out;
232 }
233
234
235 @Override
236 public FieldMatrix<T> preMultiply(final FieldMatrix<T> m)
237 throws MathIllegalArgumentException {
238 return m.multiply(this);
239 }
240
241
242 @Override
243 public FieldMatrix<T> power(final int p) throws MathIllegalArgumentException {
244 if (p < 0) {
245 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_SMALL, p, 0);
246 }
247
248 if (!isSquare()) {
249 throw new MathIllegalArgumentException(LocalizedCoreFormats.NON_SQUARE_MATRIX,
250 getRowDimension(), getColumnDimension());
251 }
252
253 if (p == 0) {
254 return MatrixUtils.createFieldIdentityMatrix(this.getField(), this.getRowDimension());
255 }
256
257 if (p == 1) {
258 return this.copy();
259 }
260
261 final int power = p - 1;
262
263
264
265
266
267
268
269
270 final char[] binaryRepresentation = Integer.toBinaryString(power).toCharArray();
271 final List<Integer> nonZeroPositions = new ArrayList<>();
272
273 for (int i = 0; i < binaryRepresentation.length; ++i) {
274 if (binaryRepresentation[i] == '1') {
275 final int pos = binaryRepresentation.length - i - 1;
276 nonZeroPositions.add(pos);
277 }
278 }
279
280 List<FieldMatrix<T>> results = new ArrayList<>(binaryRepresentation.length);
281
282 results.add(0, this.copy());
283
284 for (int i = 1; i < binaryRepresentation.length; ++i) {
285 final FieldMatrix<T> s = results.get(i - 1);
286 final FieldMatrix<T> r = s.multiply(s);
287 results.add(i, r);
288 }
289
290 FieldMatrix<T> result = this.copy();
291
292 for (Integer i : nonZeroPositions) {
293 result = result.multiply(results.get(i));
294 }
295
296 return result;
297 }
298
299
300 @Override
301 public T[][] getData() {
302 final T[][] data = MathArrays.buildArray(field, getRowDimension(), getColumnDimension());
303
304 for (int i = 0; i < data.length; ++i) {
305 final T[] dataI = data[i];
306 for (int j = 0; j < dataI.length; ++j) {
307 dataI[j] = getEntry(i, j);
308 }
309 }
310
311 return data;
312 }
313
314
315 @Override
316 public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow,
317 final int startColumn, final int endColumn)
318 throws MathIllegalArgumentException {
319 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
320
321 final FieldMatrix<T> subMatrix =
322 createMatrix(endRow - startRow + 1, endColumn - startColumn + 1);
323 for (int i = startRow; i <= endRow; ++i) {
324 for (int j = startColumn; j <= endColumn; ++j) {
325 subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j));
326 }
327 }
328
329 return subMatrix;
330
331 }
332
333
334 @Override
335 public FieldMatrix<T> getSubMatrix(final int[] selectedRows,
336 final int[] selectedColumns)
337 throws MathIllegalArgumentException, NullArgumentException {
338
339
340 checkSubMatrixIndex(selectedRows, selectedColumns);
341
342
343 final FieldMatrix<T> subMatrix =
344 createMatrix(selectedRows.length, selectedColumns.length);
345 subMatrix.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor<T>(field.getZero()) {
346
347
348 @Override
349 public T visit(final int row, final int column, final T value) {
350 return getEntry(selectedRows[row], selectedColumns[column]);
351 }
352
353 });
354
355 return subMatrix;
356
357 }
358
359
360 @Override
361 public void copySubMatrix(final int startRow, final int endRow,
362 final int startColumn, final int endColumn,
363 final T[][] destination)
364 throws MathIllegalArgumentException {
365
366 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
367 final int rowsCount = endRow + 1 - startRow;
368 final int columnsCount = endColumn + 1 - startColumn;
369 if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) {
370 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
371 destination.length, destination[0].length,
372 rowsCount, columnsCount);
373 }
374
375
376 walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) {
377
378
379 private int startRow;
380
381
382 private int startColumn;
383
384
385 @Override
386 public void start(final int rows, final int columns,
387 final int startRow, final int endRow,
388 final int startColumn, final int endColumn) {
389 this.startRow = startRow;
390 this.startColumn = startColumn;
391 }
392
393
394 @Override
395 public void visit(final int row, final int column, final T value) {
396 destination[row - startRow][column - startColumn] = value;
397 }
398
399 }, startRow, endRow, startColumn, endColumn);
400
401 }
402
403
404 @Override
405 public void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination)
406 throws MathIllegalArgumentException, NullArgumentException {
407
408 checkSubMatrixIndex(selectedRows, selectedColumns);
409 if ((destination.length < selectedRows.length) ||
410 (destination[0].length < selectedColumns.length)) {
411 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
412 destination.length, destination[0].length,
413 selectedRows.length, selectedColumns.length);
414 }
415
416
417 for (int i = 0; i < selectedRows.length; i++) {
418 final T[] destinationI = destination[i];
419 for (int j = 0; j < selectedColumns.length; j++) {
420 destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]);
421 }
422 }
423
424 }
425
426
427 @Override
428 public void setSubMatrix(final T[][] subMatrix, final int row,
429 final int column)
430 throws MathIllegalArgumentException, NullArgumentException {
431 if (subMatrix == null) {
432 throw new NullArgumentException();
433 }
434 final int nRows = subMatrix.length;
435 if (nRows == 0) {
436 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_ROW);
437 }
438
439 final int nCols = subMatrix[0].length;
440 if (nCols == 0) {
441 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_COLUMN);
442 }
443
444 for (int r = 1; r < nRows; ++r) {
445 if (subMatrix[r].length != nCols) {
446 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
447 nCols, subMatrix[r].length);
448 }
449 }
450
451 checkRowIndex(row);
452 checkColumnIndex(column);
453 checkRowIndex(nRows + row - 1);
454 checkColumnIndex(nCols + column - 1);
455
456 for (int i = 0; i < nRows; ++i) {
457 for (int j = 0; j < nCols; ++j) {
458 setEntry(row + i, column + j, subMatrix[i][j]);
459 }
460 }
461 }
462
463
464 @Override
465 public FieldMatrix<T> getRowMatrix(final int row) throws MathIllegalArgumentException {
466 checkRowIndex(row);
467 final int nCols = getColumnDimension();
468 final FieldMatrix<T> out = createMatrix(1, nCols);
469 for (int i = 0; i < nCols; ++i) {
470 out.setEntry(0, i, getEntry(row, i));
471 }
472
473 return out;
474
475 }
476
477
478 @Override
479 public void setRowMatrix(final int row, final FieldMatrix<T> matrix)
480 throws MathIllegalArgumentException {
481 checkRowIndex(row);
482 final int nCols = getColumnDimension();
483 if ((matrix.getRowDimension() != 1) ||
484 (matrix.getColumnDimension() != nCols)) {
485 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
486 matrix.getRowDimension(), matrix.getColumnDimension(),
487 1, nCols);
488 }
489 for (int i = 0; i < nCols; ++i) {
490 setEntry(row, i, matrix.getEntry(0, i));
491 }
492
493 }
494
495
496 @Override
497 public FieldMatrix<T> getColumnMatrix(final int column)
498 throws MathIllegalArgumentException {
499
500 checkColumnIndex(column);
501 final int nRows = getRowDimension();
502 final FieldMatrix<T> out = createMatrix(nRows, 1);
503 for (int i = 0; i < nRows; ++i) {
504 out.setEntry(i, 0, getEntry(i, column));
505 }
506
507 return out;
508
509 }
510
511
512 @Override
513 public void setColumnMatrix(final int column, final FieldMatrix<T> matrix)
514 throws MathIllegalArgumentException {
515 checkColumnIndex(column);
516 final int nRows = getRowDimension();
517 if ((matrix.getRowDimension() != nRows) ||
518 (matrix.getColumnDimension() != 1)) {
519 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
520 matrix.getRowDimension(), matrix.getColumnDimension(),
521 nRows, 1);
522 }
523 for (int i = 0; i < nRows; ++i) {
524 setEntry(i, column, matrix.getEntry(i, 0));
525 }
526
527 }
528
529
530 @Override
531 public FieldVector<T> getRowVector(final int row)
532 throws MathIllegalArgumentException {
533 return new ArrayFieldVector<>(field, getRow(row), false);
534 }
535
536
537 @Override
538 public void setRowVector(final int row, final FieldVector<T> vector)
539 throws MathIllegalArgumentException {
540 checkRowIndex(row);
541 final int nCols = getColumnDimension();
542 if (vector.getDimension() != nCols) {
543 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
544 1, vector.getDimension(),
545 1, nCols);
546 }
547 for (int i = 0; i < nCols; ++i) {
548 setEntry(row, i, vector.getEntry(i));
549 }
550
551 }
552
553
554 @Override
555 public FieldVector<T> getColumnVector(final int column)
556 throws MathIllegalArgumentException {
557 return new ArrayFieldVector<>(field, getColumn(column), false);
558 }
559
560
561 @Override
562 public void setColumnVector(final int column, final FieldVector<T> vector)
563 throws MathIllegalArgumentException {
564
565 checkColumnIndex(column);
566 final int nRows = getRowDimension();
567 if (vector.getDimension() != nRows) {
568 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
569 vector.getDimension(), 1,
570 nRows, 1);
571 }
572 for (int i = 0; i < nRows; ++i) {
573 setEntry(i, column, vector.getEntry(i));
574 }
575
576 }
577
578
579 @Override
580 public T[] getRow(final int row) throws MathIllegalArgumentException {
581 checkRowIndex(row);
582 final int nCols = getColumnDimension();
583 final T[] out = MathArrays.buildArray(field, nCols);
584 for (int i = 0; i < nCols; ++i) {
585 out[i] = getEntry(row, i);
586 }
587
588 return out;
589
590 }
591
592
593 @Override
594 public void setRow(final int row, final T[] array)
595 throws MathIllegalArgumentException {
596 checkRowIndex(row);
597 final int nCols = getColumnDimension();
598 if (array.length != nCols) {
599 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
600 1, array.length, 1, nCols);
601 }
602 for (int i = 0; i < nCols; ++i) {
603 setEntry(row, i, array[i]);
604 }
605
606 }
607
608
609 @Override
610 public T[] getColumn(final int column) throws MathIllegalArgumentException {
611 checkColumnIndex(column);
612 final int nRows = getRowDimension();
613 final T[] out = MathArrays.buildArray(field, nRows);
614 for (int i = 0; i < nRows; ++i) {
615 out[i] = getEntry(i, column);
616 }
617
618 return out;
619
620 }
621
622
623 @Override
624 public void setColumn(final int column, final T[] array)
625 throws MathIllegalArgumentException {
626 checkColumnIndex(column);
627 final int nRows = getRowDimension();
628 if (array.length != nRows) {
629 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
630 array.length, 1, nRows, 1);
631 }
632 for (int i = 0; i < nRows; ++i) {
633 setEntry(i, column, array[i]);
634 }
635 }
636
637
638 @Override
639 public abstract T getEntry(int row, int column) throws MathIllegalArgumentException;
640
641
642 @Override
643 public abstract void setEntry(int row, int column, T value) throws MathIllegalArgumentException;
644
645
646 @Override
647 public abstract void addToEntry(int row, int column, T increment) throws MathIllegalArgumentException;
648
649
650 @Override
651 public abstract void multiplyEntry(int row, int column, T factor) throws MathIllegalArgumentException;
652
653
654 @Override
655 public FieldMatrix<T> transpose() {
656 final int nRows = getRowDimension();
657 final int nCols = getColumnDimension();
658 final FieldMatrix<T> out = createMatrix(nCols, nRows);
659 walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) {
660
661 @Override
662 public void visit(final int row, final int column, final T value) {
663 out.setEntry(column, row, value);
664 }
665 });
666
667 return out;
668 }
669
670
671 @Override
672 public boolean isSquare() {
673 return getColumnDimension() == getRowDimension();
674 }
675
676
677 @Override
678 public abstract int getRowDimension();
679
680
681 @Override
682 public abstract int getColumnDimension();
683
684
685 @Override
686 public T getTrace() throws MathIllegalArgumentException {
687 final int nRows = getRowDimension();
688 final int nCols = getColumnDimension();
689 if (nRows != nCols) {
690 throw new MathIllegalArgumentException(LocalizedCoreFormats.NON_SQUARE_MATRIX,
691 nRows, nCols);
692 }
693 T trace = field.getZero();
694 for (int i = 0; i < nRows; ++i) {
695 trace = trace.add(getEntry(i, i));
696 }
697 return trace;
698 }
699
700
701 @Override
702 public T[] operate(final T[] v) throws MathIllegalArgumentException {
703
704 final int nRows = getRowDimension();
705 final int nCols = getColumnDimension();
706 if (v.length != nCols) {
707 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
708 v.length, nCols);
709 }
710
711 final T[] out = MathArrays.buildArray(field, nRows);
712 for (int row = 0; row < nRows; ++row) {
713 T sum = field.getZero();
714 for (int i = 0; i < nCols; ++i) {
715 sum = sum.add(getEntry(row, i).multiply(v[i]));
716 }
717 out[row] = sum;
718 }
719
720 return out;
721 }
722
723
724 @Override
725 public FieldVector<T> operate(final FieldVector<T> v)
726 throws MathIllegalArgumentException {
727 if (v instanceof ArrayFieldVector) {
728 return new ArrayFieldVector<>(field, operate(((ArrayFieldVector<T>) v).getDataRef()), false);
729 } else {
730 final int nRows = getRowDimension();
731 final int nCols = getColumnDimension();
732 if (v.getDimension() != nCols) {
733 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
734 v.getDimension(), nCols);
735 }
736
737 final T[] out = MathArrays.buildArray(field, nRows);
738 for (int row = 0; row < nRows; ++row) {
739 T sum = field.getZero();
740 for (int i = 0; i < nCols; ++i) {
741 sum = sum.add(getEntry(row, i).multiply(v.getEntry(i)));
742 }
743 out[row] = sum;
744 }
745
746 return new ArrayFieldVector<>(field, out, false);
747 }
748 }
749
750
751 @Override
752 public T[] preMultiply(final T[] v) throws MathIllegalArgumentException {
753
754 final int nRows = getRowDimension();
755 final int nCols = getColumnDimension();
756 if (v.length != nRows) {
757 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
758 v.length, nRows);
759 }
760
761 final T[] out = MathArrays.buildArray(field, nCols);
762 for (int col = 0; col < nCols; ++col) {
763 T sum = field.getZero();
764 for (int i = 0; i < nRows; ++i) {
765 sum = sum.add(getEntry(i, col).multiply(v[i]));
766 }
767 out[col] = sum;
768 }
769
770 return out;
771 }
772
773
774 @Override
775 public FieldVector<T> preMultiply(final FieldVector<T> v)
776 throws MathIllegalArgumentException {
777 if (v instanceof ArrayFieldVector) {
778 return new ArrayFieldVector<>(field, preMultiply(((ArrayFieldVector<T>) v).getDataRef()), false);
779 } else {
780 final int nRows = getRowDimension();
781 final int nCols = getColumnDimension();
782 if (v.getDimension() != nRows) {
783 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
784 v.getDimension(), nRows);
785 }
786
787 final T[] out = MathArrays.buildArray(field, nCols);
788 for (int col = 0; col < nCols; ++col) {
789 T sum = field.getZero();
790 for (int i = 0; i < nRows; ++i) {
791 sum = sum.add(getEntry(i, col).multiply(v.getEntry(i)));
792 }
793 out[col] = sum;
794 }
795
796 return new ArrayFieldVector<>(field, out, false);
797 }
798 }
799
800
801 @Override
802 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor) {
803 final int rows = getRowDimension();
804 final int columns = getColumnDimension();
805 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
806 for (int row = 0; row < rows; ++row) {
807 for (int column = 0; column < columns; ++column) {
808 final T oldValue = getEntry(row, column);
809 final T newValue = visitor.visit(row, column, oldValue);
810 setEntry(row, column, newValue);
811 }
812 }
813 return visitor.end();
814 }
815
816
817 @Override
818 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor) {
819 final int rows = getRowDimension();
820 final int columns = getColumnDimension();
821 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
822 for (int row = 0; row < rows; ++row) {
823 for (int column = 0; column < columns; ++column) {
824 visitor.visit(row, column, getEntry(row, column));
825 }
826 }
827 return visitor.end();
828 }
829
830
831 @Override
832 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
833 final int startRow, final int endRow,
834 final int startColumn, final int endColumn)
835 throws MathIllegalArgumentException {
836 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
837 visitor.start(getRowDimension(), getColumnDimension(),
838 startRow, endRow, startColumn, endColumn);
839 for (int row = startRow; row <= endRow; ++row) {
840 for (int column = startColumn; column <= endColumn; ++column) {
841 final T oldValue = getEntry(row, column);
842 final T newValue = visitor.visit(row, column, oldValue);
843 setEntry(row, column, newValue);
844 }
845 }
846 return visitor.end();
847 }
848
849
850 @Override
851 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
852 final int startRow, final int endRow,
853 final int startColumn, final int endColumn)
854 throws MathIllegalArgumentException {
855 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
856 visitor.start(getRowDimension(), getColumnDimension(),
857 startRow, endRow, startColumn, endColumn);
858 for (int row = startRow; row <= endRow; ++row) {
859 for (int column = startColumn; column <= endColumn; ++column) {
860 visitor.visit(row, column, getEntry(row, column));
861 }
862 }
863 return visitor.end();
864 }
865
866
867 @Override
868 public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor) {
869 final int rows = getRowDimension();
870 final int columns = getColumnDimension();
871 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
872 for (int column = 0; column < columns; ++column) {
873 for (int row = 0; row < rows; ++row) {
874 final T oldValue = getEntry(row, column);
875 final T newValue = visitor.visit(row, column, oldValue);
876 setEntry(row, column, newValue);
877 }
878 }
879 return visitor.end();
880 }
881
882
883 @Override
884 public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor) {
885 final int rows = getRowDimension();
886 final int columns = getColumnDimension();
887 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
888 for (int column = 0; column < columns; ++column) {
889 for (int row = 0; row < rows; ++row) {
890 visitor.visit(row, column, getEntry(row, column));
891 }
892 }
893 return visitor.end();
894 }
895
896
897 @Override
898 public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor,
899 final int startRow, final int endRow,
900 final int startColumn, final int endColumn)
901 throws MathIllegalArgumentException {
902 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
903 visitor.start(getRowDimension(), getColumnDimension(),
904 startRow, endRow, startColumn, endColumn);
905 for (int column = startColumn; column <= endColumn; ++column) {
906 for (int row = startRow; row <= endRow; ++row) {
907 final T oldValue = getEntry(row, column);
908 final T newValue = visitor.visit(row, column, oldValue);
909 setEntry(row, column, newValue);
910 }
911 }
912 return visitor.end();
913 }
914
915
916 @Override
917 public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor,
918 final int startRow, final int endRow,
919 final int startColumn, final int endColumn)
920 throws MathIllegalArgumentException {
921 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
922 visitor.start(getRowDimension(), getColumnDimension(),
923 startRow, endRow, startColumn, endColumn);
924 for (int column = startColumn; column <= endColumn; ++column) {
925 for (int row = startRow; row <= endRow; ++row) {
926 visitor.visit(row, column, getEntry(row, column));
927 }
928 }
929 return visitor.end();
930 }
931
932
933 @Override
934 public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor) {
935 return walkInRowOrder(visitor);
936 }
937
938
939 @Override
940 public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor) {
941 return walkInRowOrder(visitor);
942 }
943
944
945 @Override
946 public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor,
947 final int startRow, final int endRow,
948 final int startColumn, final int endColumn)
949 throws MathIllegalArgumentException {
950 return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
951 }
952
953
954 @Override
955 public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor,
956 final int startRow, final int endRow,
957 final int startColumn, final int endColumn)
958 throws MathIllegalArgumentException {
959 return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
960 }
961
962
963
964
965
966 @Override
967 public String toString() {
968 final int nRows = getRowDimension();
969 final int nCols = getColumnDimension();
970 final StringBuffer res = new StringBuffer();
971 String fullClassName = getClass().getName();
972 String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
973 res.append(shortClassName).append('{');
974
975 for (int i = 0; i < nRows; ++i) {
976 if (i > 0) {
977 res.append(',');
978 }
979 res.append('{');
980 for (int j = 0; j < nCols; ++j) {
981 if (j > 0) {
982 res.append(',');
983 }
984 res.append(getEntry(i, j));
985 }
986 res.append('}');
987 }
988
989 res.append('}');
990 return res.toString();
991 }
992
993
994
995
996
997
998
999
1000
1001 @Override
1002 public boolean equals(final Object object) {
1003 if (object == this) {
1004 return true;
1005 }
1006 if (!(object instanceof FieldMatrix<?>)) {
1007 return false;
1008 }
1009 FieldMatrix<?> m = (FieldMatrix<?>) object;
1010 final int nRows = getRowDimension();
1011 final int nCols = getColumnDimension();
1012 if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) {
1013 return false;
1014 }
1015 for (int row = 0; row < nRows; ++row) {
1016 for (int col = 0; col < nCols; ++col) {
1017 if (!getEntry(row, col).equals(m.getEntry(row, col))) {
1018 return false;
1019 }
1020 }
1021 }
1022 return true;
1023 }
1024
1025
1026
1027
1028
1029
1030 @Override
1031 public int hashCode() {
1032 int ret = 322562;
1033 final int nRows = getRowDimension();
1034 final int nCols = getColumnDimension();
1035 ret = ret * 31 + nRows;
1036 ret = ret * 31 + nCols;
1037 for (int row = 0; row < nRows; ++row) {
1038 for (int col = 0; col < nCols; ++col) {
1039 ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * getEntry(row, col).hashCode();
1040 }
1041 }
1042 return ret;
1043 }
1044
1045
1046
1047
1048
1049
1050
1051 protected void checkRowIndex(final int row) throws MathIllegalArgumentException {
1052 if (row < 0 || row >= getRowDimension()) {
1053 throw new MathIllegalArgumentException(LocalizedCoreFormats.ROW_INDEX,
1054 row, 0, getRowDimension() - 1);
1055 }
1056 }
1057
1058
1059
1060
1061
1062
1063
1064 protected void checkColumnIndex(final int column)
1065 throws MathIllegalArgumentException {
1066 if (column < 0 || column >= getColumnDimension()) {
1067 throw new MathIllegalArgumentException(LocalizedCoreFormats.COLUMN_INDEX,
1068 column, 0, getColumnDimension() - 1);
1069 }
1070 }
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084 protected void checkSubMatrixIndex(final int startRow, final int endRow,
1085 final int startColumn, final int endColumn)
1086 throws MathIllegalArgumentException {
1087 checkRowIndex(startRow);
1088 checkRowIndex(endRow);
1089 if (endRow < startRow) {
1090 throw new MathIllegalArgumentException(LocalizedCoreFormats.INITIAL_ROW_AFTER_FINAL_ROW,
1091 endRow, startRow, true);
1092 }
1093
1094 checkColumnIndex(startColumn);
1095 checkColumnIndex(endColumn);
1096 if (endColumn < startColumn) {
1097 throw new MathIllegalArgumentException(LocalizedCoreFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN,
1098 endColumn, startColumn, true);
1099 }
1100 }
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112 protected void checkSubMatrixIndex(final int[] selectedRows, final int[] selectedColumns)
1113 throws MathIllegalArgumentException, NullArgumentException {
1114 if (selectedRows == null ||
1115 selectedColumns == null) {
1116 throw new NullArgumentException();
1117 }
1118 if (selectedRows.length == 0 ||
1119 selectedColumns.length == 0) {
1120 throw new MathIllegalArgumentException(LocalizedCoreFormats.NO_DATA);
1121 }
1122
1123 for (final int row : selectedRows) {
1124 checkRowIndex(row);
1125 }
1126 for (final int column : selectedColumns) {
1127 checkColumnIndex(column);
1128 }
1129 }
1130
1131
1132
1133
1134
1135
1136
1137
1138 protected void checkAdditionCompatible(final FieldMatrix<T> m)
1139 throws MathIllegalArgumentException {
1140 if ((getRowDimension() != m.getRowDimension()) ||
1141 (getColumnDimension() != m.getColumnDimension())) {
1142 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
1143 m.getRowDimension(), m.getColumnDimension(),
1144 getRowDimension(), getColumnDimension());
1145 }
1146 }
1147
1148
1149
1150
1151
1152
1153
1154
1155 protected void checkSubtractionCompatible(final FieldMatrix<T> m)
1156 throws MathIllegalArgumentException {
1157 if ((getRowDimension() != m.getRowDimension()) ||
1158 (getColumnDimension() != m.getColumnDimension())) {
1159 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
1160 m.getRowDimension(), m.getColumnDimension(),
1161 getRowDimension(), getColumnDimension());
1162 }
1163 }
1164
1165
1166
1167
1168
1169
1170
1171
1172 protected void checkMultiplicationCompatible(final FieldMatrix<T> m)
1173 throws MathIllegalArgumentException {
1174 if (getColumnDimension() != m.getRowDimension()) {
1175 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
1176 getColumnDimension(), m.getRowDimension());
1177 }
1178 }
1179 }