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.io.Serializable;
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.MathIllegalStateException;
26  import org.apache.commons.math4.legacy.exception.NoDataException;
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  
44  public class Array2DRowFieldMatrix<T extends FieldElement<T>>
45      extends AbstractFieldMatrix<T>
46      implements Serializable {
47      
48      private static final long serialVersionUID = 7260756672015356458L;
49      
50      private T[][] data;
51  
52      
53  
54  
55  
56      public Array2DRowFieldMatrix(final Field<T> field) {
57          super(field);
58      }
59  
60      
61  
62  
63  
64  
65  
66  
67  
68      public Array2DRowFieldMatrix(final Field<T> field, final int rowDimension,
69                                   final int columnDimension)
70          throws NotStrictlyPositiveException {
71          super(field, rowDimension, columnDimension);
72          data = MathArrays.buildArray(field, rowDimension, columnDimension);
73      }
74  
75      
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88      public Array2DRowFieldMatrix(final T[][] d)
89          throws DimensionMismatchException, NullArgumentException,
90          NoDataException {
91          this(extractField(d), d);
92      }
93  
94      
95  
96  
97  
98  
99  
100 
101 
102 
103 
104 
105 
106 
107 
108     public Array2DRowFieldMatrix(final Field<T> field, final T[][] d)
109         throws DimensionMismatchException, NullArgumentException,
110         NoDataException {
111         super(field);
112         copyIn(d);
113     }
114 
115     
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130     public Array2DRowFieldMatrix(final T[][] d, final boolean copyArray)
131         throws DimensionMismatchException, NoDataException,
132         NullArgumentException {
133         this(extractField(d), d, copyArray);
134     }
135 
136     
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152     public Array2DRowFieldMatrix(final Field<T> field, final T[][] d, final boolean copyArray)
153         throws DimensionMismatchException, NoDataException, NullArgumentException {
154         super(field);
155         if (copyArray) {
156             copyIn(d);
157         } else {
158             NullArgumentException.check(d);
159             final int nRows = d.length;
160             if (nRows == 0) {
161                 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_ROW);
162             }
163             final int nCols = d[0].length;
164             if (nCols == 0) {
165                 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
166             }
167             for (int r = 1; r < nRows; r++) {
168                 if (d[r].length != nCols) {
169                     throw new DimensionMismatchException(nCols, d[r].length);
170                 }
171             }
172             data = d;
173         }
174     }
175 
176     
177 
178 
179 
180 
181 
182 
183 
184     public Array2DRowFieldMatrix(final T[] v) throws NoDataException {
185         this(extractField(v), v);
186     }
187 
188     
189 
190 
191 
192 
193 
194 
195 
196     public Array2DRowFieldMatrix(final Field<T> field, final T[] v) {
197         super(field);
198         final int nRows = v.length;
199         data = MathArrays.buildArray(getField(), nRows, 1);
200         for (int row = 0; row < nRows; row++) {
201             data[row][0] = v[row];
202         }
203     }
204 
205     
206     @Override
207     public FieldMatrix<T> createMatrix(final int rowDimension,
208                                        final int columnDimension)
209         throws NotStrictlyPositiveException {
210         return new Array2DRowFieldMatrix<>(getField(), rowDimension, columnDimension);
211     }
212 
213     
214     @Override
215     public FieldMatrix<T> copy() {
216         return new Array2DRowFieldMatrix<>(getField(), copyOut(), false);
217     }
218 
219     
220 
221 
222 
223 
224 
225 
226 
227     public Array2DRowFieldMatrix<T> add(final Array2DRowFieldMatrix<T> m)
228         throws MatrixDimensionMismatchException {
229         
230         checkAdd(m);
231 
232         final int rowCount    = getRowDimension();
233         final int columnCount = getColumnDimension();
234         final T[][] outData = MathArrays.buildArray(getField(), rowCount, columnCount);
235         for (int row = 0; row < rowCount; row++) {
236             final T[] dataRow    = data[row];
237             final T[] mRow       = m.data[row];
238             final T[] outDataRow = outData[row];
239             for (int col = 0; col < columnCount; col++) {
240                 outDataRow[col] = dataRow[col].add(mRow[col]);
241             }
242         }
243 
244         return new Array2DRowFieldMatrix<>(getField(), outData, false);
245     }
246 
247     
248 
249 
250 
251 
252 
253 
254 
255     public Array2DRowFieldMatrix<T> subtract(final Array2DRowFieldMatrix<T> m)
256         throws MatrixDimensionMismatchException {
257         
258         checkAdd(m);
259 
260         final int rowCount    = getRowDimension();
261         final int columnCount = getColumnDimension();
262         final T[][] outData = MathArrays.buildArray(getField(), rowCount, columnCount);
263         for (int row = 0; row < rowCount; row++) {
264             final T[] dataRow    = data[row];
265             final T[] mRow       = m.data[row];
266             final T[] outDataRow = outData[row];
267             for (int col = 0; col < columnCount; col++) {
268                 outDataRow[col] = dataRow[col].subtract(mRow[col]);
269             }
270         }
271 
272         return new Array2DRowFieldMatrix<>(getField(), outData, false);
273     }
274 
275     
276 
277 
278 
279 
280 
281 
282 
283     public Array2DRowFieldMatrix<T> multiply(final Array2DRowFieldMatrix<T> m)
284         throws DimensionMismatchException {
285         
286         checkMultiply(m);
287 
288         final int nRows = this.getRowDimension();
289         final int nCols = m.getColumnDimension();
290         final int nSum = this.getColumnDimension();
291         final T[][] outData = MathArrays.buildArray(getField(), nRows, nCols);
292         for (int row = 0; row < nRows; row++) {
293             final T[] dataRow    = data[row];
294             final T[] outDataRow = outData[row];
295             for (int col = 0; col < nCols; col++) {
296                 T sum = getField().getZero();
297                 for (int i = 0; i < nSum; i++) {
298                     sum = sum.add(dataRow[i].multiply(m.data[i][col]));
299                 }
300                 outDataRow[col] = sum;
301             }
302         }
303 
304         return new Array2DRowFieldMatrix<>(getField(), outData, false);
305     }
306 
307     
308     @Override
309     public T[][] getData() {
310         return copyOut();
311     }
312 
313     
314 
315 
316 
317 
318 
319     public T[][] getDataRef() {
320         return data;
321     }
322 
323     
324     @Override
325     public void setSubMatrix(final T[][] subMatrix, final int row,
326                              final int column)
327         throws OutOfRangeException, NullArgumentException, NoDataException,
328         DimensionMismatchException {
329         if (data == null) {
330             if (row > 0) {
331                 throw new MathIllegalStateException(LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row);
332             }
333             if (column > 0) {
334                 throw new MathIllegalStateException(LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column);
335             }
336             final int nRows = subMatrix.length;
337             if (nRows == 0) {
338                 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_ROW);
339             }
340 
341             final int nCols = subMatrix[0].length;
342             if (nCols == 0) {
343                 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
344             }
345             data = MathArrays.buildArray(getField(), subMatrix.length, nCols);
346             for (int i = 0; i < data.length; ++i) {
347                 if (subMatrix[i].length != nCols) {
348                     throw new DimensionMismatchException(nCols, subMatrix[i].length);
349                 }
350                 System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
351             }
352         } else {
353             super.setSubMatrix(subMatrix, row, column);
354         }
355     }
356 
357     
358     @Override
359     public T getEntry(final int row, final int column)
360         throws OutOfRangeException {
361         checkRowIndex(row);
362         checkColumnIndex(column);
363 
364         return data[row][column];
365     }
366 
367     
368     @Override
369     public void setEntry(final int row, final int column, final T value)
370         throws OutOfRangeException {
371         checkRowIndex(row);
372         checkColumnIndex(column);
373 
374         data[row][column] = value;
375     }
376 
377     
378     @Override
379     public void addToEntry(final int row, final int column, final T increment)
380         throws OutOfRangeException {
381         checkRowIndex(row);
382         checkColumnIndex(column);
383 
384         data[row][column] = data[row][column].add(increment);
385     }
386 
387     
388     @Override
389     public void multiplyEntry(final int row, final int column, final T factor)
390         throws OutOfRangeException {
391         checkRowIndex(row);
392         checkColumnIndex(column);
393 
394         data[row][column] = data[row][column].multiply(factor);
395     }
396 
397     
398     @Override
399     public int getRowDimension() {
400         return (data == null) ? 0 : data.length;
401     }
402 
403     
404     @Override
405     public int getColumnDimension() {
406         return (data == null || data[0] == null) ? 0 : data[0].length;
407     }
408 
409     
410     @Override
411     public T[] operate(final T[] v) throws DimensionMismatchException {
412         final int nRows = this.getRowDimension();
413         final int nCols = this.getColumnDimension();
414         if (v.length != nCols) {
415             throw new DimensionMismatchException(v.length, nCols);
416         }
417         final T[] out = MathArrays.buildArray(getField(), nRows);
418         for (int row = 0; row < nRows; row++) {
419             final T[] dataRow = data[row];
420             T sum = getField().getZero();
421             for (int i = 0; i < nCols; i++) {
422                 sum = sum.add(dataRow[i].multiply(v[i]));
423             }
424             out[row] = sum;
425         }
426         return out;
427     }
428 
429     
430     @Override
431     public T[] preMultiply(final T[] v) throws DimensionMismatchException {
432         final int nRows = getRowDimension();
433         final int nCols = getColumnDimension();
434         if (v.length != nRows) {
435             throw new DimensionMismatchException(v.length, nRows);
436         }
437 
438         final T[] out = MathArrays.buildArray(getField(), nCols);
439         for (int col = 0; col < nCols; ++col) {
440             T sum = getField().getZero();
441             for (int i = 0; i < nRows; ++i) {
442                 sum = sum.add(data[i][col].multiply(v[i]));
443             }
444             out[col] = sum;
445         }
446 
447         return out;
448     }
449 
450     
451     @Override
452     public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor) {
453         final int rows    = getRowDimension();
454         final int columns = getColumnDimension();
455         visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
456         for (int i = 0; i < rows; ++i) {
457             final T[] rowI = data[i];
458             for (int j = 0; j < columns; ++j) {
459                 rowI[j] = visitor.visit(i, j, rowI[j]);
460             }
461         }
462         return visitor.end();
463     }
464 
465     
466     @Override
467     public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor) {
468         final int rows    = getRowDimension();
469         final int columns = getColumnDimension();
470         visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
471         for (int i = 0; i < rows; ++i) {
472             final T[] rowI = data[i];
473             for (int j = 0; j < columns; ++j) {
474                 visitor.visit(i, j, rowI[j]);
475             }
476         }
477         return visitor.end();
478     }
479 
480     
481     @Override
482     public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
483                             final int startRow, final int endRow,
484                             final int startColumn, final int endColumn)
485         throws OutOfRangeException, NumberIsTooSmallException {
486         checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
487         visitor.start(getRowDimension(), getColumnDimension(),
488                       startRow, endRow, startColumn, endColumn);
489         for (int i = startRow; i <= endRow; ++i) {
490             final T[] rowI = data[i];
491             for (int j = startColumn; j <= endColumn; ++j) {
492                 rowI[j] = visitor.visit(i, j, rowI[j]);
493             }
494         }
495         return visitor.end();
496     }
497 
498     
499     @Override
500     public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
501                             final int startRow, final int endRow,
502                             final int startColumn, final int endColumn)
503         throws OutOfRangeException, NumberIsTooSmallException {
504         checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
505         visitor.start(getRowDimension(), getColumnDimension(),
506                       startRow, endRow, startColumn, endColumn);
507         for (int i = startRow; i <= endRow; ++i) {
508             final T[] rowI = data[i];
509             for (int j = startColumn; j <= endColumn; ++j) {
510                 visitor.visit(i, j, rowI[j]);
511             }
512         }
513         return visitor.end();
514     }
515 
516     
517     @Override
518     public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor) {
519         final int rows    = getRowDimension();
520         final int columns = getColumnDimension();
521         visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
522         for (int j = 0; j < columns; ++j) {
523             for (int i = 0; i < rows; ++i) {
524                 final T[] rowI = data[i];
525                 rowI[j] = visitor.visit(i, j, rowI[j]);
526             }
527         }
528         return visitor.end();
529     }
530 
531     
532     @Override
533     public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor) {
534         final int rows    = getRowDimension();
535         final int columns = getColumnDimension();
536         visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
537         for (int j = 0; j < columns; ++j) {
538             for (int i = 0; i < rows; ++i) {
539                 visitor.visit(i, j, data[i][j]);
540             }
541         }
542         return visitor.end();
543     }
544 
545     
546     @Override
547     public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor,
548                                final int startRow, final int endRow,
549                                final int startColumn, final int endColumn)
550         throws OutOfRangeException, NumberIsTooSmallException {
551     checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
552         visitor.start(getRowDimension(), getColumnDimension(),
553                       startRow, endRow, startColumn, endColumn);
554         for (int j = startColumn; j <= endColumn; ++j) {
555             for (int i = startRow; i <= endRow; ++i) {
556                 final T[] rowI = data[i];
557                 rowI[j] = visitor.visit(i, j, rowI[j]);
558             }
559         }
560         return visitor.end();
561     }
562 
563     
564     @Override
565     public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor,
566                                final int startRow, final int endRow,
567                                final int startColumn, final int endColumn)
568         throws OutOfRangeException, NumberIsTooSmallException {
569         checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
570         visitor.start(getRowDimension(), getColumnDimension(),
571                       startRow, endRow, startColumn, endColumn);
572         for (int j = startColumn; j <= endColumn; ++j) {
573             for (int i = startRow; i <= endRow; ++i) {
574                 visitor.visit(i, j, data[i][j]);
575             }
576         }
577         return visitor.end();
578     }
579 
580     
581 
582 
583 
584 
585     private T[][] copyOut() {
586         final int nRows = this.getRowDimension();
587         final T[][] out = MathArrays.buildArray(getField(), nRows, getColumnDimension());
588         
589         for (int i = 0; i < nRows; i++) {
590             System.arraycopy(data[i], 0, out[i], 0, data[i].length);
591         }
592         return out;
593     }
594 
595     
596 
597 
598 
599 
600 
601 
602 
603     private void copyIn(final T[][] in)
604         throws NullArgumentException, NoDataException,
605         DimensionMismatchException {
606         setSubMatrix(in, 0, 0);
607     }
608 }