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 import org.apache.commons.math.util.MathUtils;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class RealMatrixImpl implements RealMatrix, Serializable {
53
54
55 private static final long serialVersionUID = 4970229902484487012L;
56
57
58 protected double data[][] = null;
59
60
61
62
63 protected double lu[][] = null;
64
65
66 protected int[] permutation = null;
67
68
69 protected int parity = 1;
70
71
72 private static final double TOO_SMALL = 10E-12;
73
74
75
76
77 public RealMatrixImpl() {
78 }
79
80
81
82
83
84
85
86
87
88 public RealMatrixImpl(int rowDimension, int columnDimension) {
89 if (rowDimension <= 0 || columnDimension <= 0) {
90 throw new IllegalArgumentException(
91 "row and column dimensions must be postive");
92 }
93 data = new double[rowDimension][columnDimension];
94 lu = null;
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 public RealMatrixImpl(double[][] d) {
111 copyIn(d);
112 lu = null;
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 public RealMatrixImpl(double[][] d, boolean copyArray) {
131 if (copyArray) {
132 copyIn(d);
133 } else {
134 if (d == null) {
135 throw new NullPointerException();
136 }
137 final int nRows = d.length;
138 if (nRows == 0) {
139 throw new IllegalArgumentException("Matrix must have at least one row.");
140 }
141 final int nCols = d[0].length;
142 if (nCols == 0) {
143 throw new IllegalArgumentException("Matrix must have at least one column.");
144 }
145 for (int r = 1; r < nRows; r++) {
146 if (d[r].length != nCols) {
147 throw new IllegalArgumentException("All input rows must have the same length.");
148 }
149 }
150 data = d;
151 }
152 lu = null;
153 }
154
155
156
157
158
159
160
161
162
163 public RealMatrixImpl(double[] v) {
164 final int nRows = v.length;
165 data = new double[nRows][1];
166 for (int row = 0; row < nRows; row++) {
167 data[row][0] = v[row];
168 }
169 }
170
171
172
173
174
175
176 public RealMatrix copy() {
177 return new RealMatrixImpl(copyOut(), false);
178 }
179
180
181
182
183
184
185
186
187 public RealMatrix add(RealMatrix m) throws IllegalArgumentException {
188 try {
189 return add((RealMatrixImpl) m);
190 } catch (ClassCastException cce) {
191 final int rowCount = getRowDimension();
192 final int columnCount = getColumnDimension();
193 if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
194 throw new IllegalArgumentException("matrix dimension mismatch");
195 }
196 final double[][] outData = new double[rowCount][columnCount];
197 for (int row = 0; row < rowCount; row++) {
198 final double[] dataRow = data[row];
199 final double[] outDataRow = outData[row];
200 for (int col = 0; col < columnCount; col++) {
201 outDataRow[col] = dataRow[col] + m.getEntry(row, col);
202 }
203 }
204 return new RealMatrixImpl(outData, false);
205 }
206 }
207
208
209
210
211
212
213
214
215 public RealMatrixImpl add(RealMatrixImpl m) throws IllegalArgumentException {
216 final int rowCount = getRowDimension();
217 final int columnCount = getColumnDimension();
218 if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
219 throw new IllegalArgumentException("matrix dimension mismatch");
220 }
221 final double[][] outData = new double[rowCount][columnCount];
222 for (int row = 0; row < rowCount; row++) {
223 final double[] dataRow = data[row];
224 final double[] mRow = m.data[row];
225 final double[] outDataRow = outData[row];
226 for (int col = 0; col < columnCount; col++) {
227 outDataRow[col] = dataRow[col] + mRow[col];
228 }
229 }
230 return new RealMatrixImpl(outData, false);
231 }
232
233
234
235
236
237
238
239
240 public RealMatrix subtract(RealMatrix m) throws IllegalArgumentException {
241 try {
242 return subtract((RealMatrixImpl) m);
243 } catch (ClassCastException cce) {
244 final int rowCount = getRowDimension();
245 final int columnCount = getColumnDimension();
246 if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
247 throw new IllegalArgumentException("matrix dimension mismatch");
248 }
249 final double[][] outData = new double[rowCount][columnCount];
250 for (int row = 0; row < rowCount; row++) {
251 final double[] dataRow = data[row];
252 final double[] outDataRow = outData[row];
253 for (int col = 0; col < columnCount; col++) {
254 outDataRow[col] = dataRow[col] - m.getEntry(row, col);
255 }
256 }
257 return new RealMatrixImpl(outData, false);
258 }
259 }
260
261
262
263
264
265
266
267
268 public RealMatrixImpl subtract(RealMatrixImpl m) throws IllegalArgumentException {
269 final int rowCount = getRowDimension();
270 final int columnCount = getColumnDimension();
271 if (columnCount != m.getColumnDimension() || rowCount != m.getRowDimension()) {
272 throw new IllegalArgumentException("matrix dimension mismatch");
273 }
274 final double[][] outData = new double[rowCount][columnCount];
275 for (int row = 0; row < rowCount; row++) {
276 final double[] dataRow = data[row];
277 final double[] mRow = m.data[row];
278 final double[] outDataRow = outData[row];
279 for (int col = 0; col < columnCount; col++) {
280 outDataRow[col] = dataRow[col] - mRow[col];
281 }
282 }
283 return new RealMatrixImpl(outData, false);
284 }
285
286
287
288
289
290
291
292 public RealMatrix scalarAdd(double d) {
293 final int rowCount = getRowDimension();
294 final int columnCount = getColumnDimension();
295 final double[][] outData = new double[rowCount][columnCount];
296 for (int row = 0; row < rowCount; row++) {
297 final double[] dataRow = data[row];
298 final double[] outDataRow = outData[row];
299 for (int col = 0; col < columnCount; col++) {
300 outDataRow[col] = dataRow[col] + d;
301 }
302 }
303 return new RealMatrixImpl(outData, false);
304 }
305
306
307
308
309
310
311 public RealMatrix scalarMultiply(double d) {
312 final int rowCount = getRowDimension();
313 final int columnCount = getColumnDimension();
314 final double[][] outData = new double[rowCount][columnCount];
315 for (int row = 0; row < rowCount; row++) {
316 final double[] dataRow = data[row];
317 final double[] outDataRow = outData[row];
318 for (int col = 0; col < columnCount; col++) {
319 outDataRow[col] = dataRow[col] * d;
320 }
321 }
322 return new RealMatrixImpl(outData, false);
323 }
324
325
326
327
328
329
330
331
332 public RealMatrix multiply(RealMatrix m) throws IllegalArgumentException {
333 try {
334 return multiply((RealMatrixImpl) m);
335 } catch (ClassCastException cce) {
336 if (this.getColumnDimension() != m.getRowDimension()) {
337 throw new IllegalArgumentException("Matrices are not multiplication compatible.");
338 }
339 final int nRows = this.getRowDimension();
340 final int nCols = m.getColumnDimension();
341 final int nSum = this.getColumnDimension();
342 final double[][] outData = new double[nRows][nCols];
343 for (int row = 0; row < nRows; row++) {
344 final double[] dataRow = data[row];
345 final double[] outDataRow = outData[row];
346 for (int col = 0; col < nCols; col++) {
347 double sum = 0;
348 for (int i = 0; i < nSum; i++) {
349 sum += dataRow[i] * m.getEntry(i, col);
350 }
351 outDataRow[col] = sum;
352 }
353 }
354 return new RealMatrixImpl(outData, false);
355 }
356 }
357
358
359
360
361
362
363
364
365 public RealMatrixImpl multiply(RealMatrixImpl m) throws IllegalArgumentException {
366 if (this.getColumnDimension() != m.getRowDimension()) {
367 throw new IllegalArgumentException("Matrices are not multiplication compatible.");
368 }
369 final int nRows = this.getRowDimension();
370 final int nCols = m.getColumnDimension();
371 final int nSum = this.getColumnDimension();
372 final double[][] outData = new double[nRows][nCols];
373 for (int row = 0; row < nRows; row++) {
374 final double[] dataRow = data[row];
375 final double[] outDataRow = outData[row];
376 for (int col = 0; col < nCols; col++) {
377 double sum = 0;
378 for (int i = 0; i < nSum; i++) {
379 sum += dataRow[i] * m.data[i][col];
380 }
381 outDataRow[col] = sum;
382 }
383 }
384 return new RealMatrixImpl(outData, false);
385 }
386
387
388
389
390
391
392
393
394 public RealMatrix preMultiply(RealMatrix m) throws IllegalArgumentException {
395 return m.multiply(this);
396 }
397
398
399
400
401
402
403
404
405 public double[][] getData() {
406 return copyOut();
407 }
408
409
410
411
412
413
414
415
416 public double[][] getDataRef() {
417 return data;
418 }
419
420
421
422
423
424 public double getNorm() {
425 double maxColSum = 0;
426 for (int col = 0; col < this.getColumnDimension(); col++) {
427 double sum = 0;
428 for (int row = 0; row < this.getRowDimension(); row++) {
429 sum += Math.abs(data[row][col]);
430 }
431 maxColSum = Math.max(maxColSum, sum);
432 }
433 return maxColSum;
434 }
435
436
437
438
439
440
441
442
443
444
445
446
447
448 public RealMatrix getSubMatrix(int startRow, int endRow,
449 int startColumn, int endColumn)
450 throws MatrixIndexException {
451 if (startRow < 0 || startRow > endRow || endRow > data.length ||
452 startColumn < 0 || startColumn > endColumn ||
453 endColumn > data[0].length) {
454 throw new MatrixIndexException(
455 "invalid row or column index selection");
456 }
457 final double[][] subMatrixData =
458 new double[endRow - startRow + 1][endColumn - startColumn + 1];
459 for (int i = startRow; i <= endRow; i++) {
460 System.arraycopy(data[i], startColumn,
461 subMatrixData[i - startRow], 0,
462 endColumn - startColumn + 1);
463 }
464 return new RealMatrixImpl(subMatrixData, false);
465 }
466
467
468
469
470
471
472
473
474
475
476
477
478 public RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
479 throws MatrixIndexException {
480 if (selectedRows.length * selectedColumns.length == 0) {
481 throw new MatrixIndexException(
482 "selected row and column index arrays must be non-empty");
483 }
484 final double[][] subMatrixData =
485 new double[selectedRows.length][selectedColumns.length];
486 try {
487 for (int i = 0; i < selectedRows.length; i++) {
488 final double[] subI = subMatrixData[i];
489 final double[] dataSelectedI = data[selectedRows[i]];
490 for (int j = 0; j < selectedColumns.length; j++) {
491 subI[j] = dataSelectedI[selectedColumns[j]];
492 }
493 }
494 } catch (ArrayIndexOutOfBoundsException e) {
495 throw new MatrixIndexException("matrix dimension mismatch");
496 }
497 return new RealMatrixImpl(subMatrixData, false);
498 }
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527 public void setSubMatrix(double[][] subMatrix, int row, int column)
528 throws MatrixIndexException {
529 if ((row < 0) || (column < 0)){
530 throw new MatrixIndexException
531 ("invalid row or column index selection");
532 }
533 final int nRows = subMatrix.length;
534 if (nRows == 0) {
535 throw new IllegalArgumentException(
536 "Matrix must have at least one row.");
537 }
538 final int nCols = subMatrix[0].length;
539 if (nCols == 0) {
540 throw new IllegalArgumentException(
541 "Matrix must have at least one column.");
542 }
543 for (int r = 1; r < nRows; r++) {
544 if (subMatrix[r].length != nCols) {
545 throw new IllegalArgumentException(
546 "All input rows must have the same length.");
547 }
548 }
549 if (data == null) {
550 if ((row > 0)||(column > 0)) throw new MatrixIndexException
551 ("matrix must be initialized to perfom this method");
552 data = new double[nRows][nCols];
553 System.arraycopy(subMatrix, 0, data, 0, subMatrix.length);
554 }
555 if (((nRows + row) > this.getRowDimension()) ||
556 (nCols + column > this.getColumnDimension()))
557 throw new MatrixIndexException(
558 "invalid row or column index selection");
559 for (int i = 0; i < nRows; i++) {
560 System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols);
561 }
562 lu = null;
563 }
564
565
566
567
568
569
570
571
572
573 public RealMatrix getRowMatrix(int row) throws MatrixIndexException {
574 if ( !isValidCoordinate( row, 0)) {
575 throw new MatrixIndexException("illegal row argument");
576 }
577 final int ncols = this.getColumnDimension();
578 final double[][] out = new double[1][ncols];
579 System.arraycopy(data[row], 0, out[0], 0, ncols);
580 return new RealMatrixImpl(out, false);
581 }
582
583
584
585
586
587
588
589
590
591 public RealMatrix getColumnMatrix(int column) throws MatrixIndexException {
592 if ( !isValidCoordinate( 0, column)) {
593 throw new MatrixIndexException("illegal column argument");
594 }
595 final int nRows = this.getRowDimension();
596 final double[][] out = new double[nRows][1];
597 for (int row = 0; row < nRows; row++) {
598 out[row][0] = data[row][column];
599 }
600 return new RealMatrixImpl(out, false);
601 }
602
603
604 public RealVector getColumnVector(int column) throws MatrixIndexException {
605 return new RealVectorImpl(getColumn(column), false);
606 }
607
608
609 public RealVector getRowVector(int row) throws MatrixIndexException {
610 return new RealVectorImpl(getRow(row), false);
611 }
612
613
614
615
616
617
618
619
620
621
622
623 public double[] getRow(int row) throws MatrixIndexException {
624 if ( !isValidCoordinate( row, 0 ) ) {
625 throw new MatrixIndexException("illegal row argument");
626 }
627 final int ncols = this.getColumnDimension();
628 final double[] out = new double[ncols];
629 System.arraycopy(data[row], 0, out, 0, ncols);
630 return out;
631 }
632
633
634
635
636
637
638
639
640
641
642
643 public double[] getColumn(int col) throws MatrixIndexException {
644 if ( !isValidCoordinate(0, col) ) {
645 throw new MatrixIndexException("illegal column argument");
646 }
647 final int nRows = this.getRowDimension();
648 final double[] out = new double[nRows];
649 for (int row = 0; row < nRows; row++) {
650 out[row] = data[row][col];
651 }
652 return out;
653 }
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670 public double getEntry(int row, int column)
671 throws MatrixIndexException {
672 try {
673 return data[row][column];
674 } catch (ArrayIndexOutOfBoundsException e) {
675 throw new MatrixIndexException("matrix entry does not exist");
676 }
677 }
678
679
680
681
682
683
684 public RealMatrix transpose() {
685 final int nRows = getRowDimension();
686 final int nCols = getColumnDimension();
687 final double[][] outData = new double[nCols][nRows];
688 for (int row = 0; row < nRows; row++) {
689 final double[] dataRow = data[row];
690 for (int col = 0; col < nCols; col++) {
691 outData[col][row] = dataRow[col];
692 }
693 }
694 return new RealMatrixImpl(outData, false);
695 }
696
697
698
699
700
701
702
703 public RealMatrix inverse() throws InvalidMatrixException {
704 return solve(MatrixUtils.createRealIdentityMatrix(getRowDimension()));
705 }
706
707
708
709
710
711 public double getDeterminant() throws InvalidMatrixException {
712 if (!isSquare()) {
713 throw new InvalidMatrixException("matrix is not square");
714 }
715 if (isSingular()) {
716 return 0d;
717 } else {
718 double det = parity;
719 for (int i = 0; i < this.getRowDimension(); i++) {
720 det *= lu[i][i];
721 }
722 return det;
723 }
724 }
725
726
727
728
729 public boolean isSquare() {
730 return (this.getColumnDimension() == this.getRowDimension());
731 }
732
733
734
735
736 public boolean isSingular() {
737 if (lu == null) {
738 try {
739 luDecompose();
740 return false;
741 } catch (InvalidMatrixException ex) {
742 return true;
743 }
744 } else {
745 return false;
746 }
747 }
748
749
750
751
752 public int getRowDimension() {
753 return data.length;
754 }
755
756
757
758
759 public int getColumnDimension() {
760 return data[0].length;
761 }
762
763
764
765
766
767 public double getTrace() throws IllegalArgumentException {
768 if (!isSquare()) {
769 throw new IllegalArgumentException("matrix is not square");
770 }
771 double trace = data[0][0];
772 for (int i = 1; i < this.getRowDimension(); i++) {
773 trace += data[i][i];
774 }
775 return trace;
776 }
777
778
779
780
781
782
783 public double[] operate(double[] v) throws IllegalArgumentException {
784 final int nRows = this.getRowDimension();
785 final int nCols = this.getColumnDimension();
786 if (v.length != nCols) {
787 throw new IllegalArgumentException("vector has wrong length");
788 }
789 final double[] out = new double[nRows];
790 for (int row = 0; row < nRows; row++) {
791 final double[] dataRow = data[row];
792 double sum = 0;
793 for (int i = 0; i < nCols; i++) {
794 sum += dataRow[i] * v[i];
795 }
796 out[row] = sum;
797 }
798 return out;
799 }
800
801
802 public RealVector operate(RealVector v) throws IllegalArgumentException {
803 try {
804 return operate((RealVectorImpl) v);
805 } catch (ClassCastException cce) {
806 final int nRows = this.getRowDimension();
807 final int nCols = this.getColumnDimension();
808 if (v.getDimension() != nCols) {
809 throw new IllegalArgumentException("vector has wrong length");
810 }
811 final double[] out = new double[nRows];
812 for (int row = 0; row < nRows; row++) {
813 final double[] dataRow = data[row];
814 double sum = 0;
815 for (int i = 0; i < nCols; i++) {
816 sum += dataRow[i] * v.getEntry(i);
817 }
818 out[row] = sum;
819 }
820 return new RealVectorImpl(out, false);
821 }
822 }
823
824
825
826
827
828
829
830
831 public RealVectorImpl operate(RealVectorImpl v) throws IllegalArgumentException {
832 return new RealVectorImpl(operate(v.getDataRef()), false);
833 }
834
835
836
837
838
839
840 public double[] preMultiply(double[] v) throws IllegalArgumentException {
841 final int nRows = this.getRowDimension();
842 if (v.length != nRows) {
843 throw new IllegalArgumentException("vector has wrong length");
844 }
845 final int nCols = this.getColumnDimension();
846 final double[] out = new double[nCols];
847 for (int col = 0; col < nCols; col++) {
848 double sum = 0;
849 for (int i = 0; i < nRows; i++) {
850 sum += data[i][col] * v[i];
851 }
852 out[col] = sum;
853 }
854 return out;
855 }
856
857
858 public RealVector preMultiply(RealVector v) throws IllegalArgumentException {
859 try {
860 return preMultiply((RealVectorImpl) v);
861 } catch (ClassCastException cce) {
862 final int nRows = this.getRowDimension();
863 if (v.getDimension() != nRows) {
864 throw new IllegalArgumentException("vector has wrong length");
865 }
866 final int nCols = this.getColumnDimension();
867 final double[] out = new double[nCols];
868 for (int col = 0; col < nCols; col++) {
869 double sum = 0;
870 for (int i = 0; i < nRows; i++) {
871 sum += data[i][col] * v.getEntry(i);
872 }
873 out[col] = sum;
874 }
875 return new RealVectorImpl(out, false);
876 }
877 }
878
879
880
881
882
883
884
885
886 RealVectorImpl preMultiply(RealVectorImpl v) throws IllegalArgumentException {
887 return new RealVectorImpl(preMultiply(v.getDataRef()), false);
888 }
889
890
891
892
893
894
895
896
897
898
899
900
901 public double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException {
902
903 final int nRows = this.getRowDimension();
904 final int nCol = this.getColumnDimension();
905
906 if (b.length != nRows) {
907 throw new IllegalArgumentException("constant vector has wrong length");
908 }
909 if (!isSquare()) {
910 throw new InvalidMatrixException("coefficient matrix is not square");
911 }
912 if (isSingular()) {
913 throw new InvalidMatrixException("Matrix is singular.");
914 }
915
916 final double[] bp = new double[nRows];
917
918
919 for (int row = 0; row < nRows; row++) {
920 bp[row] = b[permutation[row]];
921 }
922
923
924 for (int col = 0; col < nCol; col++) {
925 for (int i = col + 1; i < nCol; i++) {
926 bp[i] -= bp[col] * lu[i][col];
927 }
928 }
929
930
931 for (int col = nCol - 1; col >= 0; col--) {
932 bp[col] /= lu[col][col];
933 for (int i = 0; i < col; i++) {
934 bp[i] -= bp[col] * lu[i][col];
935 }
936 }
937
938 return bp;
939
940 }
941
942
943 public RealVector solve(RealVector b)
944 throws IllegalArgumentException, InvalidMatrixException {
945 try {
946 return solve((RealVectorImpl) b);
947 } catch (ClassCastException cce) {
948
949 final int nRows = this.getRowDimension();
950 final int nCol = this.getColumnDimension();
951
952 if (b.getDimension() != nRows) {
953 throw new IllegalArgumentException("constant vector has wrong length");
954 }
955 if (!isSquare()) {
956 throw new InvalidMatrixException("coefficient matrix is not square");
957 }
958 if (isSingular()) {
959 throw new InvalidMatrixException("Matrix is singular.");
960 }
961
962 final double[] bp = new double[nRows];
963
964
965 for (int row = 0; row < nRows; row++) {
966 bp[row] = b.getEntry(permutation[row]);
967 }
968
969
970 for (int col = 0; col < nCol; col++) {
971 for (int i = col + 1; i < nCol; i++) {
972 bp[i] -= bp[col] * lu[i][col];
973 }
974 }
975
976
977 for (int col = nCol - 1; col >= 0; col--) {
978 bp[col] /= lu[col][col];
979 for (int i = 0; i < col; i++) {
980 bp[i] -= bp[col] * lu[i][col];
981 }
982 }
983
984 return new RealVectorImpl(bp, false);
985
986 }
987 }
988
989
990
991
992
993
994
995
996
997
998 RealVectorImpl solve(RealVectorImpl b)
999 throws IllegalArgumentException, InvalidMatrixException {
1000 return new RealVectorImpl(solve(b.getDataRef()), false);
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014 public RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException {
1015 if (b.getRowDimension() != this.getRowDimension()) {
1016 throw new IllegalArgumentException("Incorrect row dimension");
1017 }
1018 if (!this.isSquare()) {
1019 throw new InvalidMatrixException("coefficient matrix is not square");
1020 }
1021 if (this.isSingular()) {
1022 throw new InvalidMatrixException("Matrix is singular.");
1023 }
1024
1025 final int nCol = this.getColumnDimension();
1026 final int nColB = b.getColumnDimension();
1027 final int nRowB = b.getRowDimension();
1028
1029
1030 final double[][] bp = new double[nRowB][nColB];
1031 for (int row = 0; row < nRowB; row++) {
1032 final double[] bpRow = bp[row];
1033 final int pRow = permutation[row];
1034 for (int col = 0; col < nColB; col++) {
1035 bpRow[col] = b.getEntry(pRow, col);
1036 }
1037 }
1038
1039
1040 for (int col = 0; col < nCol; col++) {
1041 final double[] bpCol = bp[col];
1042 for (int i = col + 1; i < nCol; i++) {
1043 final double[] bpI = bp[i];
1044 final double luICol = lu[i][col];
1045 for (int j = 0; j < nColB; j++) {
1046 bpI[j] -= bpCol[j] * luICol;
1047 }
1048 }
1049 }
1050
1051
1052 for (int col = nCol - 1; col >= 0; col--) {
1053 final double[] bpCol = bp[col];
1054 final double luDiag = lu[col][col];
1055 for (int j = 0; j < nColB; j++) {
1056 bpCol[j] /= luDiag;
1057 }
1058 for (int i = 0; i < col; i++) {
1059 final double[] bpI = bp[i];
1060 final double luICol = lu[i][col];
1061 for (int j = 0; j < nColB; j++) {
1062 bpI[j] -= bpCol[j] * luICol;
1063 }
1064 }
1065 }
1066
1067 return new RealMatrixImpl(bp, false);
1068
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083