source: src/main/java/agents/anac/y2019/harddealer/math3/linear/AbstractFieldMatrix.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

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