1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.linear;
24
25 import java.io.Serializable;
26 import org.hipparchus.exception.LocalizedCoreFormats;
27 import org.hipparchus.exception.MathIllegalArgumentException;
28 import org.hipparchus.exception.MathIllegalStateException;
29 import org.hipparchus.exception.NullArgumentException;
30 import org.hipparchus.util.FastMath;
31 import org.hipparchus.util.MathUtils;
32
33
34
35
36
37
38 public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializable {
39
40 private static final long serialVersionUID = -1067294169172445528L;
41
42
43 private double[][] data;
44
45
46
47
48 public Array2DRowRealMatrix() {
49
50 }
51
52
53
54
55
56
57
58
59
60 public Array2DRowRealMatrix(final int rowDimension,
61 final int columnDimension)
62 throws MathIllegalArgumentException {
63 super(rowDimension, columnDimension);
64 data = new double[rowDimension][columnDimension];
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public Array2DRowRealMatrix(final double[][] d)
81 throws MathIllegalArgumentException, NullArgumentException {
82 copyIn(d);
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public Array2DRowRealMatrix(final double[][] d, final boolean copyArray)
102 throws MathIllegalArgumentException,
103 NullArgumentException {
104 if (copyArray) {
105 copyIn(d);
106 } else {
107 if (d == null) {
108 throw new NullArgumentException();
109 }
110 final int nRows = d.length;
111 if (nRows == 0) {
112 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_ROW);
113 }
114 final int nCols = d[0].length;
115 if (nCols == 0) {
116 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_COLUMN);
117 }
118 for (int r = 1; r < nRows; r++) {
119 if (d[r].length != nCols) {
120 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
121 d[r].length, nCols);
122 }
123 }
124 data = d;
125 }
126 }
127
128
129
130
131
132
133
134
135 public Array2DRowRealMatrix(final double[] v) {
136 final int nRows = v.length;
137 data = new double[nRows][1];
138 for (int row = 0; row < nRows; row++) {
139 data[row][0] = v[row];
140 }
141 }
142
143
144 @Override
145 public RealMatrix createMatrix(final int rowDimension,
146 final int columnDimension)
147 throws MathIllegalArgumentException {
148 return new Array2DRowRealMatrix(rowDimension, columnDimension);
149 }
150
151
152 @Override
153 public RealMatrix copy() {
154 return new Array2DRowRealMatrix(copyOut(), false);
155 }
156
157
158
159
160
161
162
163
164
165 public Array2DRowRealMatrix add(final Array2DRowRealMatrix m)
166 throws MathIllegalArgumentException {
167
168 MatrixUtils.checkAdditionCompatible(this, m);
169
170 final int rowCount = getRowDimension();
171 final int columnCount = getColumnDimension();
172 final double[][] outData = new double[rowCount][columnCount];
173 for (int row = 0; row < rowCount; row++) {
174 final double[] dataRow = data[row];
175 final double[] mRow = m.data[row];
176 final double[] outDataRow = outData[row];
177 for (int col = 0; col < columnCount; col++) {
178 outDataRow[col] = dataRow[col] + mRow[col];
179 }
180 }
181
182 return new Array2DRowRealMatrix(outData, false);
183 }
184
185
186
187
188
189
190
191
192
193 public Array2DRowRealMatrix subtract(final Array2DRowRealMatrix m)
194 throws MathIllegalArgumentException {
195 MatrixUtils.checkSubtractionCompatible(this, m);
196
197 final int rowCount = getRowDimension();
198 final int columnCount = getColumnDimension();
199 final double[][] outData = new double[rowCount][columnCount];
200 for (int row = 0; row < rowCount; row++) {
201 final double[] dataRow = data[row];
202 final double[] mRow = m.data[row];
203 final double[] outDataRow = outData[row];
204 for (int col = 0; col < columnCount; col++) {
205 outDataRow[col] = dataRow[col] - mRow[col];
206 }
207 }
208
209 return new Array2DRowRealMatrix(outData, false);
210 }
211
212
213
214
215
216
217
218
219
220 public Array2DRowRealMatrix multiply(final Array2DRowRealMatrix m)
221 throws MathIllegalArgumentException {
222 MatrixUtils.checkMultiplicationCompatible(this, m);
223
224 final int nRows = this.getRowDimension();
225 final int nCols = m.getColumnDimension();
226 final int nSum = this.getColumnDimension();
227
228 final double[][] outData = new double[nRows][nCols];
229
230 final double[] mCol = new double[nSum];
231 final double[][] mData = m.data;
232
233
234 for (int col = 0; col < nCols; col++) {
235
236
237 for (int mRow = 0; mRow < nSum; mRow++) {
238 mCol[mRow] = mData[mRow][col];
239 }
240
241 for (int row = 0; row < nRows; row++) {
242 final double[] dataRow = data[row];
243 double sum = 0;
244 for (int i = 0; i < nSum; i++) {
245 sum += dataRow[i] * mCol[i];
246 }
247 outData[row][col] = sum;
248 }
249 }
250
251 return new Array2DRowRealMatrix(outData, false);
252 }
253
254
255
256
257
258
259
260
261
262 public RealMatrix multiplyTransposed(final Array2DRowRealMatrix m)
263 throws MathIllegalArgumentException {
264 MatrixUtils.checkSameColumnDimension(this, m);
265
266 final int nRows = this.getRowDimension();
267 final int nCols = m.getRowDimension();
268 final int nSum = this.getColumnDimension();
269
270 final RealMatrix out = MatrixUtils.createRealMatrix(nRows, nCols);
271 final double[][] mData = m.data;
272
273
274 for (int col = 0; col < nCols; col++) {
275 for (int row = 0; row < nRows; row++) {
276 final double[] dataRow = data[row];
277 final double[] mRow = mData[col];
278 double sum = 0;
279 for (int i = 0; i < nSum; i++) {
280 sum += dataRow[i] * mRow[i];
281 }
282 out.setEntry(row, col, sum);
283 }
284 }
285
286 return out;
287
288 }
289
290
291 @Override
292 public RealMatrix multiplyTransposed(final RealMatrix m) {
293 if (m instanceof Array2DRowRealMatrix) {
294 return multiplyTransposed((Array2DRowRealMatrix) m);
295 } else {
296 MatrixUtils.checkSameColumnDimension(this, m);
297
298 final int nRows = this.getRowDimension();
299 final int nCols = m.getRowDimension();
300 final int nSum = this.getColumnDimension();
301
302 final RealMatrix out = MatrixUtils.createRealMatrix(nRows, nCols);
303
304
305 for (int col = 0; col < nCols; col++) {
306 for (int row = 0; row < nRows; row++) {
307 final double[] dataRow = data[row];
308 double sum = 0;
309 for (int i = 0; i < nSum; i++) {
310 sum += dataRow[i] * m.getEntry(col, i);
311 }
312 out.setEntry(row, col, sum);
313 }
314 }
315
316 return out;
317
318 }
319 }
320
321
322
323
324
325
326
327
328
329 public RealMatrix transposeMultiply(final Array2DRowRealMatrix m)
330 throws MathIllegalArgumentException {
331 MatrixUtils.checkSameRowDimension(this, m);
332
333 final int nRows = this.getColumnDimension();
334 final int nCols = m.getColumnDimension();
335 final int nSum = this.getRowDimension();
336
337 final RealMatrix out = MatrixUtils.createRealMatrix(nRows, nCols);
338 final double[][] mData = m.data;
339
340
341 for (int k = 0; k < nSum; k++) {
342 final double[] dataK = data[k];
343 final double[] mK = mData[k];
344 for (int row = 0; row < nRows; row++) {
345 final double dataIRow = dataK[row];
346 for (int col = 0; col < nCols; col++) {
347 out.addToEntry(row, col, dataIRow * mK[col]);
348 }
349 }
350 }
351
352 return out;
353
354 }
355
356
357 @Override
358 public RealMatrix transposeMultiply(final RealMatrix m) {
359 if (m instanceof Array2DRowRealMatrix) {
360 return transposeMultiply((Array2DRowRealMatrix) m);
361 } else {
362 MatrixUtils.checkSameRowDimension(this, m);
363
364 final int nRows = this.getColumnDimension();
365 final int nCols = m.getColumnDimension();
366 final int nSum = this.getRowDimension();
367
368 final RealMatrix out = MatrixUtils.createRealMatrix(nRows, nCols);
369
370
371 for (int k = 0; k < nSum; k++) {
372 final double[] dataK = data[k];
373 for (int row = 0; row < nRows; row++) {
374 final double dataIRow = dataK[row];
375 for (int col = 0; col < nCols; col++) {
376 out.addToEntry(row, col, dataIRow * m.getEntry(k, col));
377 }
378 }
379 }
380
381 return out;
382
383 }
384 }
385
386
387 @Override
388 public double[][] getData() {
389 return copyOut();
390 }
391
392
393
394
395
396
397 public double[][] getDataRef() {
398 return data;
399 }
400
401
402 @Override
403 public void setSubMatrix(final double[][] subMatrix, final int row,
404 final int column)
405 throws MathIllegalArgumentException, NullArgumentException {
406 if (data == null) {
407 if (row > 0) {
408 throw new MathIllegalStateException(LocalizedCoreFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row);
409 }
410 if (column > 0) {
411 throw new MathIllegalStateException(LocalizedCoreFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column);
412 }
413 MathUtils.checkNotNull(subMatrix);
414 final int nRows = subMatrix.length;
415 if (nRows == 0) {
416 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_ROW);
417 }
418
419 final int nCols = subMatrix[0].length;
420 if (nCols == 0) {
421 throw new MathIllegalArgumentException(LocalizedCoreFormats.AT_LEAST_ONE_COLUMN);
422 }
423 data = new double[subMatrix.length][nCols];
424 for (int i = 0; i < data.length; ++i) {
425 if (subMatrix[i].length != nCols) {
426 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
427 subMatrix[i].length, nCols);
428 }
429 System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
430 }
431 } else {
432 super.setSubMatrix(subMatrix, row, column);
433 }
434
435 }
436
437
438 @Override
439 public double getEntry(final int row, final int column)
440 throws MathIllegalArgumentException {
441 try {
442 return data[row][column];
443 } catch (IndexOutOfBoundsException e) {
444
445 MatrixUtils.checkMatrixIndex(this, row, column);
446
447 throw e;
448 }
449 }
450
451
452 @Override
453 public void setEntry(final int row, final int column, final double value)
454 throws MathIllegalArgumentException {
455 MatrixUtils.checkMatrixIndex(this, row, column);
456 data[row][column] = value;
457 }
458
459
460 @Override
461 public void addToEntry(final int row, final int column,
462 final double increment)
463 throws MathIllegalArgumentException {
464 MatrixUtils.checkMatrixIndex(this, row, column);
465 data[row][column] += increment;
466 }
467
468
469 @Override
470 public void multiplyEntry(final int row, final int column,
471 final double factor)
472 throws MathIllegalArgumentException {
473 MatrixUtils.checkMatrixIndex(this, row, column);
474 data[row][column] *= factor;
475 }
476
477
478 @Override
479 public int getRowDimension() {
480 return (data == null) ? 0 : data.length;
481 }
482
483
484 @Override
485 public int getColumnDimension() {
486 return ((data == null) || (data[0] == null)) ? 0 : data[0].length;
487 }
488
489
490 @Override
491 public double[] operate(final double[] v)
492 throws MathIllegalArgumentException {
493 final int nRows = this.getRowDimension();
494 final int nCols = this.getColumnDimension();
495 if (v.length != nCols) {
496 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
497 v.length, nCols);
498 }
499 final double[] out = new double[nRows];
500 for (int row = 0; row < nRows; row++) {
501 final double[] dataRow = data[row];
502 double sum = 0;
503 for (int i = 0; i < nCols; i++) {
504 sum += dataRow[i] * v[i];
505 }
506 out[row] = sum;
507 }
508 return out;
509 }
510
511
512 @Override
513 public double[] preMultiply(final double[] v)
514 throws MathIllegalArgumentException {
515 final int nRows = getRowDimension();
516 final int nCols = getColumnDimension();
517 if (v.length != nRows) {
518 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
519 v.length, nRows);
520 }
521
522 final double[] out = new double[nCols];
523 for (int col = 0; col < nCols; ++col) {
524 double sum = 0;
525 for (int i = 0; i < nRows; ++i) {
526 sum += data[i][col] * v[i];
527 }
528 out[col] = sum;
529 }
530
531 return out;
532
533 }
534
535
536 @Override
537 public RealMatrix getSubMatrix(final int startRow, final int endRow,
538 final int startColumn, final int endColumn)
539 throws MathIllegalArgumentException {
540 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
541 final int rowCount = endRow - startRow + 1;
542 final int columnCount = endColumn - startColumn + 1;
543 final double[][] outData = new double[rowCount][columnCount];
544 for (int i = 0; i < rowCount; ++i) {
545 System.arraycopy(data[startRow + i], startColumn, outData[i], 0, columnCount);
546 }
547
548 Array2DRowRealMatrix subMatrix = new Array2DRowRealMatrix();
549 subMatrix.data = outData;
550 return subMatrix;
551 }
552
553
554 @Override
555 public double walkInRowOrder(final RealMatrixChangingVisitor visitor) {
556 final int rows = getRowDimension();
557 final int columns = getColumnDimension();
558 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
559 for (int i = 0; i < rows; ++i) {
560 final double[] rowI = data[i];
561 for (int j = 0; j < columns; ++j) {
562 rowI[j] = visitor.visit(i, j, rowI[j]);
563 }
564 }
565 return visitor.end();
566 }
567
568
569 @Override
570 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) {
571 final int rows = getRowDimension();
572 final int columns = getColumnDimension();
573 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
574 for (int i = 0; i < rows; ++i) {
575 final double[] rowI = data[i];
576 for (int j = 0; j < columns; ++j) {
577 visitor.visit(i, j, rowI[j]);
578 }
579 }
580 return visitor.end();
581 }
582
583
584 @Override
585 public double walkInRowOrder(final RealMatrixChangingVisitor visitor,
586 final int startRow, final int endRow,
587 final int startColumn, final int endColumn)
588 throws MathIllegalArgumentException {
589 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
590 visitor.start(getRowDimension(), getColumnDimension(),
591 startRow, endRow, startColumn, endColumn);
592 for (int i = startRow; i <= endRow; ++i) {
593 final double[] rowI = data[i];
594 for (int j = startColumn; j <= endColumn; ++j) {
595 rowI[j] = visitor.visit(i, j, rowI[j]);
596 }
597 }
598 return visitor.end();
599 }
600
601
602 @Override
603 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
604 final int startRow, final int endRow,
605 final int startColumn, final int endColumn)
606 throws MathIllegalArgumentException {
607 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
608 visitor.start(getRowDimension(), getColumnDimension(),
609 startRow, endRow, startColumn, endColumn);
610 for (int i = startRow; i <= endRow; ++i) {
611 final double[] rowI = data[i];
612 for (int j = startColumn; j <= endColumn; ++j) {
613 visitor.visit(i, j, rowI[j]);
614 }
615 }
616 return visitor.end();
617 }
618
619
620 @Override
621 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) {
622 final int rows = getRowDimension();
623 final int columns = getColumnDimension();
624 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
625 for (int j = 0; j < columns; ++j) {
626 for (int i = 0; i < rows; ++i) {
627 final double[] rowI = data[i];
628 rowI[j] = visitor.visit(i, j, rowI[j]);
629 }
630 }
631 return visitor.end();
632 }
633
634
635 @Override
636 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) {
637 final int rows = getRowDimension();
638 final int columns = getColumnDimension();
639 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
640 for (int j = 0; j < columns; ++j) {
641 for (int i = 0; i < rows; ++i) {
642 visitor.visit(i, j, data[i][j]);
643 }
644 }
645 return visitor.end();
646 }
647
648
649 @Override
650 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor,
651 final int startRow, final int endRow,
652 final int startColumn, final int endColumn)
653 throws MathIllegalArgumentException {
654 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
655 visitor.start(getRowDimension(), getColumnDimension(),
656 startRow, endRow, startColumn, endColumn);
657 for (int j = startColumn; j <= endColumn; ++j) {
658 for (int i = startRow; i <= endRow; ++i) {
659 final double[] rowI = data[i];
660 rowI[j] = visitor.visit(i, j, rowI[j]);
661 }
662 }
663 return visitor.end();
664 }
665
666
667 @Override
668 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor,
669 final int startRow, final int endRow,
670 final int startColumn, final int endColumn)
671 throws MathIllegalArgumentException {
672 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
673 visitor.start(getRowDimension(), getColumnDimension(),
674 startRow, endRow, startColumn, endColumn);
675 for (int j = startColumn; j <= endColumn; ++j) {
676 for (int i = startRow; i <= endRow; ++i) {
677 visitor.visit(i, j, data[i][j]);
678 }
679 }
680 return visitor.end();
681 }
682
683
684
685
686
687
688 private double[][] copyOut() {
689 final int nRows = this.getRowDimension();
690 final double[][] out = new double[nRows][this.getColumnDimension()];
691
692 for (int i = 0; i < nRows; i++) {
693 System.arraycopy(data[i], 0, out[i], 0, data[i].length);
694 }
695 return out;
696 }
697
698
699
700
701
702
703
704
705
706 private void copyIn(final double[][] in)
707 throws MathIllegalArgumentException, NullArgumentException {
708 setSubMatrix(in, 0, 0);
709 }
710
711
712 @Override
713 public double[] getRow(final int row) throws MathIllegalArgumentException {
714 MatrixUtils.checkRowIndex(this, row);
715 final int nCols = getColumnDimension();
716 final double[] out = new double[nCols];
717 System.arraycopy(data[row], 0, out, 0, nCols);
718 return out;
719 }
720
721
722 @Override
723 public void setRow(final int row, final double[] array)
724 throws MathIllegalArgumentException {
725 MatrixUtils.checkRowIndex(this, row);
726 final int nCols = getColumnDimension();
727 if (array.length != nCols) {
728 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH_2x2,
729 1, array.length, 1, nCols);
730 }
731 System.arraycopy(array, 0, data[row], 0, nCols);
732 }
733
734
735
736
737
738
739
740 public RealMatrix kroneckerProduct(final RealMatrix b) {
741 final int m = getRowDimension();
742 final int n = getColumnDimension();
743
744 final int p = b.getRowDimension();
745 final int q = b.getColumnDimension();
746
747 final RealMatrix kroneckerProduct = MatrixUtils.createRealMatrix(m * p, n * q);
748
749 for (int i = 0; i < m; i++) {
750 for (int j = 0; j < n; j++) {
751 kroneckerProduct.setSubMatrix(b.scalarMultiply(getEntry(i, j)) .getData(), i * p, j * q);
752 }
753 }
754
755 return kroneckerProduct;
756 }
757
758
759
760
761
762 public RealMatrix stack() {
763 final int m = getRowDimension();
764 final int n = getColumnDimension();
765
766 final RealMatrix stacked = MatrixUtils.createRealMatrix(m * n, 1);
767
768 for (int i = 0; i < m; i++) {
769 stacked.setSubMatrix(getColumnMatrix(i).getData(), i * n, 0);
770 }
771
772 return stacked;
773 }
774
775
776
777
778
779 public RealMatrix unstackSquare() {
780 final int m = getRowDimension();
781 final int n = getColumnDimension();
782 final int s = (int) FastMath.round(FastMath.sqrt(m));
783
784 if (n != 1) {
785 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH, n, 1);
786 }
787 if (s * s != m) {
788 throw new MathIllegalArgumentException(LocalizedCoreFormats.NON_SQUARE_MATRIX, s, ((double) m) / s);
789 }
790
791 final RealMatrix unstacked = MatrixUtils.createRealMatrix(s, s);
792
793 for (int i = 0; i < s; i++) {
794 unstacked.setColumnMatrix(i, getSubMatrix(i * s, i * s + s - 1, 0, 0));
795 }
796
797 return unstacked;
798 }
799
800 }