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