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