View Javadoc
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  package org.apache.commons.math4.legacy.linear;
18  
19  import org.junit.Test;
20  import org.junit.Assert;
21  import org.apache.commons.math4.legacy.TestUtils;
22  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
23  import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
24  import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
25  import org.apache.commons.math4.legacy.exception.NoDataException;
26  import org.apache.commons.math4.legacy.exception.NullArgumentException;
27  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
28  import org.apache.commons.math4.legacy.exception.OutOfRangeException;
29  import org.apache.commons.math4.core.jdkmath.JdkMath;
30  
31  /**
32   * Test cases for the {@link Array2DRowRealMatrix} class.
33   *
34   */
35  
36  public final class Array2DRowRealMatrixTest {
37  
38      // 3 x 3 identity matrix
39      protected double[][] id = { {1d,0d,0d}, {0d,1d,0d}, {0d,0d,1d} };
40  
41      // Test data for group operations
42      protected double[][] testData = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} };
43      protected double[][] testDataLU = {{2d, 5d, 3d}, {.5d, -2.5d, 6.5d}, {0.5d, 0.2d, .2d}};
44      protected double[][] testDataPlus2 = { {3d,4d,5d}, {4d,7d,5d}, {3d,2d,10d} };
45      protected double[][] testDataMinus = { {-1d,-2d,-3d}, {-2d,-5d,-3d},
46         {-1d,0d,-8d} };
47      protected double[] testDataRow1 = {1d,2d,3d};
48      protected double[] testDataCol3 = {3d,3d,8d};
49      protected double[][] testDataInv =
50          { {-40d,16d,9d}, {13d,-5d,-3d}, {5d,-2d,-1d} };
51      protected double[] preMultTest = {8,12,33};
52      protected double[][] testData2 ={ {1d,2d,3d}, {2d,5d,3d}};
53      protected double[][] testData2T = { {1d,2d}, {2d,5d}, {3d,3d}};
54      protected double[][] testDataPlusInv =
55          { {-39d,18d,12d}, {15d,0d,0d}, {6d,-2d,7d} };
56  
57      // lu decomposition tests
58      protected double[][] luData = { {2d,3d,3d}, {0d,5d,7d}, {6d,9d,8d} };
59      protected double[][] luDataLUDecomposition = { {6d,9d,8d}, {0d,5d,7d},
60              {0.33333333333333,0d,0.33333333333333} };
61  
62      // singular matrices
63      protected double[][] singular = { {2d,3d}, {2d,3d} };
64      protected double[][] bigSingular = {{1d,2d,3d,4d}, {2d,5d,3d,4d},
65          {7d,3d,256d,1930d}, {3d,7d,6d,8d}}; // 4th row = 1st + 2nd
66      protected double[][] detData = { {1d,2d,3d}, {4d,5d,6d}, {7d,8d,10d} };
67      protected double[][] detData2 = { {1d, 3d}, {2d, 4d}};
68  
69      // vectors
70      protected double[] testVector = {1,2,3};
71      protected double[] testVector2 = {1,2,3,4};
72  
73      // submatrix accessor tests
74      protected double[][] subTestData = {{1, 2, 3, 4}, {1.5, 2.5, 3.5, 4.5},
75              {2, 4, 6, 8}, {4, 5, 6, 7}};
76      // array selections
77      protected double[][] subRows02Cols13 = { {2, 4}, {4, 8}};
78      protected double[][] subRows03Cols12 = { {2, 3}, {5, 6}};
79      protected double[][] subRows03Cols123 = { {2, 3, 4} , {5, 6, 7}};
80      // effective permutations
81      protected double[][] subRows20Cols123 = { {4, 6, 8} , {2, 3, 4}};
82      protected double[][] subRows31Cols31 = {{7, 5}, {4.5, 2.5}};
83      // contiguous ranges
84      protected double[][] subRows01Cols23 = {{3,4} , {3.5, 4.5}};
85      protected double[][] subRows23Cols00 = {{2} , {4}};
86      protected double[][] subRows00Cols33 = {{4}};
87      // row matrices
88      protected double[][] subRow0 = {{1,2,3,4}};
89      protected double[][] subRow3 = {{4,5,6,7}};
90      // column matrices
91      protected double[][] subColumn1 = {{2}, {2.5}, {4}, {5}};
92      protected double[][] subColumn3 = {{4}, {4.5}, {8}, {7}};
93  
94      // tolerances
95      protected double entryTolerance = 10E-16;
96      protected double normTolerance = 10E-14;
97      protected double powerTolerance = 10E-16;
98  
99      /** test dimensions */
100     @Test
101     public void testDimensions() {
102         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
103         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2);
104         Assert.assertEquals("testData row dimension",3,m.getRowDimension());
105         Assert.assertEquals("testData column dimension",3,m.getColumnDimension());
106         Assert.assertTrue("testData is square",m.isSquare());
107         Assert.assertEquals("testData2 row dimension",m2.getRowDimension(),2);
108         Assert.assertEquals("testData2 column dimension",m2.getColumnDimension(),3);
109         Assert.assertFalse("testData2 is not square", m2.isSquare());
110     }
111 
112     /** test copy functions */
113     @Test
114     public void testCopyFunctions() {
115         Array2DRowRealMatrix m1 = new Array2DRowRealMatrix(testData);
116         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(m1.getData());
117         Assert.assertEquals(m2,m1);
118         Array2DRowRealMatrix m3 = new Array2DRowRealMatrix(testData);
119         Array2DRowRealMatrix m4 = new Array2DRowRealMatrix(m3.getData(), false);
120         Assert.assertEquals(m4,m3);
121     }
122 
123     /** test add */
124     @Test
125     public void testAdd() {
126         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
127         Array2DRowRealMatrix mInv = new Array2DRowRealMatrix(testDataInv);
128         RealMatrix mPlusMInv = m.add(mInv);
129         double[][] sumEntries = mPlusMInv.getData();
130         for (int row = 0; row < m.getRowDimension(); row++) {
131             for (int col = 0; col < m.getColumnDimension(); col++) {
132                 Assert.assertEquals("sum entry entry",
133                     testDataPlusInv[row][col],sumEntries[row][col],
134                         entryTolerance);
135             }
136         }
137     }
138 
139     /** test add failure */
140     @Test
141     public void testAddFail() {
142         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
143         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2);
144         try {
145             m.add(m2);
146             Assert.fail("MathIllegalArgumentException expected");
147         } catch (MathIllegalArgumentException ex) {
148             // ignored
149         }
150     }
151 
152     /** test norm */
153     @Test
154     public void testNorm() {
155         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
156         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2);
157         Assert.assertEquals("testData norm",14d,m.getNorm(),entryTolerance);
158         Assert.assertEquals("testData2 norm",7d,m2.getNorm(),entryTolerance);
159     }
160 
161     /** test Frobenius norm */
162     @Test
163     public void testFrobeniusNorm() {
164         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
165         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2);
166         Assert.assertEquals("testData Frobenius norm", JdkMath.sqrt(117.0), m.getFrobeniusNorm(), entryTolerance);
167         Assert.assertEquals("testData2 Frobenius norm", JdkMath.sqrt(52.0), m2.getFrobeniusNorm(), entryTolerance);
168     }
169 
170      /** test m-n = m + -n */
171     @Test
172     public void testPlusMinus() {
173         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
174         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testDataInv);
175         TestUtils.assertEquals("m-n = m + -n",m.subtract(m2),
176             m2.scalarMultiply(-1d).add(m),entryTolerance);
177         try {
178             m.subtract(new Array2DRowRealMatrix(testData2));
179             Assert.fail("Expecting illegalArgumentException");
180         } catch (MathIllegalArgumentException ex) {
181             // ignored
182         }
183     }
184 
185     /** test multiply */
186     @Test
187     public void testMultiply() {
188         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
189         Array2DRowRealMatrix mInv = new Array2DRowRealMatrix(testDataInv);
190         Array2DRowRealMatrix identity = new Array2DRowRealMatrix(id);
191         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix(testData2);
192         TestUtils.assertEquals("inverse multiply",m.multiply(mInv),
193             identity,entryTolerance);
194         TestUtils.assertEquals("inverse multiply",mInv.multiply(m),
195             identity,entryTolerance);
196         TestUtils.assertEquals("identity multiply",m.multiply(identity),
197             m,entryTolerance);
198         TestUtils.assertEquals("identity multiply",identity.multiply(mInv),
199             mInv,entryTolerance);
200         TestUtils.assertEquals("identity multiply",m2.multiply(identity),
201             m2,entryTolerance);
202         try {
203             m.multiply(new Array2DRowRealMatrix(bigSingular));
204             Assert.fail("Expecting illegalArgumentException");
205         } catch (MathIllegalArgumentException ex) {
206             // ignored
207         }
208     }
209 
210     //Additional Test for Array2DRowRealMatrixTest.testMultiply
211 
212     private final double[][] d3 = new double[][] {{1,2,3,4},{5,6,7,8}};
213     private final double[][] d4 = new double[][] {{1},{2},{3},{4}};
214     private final double[][] d5 = new double[][] {{30},{70}};
215 
216     @Test
217     public void testMultiply2() {
218        RealMatrix m3 = new Array2DRowRealMatrix(d3);
219        RealMatrix m4 = new Array2DRowRealMatrix(d4);
220        RealMatrix m5 = new Array2DRowRealMatrix(d5);
221        TestUtils.assertEquals("m3*m4=m5", m3.multiply(m4), m5, entryTolerance);
222    }
223 
224     @Test
225     public void testPower() {
226         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
227         Array2DRowRealMatrix mInv = new Array2DRowRealMatrix(testDataInv);
228         Array2DRowRealMatrix mPlusInv = new Array2DRowRealMatrix(testDataPlusInv);
229         Array2DRowRealMatrix identity = new Array2DRowRealMatrix(id);
230 
231         TestUtils.assertEquals("m^0", m.power(0),
232             identity, entryTolerance);
233         TestUtils.assertEquals("mInv^0", mInv.power(0),
234                 identity, entryTolerance);
235         TestUtils.assertEquals("mPlusInv^0", mPlusInv.power(0),
236                 identity, entryTolerance);
237 
238         TestUtils.assertEquals("m^1", m.power(1),
239                 m, entryTolerance);
240         TestUtils.assertEquals("mInv^1", mInv.power(1),
241                 mInv, entryTolerance);
242         TestUtils.assertEquals("mPlusInv^1", mPlusInv.power(1),
243                 mPlusInv, entryTolerance);
244 
245         RealMatrix C1 = m.copy();
246         RealMatrix C2 = mInv.copy();
247         RealMatrix C3 = mPlusInv.copy();
248 
249         for (int i = 2; i <= 10; ++i) {
250             C1 = C1.multiply(m);
251             C2 = C2.multiply(mInv);
252             C3 = C3.multiply(mPlusInv);
253 
254             TestUtils.assertEquals("m^" + i, m.power(i),
255                     C1, entryTolerance);
256             TestUtils.assertEquals("mInv^" + i, mInv.power(i),
257                     C2, entryTolerance);
258             TestUtils.assertEquals("mPlusInv^" + i, mPlusInv.power(i),
259                     C3, entryTolerance);
260         }
261 
262         try {
263             Array2DRowRealMatrix mNotSquare = new Array2DRowRealMatrix(testData2T);
264             mNotSquare.power(2);
265             Assert.fail("Expecting NonSquareMatrixException");
266         } catch (NonSquareMatrixException ex) {
267             // ignored
268         }
269 
270         try {
271             m.power(-1);
272             Assert.fail("Expecting MathIllegalArgumentException");
273         } catch (MathIllegalArgumentException ex) {
274             // ignored
275         }
276     }
277 
278     /** test trace */
279     @Test
280     public void testTrace() {
281         RealMatrix m = new Array2DRowRealMatrix(id);
282         Assert.assertEquals("identity trace",3d,m.getTrace(),entryTolerance);
283         m = new Array2DRowRealMatrix(testData2);
284         try {
285             m.getTrace();
286             Assert.fail("Expecting NonSquareMatrixException");
287         } catch (NonSquareMatrixException ex) {
288             // ignored
289         }
290     }
291 
292     /** test scalarAdd */
293     @Test
294     public void testScalarAdd() {
295         RealMatrix m = new Array2DRowRealMatrix(testData);
296         TestUtils.assertEquals("scalar add",new Array2DRowRealMatrix(testDataPlus2),
297             m.scalarAdd(2d),entryTolerance);
298     }
299 
300     /** test operate */
301     @Test
302     public void testOperate() {
303         RealMatrix m = new Array2DRowRealMatrix(id);
304         TestUtils.assertEquals("identity operate", testVector,
305                     m.operate(testVector), entryTolerance);
306         TestUtils.assertEquals("identity operate", testVector,
307                     m.operate(new ArrayRealVector(testVector)).toArray(), entryTolerance);
308         m = new Array2DRowRealMatrix(bigSingular);
309         try {
310             m.operate(testVector);
311             Assert.fail("Expecting illegalArgumentException");
312         } catch (MathIllegalArgumentException ex) {
313             // ignored
314         }
315     }
316 
317     /** test issue MATH-209 */
318     @Test
319     public void testMath209() {
320         RealMatrix a = new Array2DRowRealMatrix(new double[][] {
321                 { 1, 2 }, { 3, 4 }, { 5, 6 }
322         }, false);
323         double[] b = a.operate(new double[] { 1, 1 });
324         Assert.assertEquals(a.getRowDimension(), b.length);
325         Assert.assertEquals( 3.0, b[0], 1.0e-12);
326         Assert.assertEquals( 7.0, b[1], 1.0e-12);
327         Assert.assertEquals(11.0, b[2], 1.0e-12);
328     }
329 
330     /** test transpose */
331     @Test
332     public void testTranspose() {
333         RealMatrix m = new Array2DRowRealMatrix(testData);
334         RealMatrix mIT = new LUDecomposition(m).getSolver().getInverse().transpose();
335         RealMatrix mTI = new LUDecomposition(m.transpose()).getSolver().getInverse();
336         TestUtils.assertEquals("inverse-transpose", mIT, mTI, normTolerance);
337         m = new Array2DRowRealMatrix(testData2);
338         RealMatrix mt = new Array2DRowRealMatrix(testData2T);
339         TestUtils.assertEquals("transpose",mt,m.transpose(),normTolerance);
340     }
341 
342     /** test preMultiply by vector */
343     @Test
344     public void testPremultiplyVector() {
345         RealMatrix m = new Array2DRowRealMatrix(testData);
346         TestUtils.assertEquals("premultiply", m.preMultiply(testVector),
347                     preMultTest, normTolerance);
348         TestUtils.assertEquals("premultiply", m.preMultiply(new ArrayRealVector(testVector).toArray()),
349                     preMultTest, normTolerance);
350         m = new Array2DRowRealMatrix(bigSingular);
351         try {
352             m.preMultiply(testVector);
353             Assert.fail("expecting MathIllegalArgumentException");
354         } catch (MathIllegalArgumentException ex) {
355             // ignored
356         }
357     }
358 
359     @Test
360     public void testPremultiply() {
361         RealMatrix m3 = new Array2DRowRealMatrix(d3);
362         RealMatrix m4 = new Array2DRowRealMatrix(d4);
363         RealMatrix m5 = new Array2DRowRealMatrix(d5);
364         TestUtils.assertEquals("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance);
365 
366         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
367         Array2DRowRealMatrix mInv = new Array2DRowRealMatrix(testDataInv);
368         Array2DRowRealMatrix identity = new Array2DRowRealMatrix(id);
369         TestUtils.assertEquals("inverse multiply",m.preMultiply(mInv),
370                 identity,entryTolerance);
371         TestUtils.assertEquals("inverse multiply",mInv.preMultiply(m),
372                 identity,entryTolerance);
373         TestUtils.assertEquals("identity multiply",m.preMultiply(identity),
374                 m,entryTolerance);
375         TestUtils.assertEquals("identity multiply",identity.preMultiply(mInv),
376                 mInv,entryTolerance);
377         try {
378             m.preMultiply(new Array2DRowRealMatrix(bigSingular));
379             Assert.fail("Expecting illegalArgumentException");
380         } catch (MathIllegalArgumentException ex) {
381             // ignored
382         }
383     }
384 
385     @Test
386     public void testGetVectors() {
387         RealMatrix m = new Array2DRowRealMatrix(testData);
388         TestUtils.assertEquals("get row",m.getRow(0),testDataRow1,entryTolerance);
389         TestUtils.assertEquals("get col",m.getColumn(2),testDataCol3,entryTolerance);
390         try {
391             m.getRow(10);
392             Assert.fail("expecting OutOfRangeException");
393         } catch (OutOfRangeException ex) {
394             // ignored
395         }
396         try {
397             m.getColumn(-1);
398             Assert.fail("expecting OutOfRangeException");
399         } catch (OutOfRangeException ex) {
400             // ignored
401         }
402     }
403 
404     @Test
405     public void testGetEntry() {
406         RealMatrix m = new Array2DRowRealMatrix(testData);
407         Assert.assertEquals("get entry",m.getEntry(0,1),2d,entryTolerance);
408         try {
409             m.getEntry(10, 4);
410             Assert.fail("Expecting OutOfRangeException");
411         } catch (OutOfRangeException ex) {
412             // expected
413         }
414     }
415 
416     /** test examples in user guide */
417     @Test
418     public void testExamples() {
419         // Create a real matrix with two rows and three columns
420         double[][] matrixData = { {1d,2d,3d}, {2d,5d,3d}};
421         RealMatrix m = new Array2DRowRealMatrix(matrixData);
422         // One more with three rows, two columns
423         double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}};
424         RealMatrix n = new Array2DRowRealMatrix(matrixData2);
425         // Now multiply m by n
426         RealMatrix p = m.multiply(n);
427         Assert.assertEquals(2, p.getRowDimension());
428         Assert.assertEquals(2, p.getColumnDimension());
429         // Invert p
430         RealMatrix pInverse = new LUDecomposition(p).getSolver().getInverse();
431         Assert.assertEquals(2, pInverse.getRowDimension());
432         Assert.assertEquals(2, pInverse.getColumnDimension());
433 
434         // Solve example
435         double[][] coefficientsData = {{2, 3, -2}, {-1, 7, 6}, {4, -3, -5}};
436         RealMatrix coefficients = new Array2DRowRealMatrix(coefficientsData);
437         RealVector constants = new ArrayRealVector(new double[]{1, -2, 1}, false);
438         RealVector solution = new LUDecomposition(coefficients).getSolver().solve(constants);
439         final double cst0 = constants.getEntry(0);
440         final double cst1 = constants.getEntry(1);
441         final double cst2 = constants.getEntry(2);
442         final double sol0 = solution.getEntry(0);
443         final double sol1 = solution.getEntry(1);
444         final double sol2 = solution.getEntry(2);
445         Assert.assertEquals(2 * sol0 + 3 * sol1 -2 * sol2, cst0, 1E-12);
446         Assert.assertEquals(-1 * sol0 + 7 * sol1 + 6 * sol2, cst1, 1E-12);
447         Assert.assertEquals(4 * sol0 - 3 * sol1 -5 * sol2, cst2, 1E-12);
448     }
449 
450     // test submatrix accessors
451     @Test
452     public void testGetSubMatrix() {
453         RealMatrix m = new Array2DRowRealMatrix(subTestData);
454         checkGetSubMatrix(m, subRows23Cols00,  2 , 3 , 0, 0, false);
455         checkGetSubMatrix(m, subRows00Cols33,  0 , 0 , 3, 3, false);
456         checkGetSubMatrix(m, subRows01Cols23,  0 , 1 , 2, 3, false);
457         checkGetSubMatrix(m, subRows02Cols13,  new int[] { 0, 2 }, new int[] { 1, 3 },    false);
458         checkGetSubMatrix(m, subRows03Cols12,  new int[] { 0, 3 }, new int[] { 1, 2 },    false);
459         checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false);
460         checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false);
461         checkGetSubMatrix(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false);
462         checkGetSubMatrix(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false);
463         checkGetSubMatrix(m, null,  1, 0, 2, 4, true);
464         checkGetSubMatrix(m, null, -1, 1, 2, 2, true);
465         checkGetSubMatrix(m, null,  1, 0, 2, 2, true);
466         checkGetSubMatrix(m, null,  1, 0, 2, 4, true);
467         checkGetSubMatrix(m, null, new int[] {},    new int[] { 0 }, true);
468         checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }, true);
469     }
470 
471     private void checkGetSubMatrix(RealMatrix m, double[][] reference,
472                                    int startRow, int endRow, int startColumn, int endColumn,
473                                    boolean mustFail) {
474         try {
475             RealMatrix sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn);
476             Assert.assertEquals(new Array2DRowRealMatrix(reference), sub);
477             if (mustFail) {
478                 Assert.fail("Expecting OutOfRangeException or NumberIsTooSmallException or NoDataException");
479             }
480         } catch (OutOfRangeException e) {
481             if (!mustFail) {
482                 throw e;
483             }
484         } catch (NumberIsTooSmallException e) {
485             if (!mustFail) {
486                 throw e;
487             }
488         } catch (NoDataException e) {
489             if (!mustFail) {
490                 throw e;
491             }
492         }
493     }
494 
495     private void checkGetSubMatrix(RealMatrix m, double[][] reference,
496                                    int[] selectedRows, int[] selectedColumns,
497                                    boolean mustFail) {
498         try {
499             RealMatrix sub = m.getSubMatrix(selectedRows, selectedColumns);
500             Assert.assertEquals(new Array2DRowRealMatrix(reference), sub);
501             if (mustFail) {
502                 Assert.fail("Expecting OutOfRangeException or NumberIsTooSmallException or NoDataException");
503             }
504         } catch (OutOfRangeException e) {
505             if (!mustFail) {
506                 throw e;
507             }
508         } catch (NumberIsTooSmallException e) {
509             if (!mustFail) {
510                 throw e;
511             }
512         } catch (NoDataException e) {
513             if (!mustFail) {
514                 throw e;
515             }
516         }
517     }
518 
519     @Test
520     public void testCopySubMatrix() {
521         RealMatrix m = new Array2DRowRealMatrix(subTestData);
522         checkCopy(m, subRows23Cols00,  2 , 3 , 0, 0, false);
523         checkCopy(m, subRows00Cols33,  0 , 0 , 3, 3, false);
524         checkCopy(m, subRows01Cols23,  0 , 1 , 2, 3, false);
525         checkCopy(m, subRows02Cols13,  new int[] { 0, 2 }, new int[] { 1, 3 },    false);
526         checkCopy(m, subRows03Cols12,  new int[] { 0, 3 }, new int[] { 1, 2 },    false);
527         checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false);
528         checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false);
529         checkCopy(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false);
530         checkCopy(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false);
531 
532         checkCopy(m, null,  1, 0, 2, 4, true);
533         checkCopy(m, null, -1, 1, 2, 2, true);
534         checkCopy(m, null,  1, 0, 2, 2, true);
535         checkCopy(m, null,  1, 0, 2, 4, true);
536         checkCopy(m, null, new int[] {},    new int[] { 0 }, true);
537         checkCopy(m, null, new int[] { 0 }, new int[] { 4 }, true);
538 
539         // rectangular check
540         double[][] copy = new double[][] { { 0, 0, 0 }, { 0, 0 } };
541         checkCopy(m, copy, 0, 1, 0, 2, true);
542         checkCopy(m, copy, new int[] { 0, 1 }, new int[] { 0, 1, 2 }, true);
543     }
544 
545     private void checkCopy(RealMatrix m, double[][] reference,
546                            int startRow, int endRow, int startColumn, int endColumn,
547                            boolean mustFail) {
548         try {
549             double[][] sub = (reference == null) ?
550                              new double[1][1] : createIdenticalCopy(reference);
551             m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub);
552             Assert.assertEquals(new Array2DRowRealMatrix(reference), new Array2DRowRealMatrix(sub));
553             if (mustFail) {
554                 Assert.fail("Expecting OutOfRangeException or NumberIsTooSmallException or NoDataException");
555             }
556         } catch (OutOfRangeException e) {
557             if (!mustFail) {
558                 throw e;
559             }
560         } catch (NumberIsTooSmallException e) {
561             if (!mustFail) {
562                 throw e;
563             }
564         } catch (NoDataException e) {
565             if (!mustFail) {
566                 throw e;
567             }
568         } catch (MatrixDimensionMismatchException e) {
569             if (!mustFail) {
570                 throw e;
571             }
572         }
573     }
574 
575     private void checkCopy(RealMatrix m, double[][] reference,
576                            int[] selectedRows, int[] selectedColumns,
577                            boolean mustFail) {
578         try {
579             double[][] sub = (reference == null) ?
580                     new double[1][1] : createIdenticalCopy(reference);
581             m.copySubMatrix(selectedRows, selectedColumns, sub);
582             Assert.assertEquals(new Array2DRowRealMatrix(reference), new Array2DRowRealMatrix(sub));
583             if (mustFail) {
584                 Assert.fail("Expecting OutOfRangeException or NumberIsTooSmallException or NoDataException");
585             }
586         } catch (OutOfRangeException e) {
587             if (!mustFail) {
588                 throw e;
589             }
590         } catch (NumberIsTooSmallException e) {
591             if (!mustFail) {
592                 throw e;
593             }
594         } catch (NoDataException e) {
595             if (!mustFail) {
596                 throw e;
597             }
598         } catch (MatrixDimensionMismatchException e) {
599             if (!mustFail) {
600                 throw e;
601             }
602         }
603     }
604 
605     private double[][] createIdenticalCopy(final double[][] matrix) {
606         final double[][] matrixCopy = new double[matrix.length][];
607         for (int i = 0; i < matrixCopy.length; i++) {
608             matrixCopy[i] = new double[matrix[i].length];
609         }
610         return matrixCopy;
611     }
612 
613     @Test
614     public void testGetRowMatrix() {
615         RealMatrix m = new Array2DRowRealMatrix(subTestData);
616         RealMatrix mRow0 = new Array2DRowRealMatrix(subRow0);
617         RealMatrix mRow3 = new Array2DRowRealMatrix(subRow3);
618         Assert.assertEquals("Row0", mRow0,
619                 m.getRowMatrix(0));
620         Assert.assertEquals("Row3", mRow3,
621                 m.getRowMatrix(3));
622         try {
623             m.getRowMatrix(-1);
624             Assert.fail("Expecting OutOfRangeException");
625         } catch (OutOfRangeException ex) {
626             // expected
627         }
628         try {
629             m.getRowMatrix(4);
630             Assert.fail("Expecting OutOfRangeException");
631         } catch (OutOfRangeException ex) {
632             // expected
633         }
634     }
635 
636     @Test
637     public void testSetRowMatrix() {
638         RealMatrix m = new Array2DRowRealMatrix(subTestData);
639         RealMatrix mRow3 = new Array2DRowRealMatrix(subRow3);
640         Assert.assertNotSame(mRow3, m.getRowMatrix(0));
641         m.setRowMatrix(0, mRow3);
642         Assert.assertEquals(mRow3, m.getRowMatrix(0));
643         try {
644             m.setRowMatrix(-1, mRow3);
645             Assert.fail("Expecting OutOfRangeException");
646         } catch (OutOfRangeException ex) {
647             // expected
648         }
649         try {
650             m.setRowMatrix(0, m);
651             Assert.fail("Expecting MatrixDimensionMismatchException");
652         } catch (MatrixDimensionMismatchException ex) {
653             // expected
654         }
655     }
656 
657     @Test
658     public void testGetColumnMatrix() {
659         RealMatrix m = new Array2DRowRealMatrix(subTestData);
660         RealMatrix mColumn1 = new Array2DRowRealMatrix(subColumn1);
661         RealMatrix mColumn3 = new Array2DRowRealMatrix(subColumn3);
662         Assert.assertEquals("Column1", mColumn1,
663                 m.getColumnMatrix(1));
664         Assert.assertEquals("Column3", mColumn3,
665                 m.getColumnMatrix(3));
666         try {
667             m.getColumnMatrix(-1);
668             Assert.fail("Expecting OutOfRangeException");
669         } catch (OutOfRangeException ex) {
670             // expected
671         }
672         try {
673             m.getColumnMatrix(4);
674             Assert.fail("Expecting OutOfRangeException");
675         } catch (OutOfRangeException ex) {
676             // expected
677         }
678     }
679 
680     @Test
681     public void testSetColumnMatrix() {
682         RealMatrix m = new Array2DRowRealMatrix(subTestData);
683         RealMatrix mColumn3 = new Array2DRowRealMatrix(subColumn3);
684         Assert.assertNotSame(mColumn3, m.getColumnMatrix(1));
685         m.setColumnMatrix(1, mColumn3);
686         Assert.assertEquals(mColumn3, m.getColumnMatrix(1));
687         try {
688             m.setColumnMatrix(-1, mColumn3);
689             Assert.fail("Expecting OutOfRangeException");
690         } catch (OutOfRangeException ex) {
691             // expected
692         }
693         try {
694             m.setColumnMatrix(0, m);
695             Assert.fail("Expecting MatrixDimensionMismatchException");
696         } catch (MatrixDimensionMismatchException ex) {
697             // expected
698         }
699     }
700 
701     @Test
702     public void testGetRowVector() {
703         RealMatrix m = new Array2DRowRealMatrix(subTestData);
704         RealVector mRow0 = new ArrayRealVector(subRow0[0]);
705         RealVector mRow3 = new ArrayRealVector(subRow3[0]);
706         Assert.assertEquals("Row0", mRow0, m.getRowVector(0));
707         Assert.assertEquals("Row3", mRow3, m.getRowVector(3));
708         try {
709             m.getRowVector(-1);
710             Assert.fail("Expecting OutOfRangeException");
711         } catch (OutOfRangeException ex) {
712             // expected
713         }
714         try {
715             m.getRowVector(4);
716             Assert.fail("Expecting OutOfRangeException");
717         } catch (OutOfRangeException ex) {
718             // expected
719         }
720     }
721 
722     @Test
723     public void testSetRowVector() {
724         RealMatrix m = new Array2DRowRealMatrix(subTestData);
725         RealVector mRow3 = new ArrayRealVector(subRow3[0]);
726         Assert.assertNotSame(mRow3, m.getRowMatrix(0));
727         m.setRowVector(0, mRow3);
728         Assert.assertEquals(mRow3, m.getRowVector(0));
729         try {
730             m.setRowVector(-1, mRow3);
731             Assert.fail("Expecting OutOfRangeException");
732         } catch (OutOfRangeException ex) {
733             // expected
734         }
735         try {
736             m.setRowVector(0, new ArrayRealVector(5));
737             Assert.fail("Expecting MatrixDimensionMismatchException");
738         } catch (MatrixDimensionMismatchException ex) {
739             // expected
740         }
741     }
742 
743     @Test
744     public void testGetColumnVector() {
745         RealMatrix m = new Array2DRowRealMatrix(subTestData);
746         RealVector mColumn1 = columnToVector(subColumn1);
747         RealVector mColumn3 = columnToVector(subColumn3);
748         Assert.assertEquals("Column1", mColumn1, m.getColumnVector(1));
749         Assert.assertEquals("Column3", mColumn3, m.getColumnVector(3));
750         try {
751             m.getColumnVector(-1);
752             Assert.fail("Expecting OutOfRangeException");
753         } catch (OutOfRangeException ex) {
754             // expected
755         }
756         try {
757             m.getColumnVector(4);
758             Assert.fail("Expecting OutOfRangeException");
759         } catch (OutOfRangeException ex) {
760             // expected
761         }
762     }
763 
764     @Test
765     public void testSetColumnVector() {
766         RealMatrix m = new Array2DRowRealMatrix(subTestData);
767         RealVector mColumn3 = columnToVector(subColumn3);
768         Assert.assertNotSame(mColumn3, m.getColumnVector(1));
769         m.setColumnVector(1, mColumn3);
770         Assert.assertEquals(mColumn3, m.getColumnVector(1));
771         try {
772             m.setColumnVector(-1, mColumn3);
773             Assert.fail("Expecting OutOfRangeException");
774         } catch (OutOfRangeException ex) {
775             // expected
776         }
777         try {
778             m.setColumnVector(0, new ArrayRealVector(5));
779             Assert.fail("Expecting MatrixDimensionMismatchException");
780         } catch (MatrixDimensionMismatchException ex) {
781             // expected
782         }
783     }
784 
785     private RealVector columnToVector(double[][] column) {
786         double[] data = new double[column.length];
787         for (int i = 0; i < data.length; ++i) {
788             data[i] = column[i][0];
789         }
790         return new ArrayRealVector(data, false);
791     }
792 
793     @Test
794     public void testGetRow() {
795         RealMatrix m = new Array2DRowRealMatrix(subTestData);
796         checkArrays(subRow0[0], m.getRow(0));
797         checkArrays(subRow3[0], m.getRow(3));
798         try {
799             m.getRow(-1);
800             Assert.fail("Expecting OutOfRangeException");
801         } catch (OutOfRangeException ex) {
802             // expected
803         }
804         try {
805             m.getRow(4);
806             Assert.fail("Expecting OutOfRangeException");
807         } catch (OutOfRangeException ex) {
808             // expected
809         }
810     }
811 
812     @Test
813     public void testSetRow() {
814         RealMatrix m = new Array2DRowRealMatrix(subTestData);
815         Assert.assertTrue(subRow3[0][0] != m.getRow(0)[0]);
816         m.setRow(0, subRow3[0]);
817         checkArrays(subRow3[0], m.getRow(0));
818         try {
819             m.setRow(-1, subRow3[0]);
820             Assert.fail("Expecting OutOfRangeException");
821         } catch (OutOfRangeException ex) {
822             // expected
823         }
824         try {
825             m.setRow(0, new double[5]);
826             Assert.fail("Expecting MatrixDimensionMismatchException");
827         } catch (MatrixDimensionMismatchException ex) {
828             // expected
829         }
830     }
831 
832     @Test
833     public void testGetColumn() {
834         RealMatrix m = new Array2DRowRealMatrix(subTestData);
835         double[] mColumn1 = columnToArray(subColumn1);
836         double[] mColumn3 = columnToArray(subColumn3);
837         checkArrays(mColumn1, m.getColumn(1));
838         checkArrays(mColumn3, m.getColumn(3));
839         try {
840             m.getColumn(-1);
841             Assert.fail("Expecting OutOfRangeException");
842         } catch (OutOfRangeException ex) {
843             // expected
844         }
845         try {
846             m.getColumn(4);
847             Assert.fail("Expecting OutOfRangeException");
848         } catch (OutOfRangeException ex) {
849             // expected
850         }
851     }
852 
853     @Test
854     public void testSetColumn() {
855         RealMatrix m = new Array2DRowRealMatrix(subTestData);
856         double[] mColumn3 = columnToArray(subColumn3);
857         Assert.assertTrue(mColumn3[0] != m.getColumn(1)[0]);
858         m.setColumn(1, mColumn3);
859         checkArrays(mColumn3, m.getColumn(1));
860         try {
861             m.setColumn(-1, mColumn3);
862             Assert.fail("Expecting OutOfRangeException");
863         } catch (OutOfRangeException ex) {
864             // expected
865         }
866         try {
867             m.setColumn(0, new double[5]);
868             Assert.fail("Expecting MatrixDimensionMismatchException");
869         } catch (MatrixDimensionMismatchException ex) {
870             // expected
871         }
872     }
873 
874     private double[] columnToArray(double[][] column) {
875         double[] data = new double[column.length];
876         for (int i = 0; i < data.length; ++i) {
877             data[i] = column[i][0];
878         }
879         return data;
880     }
881 
882     private void checkArrays(double[] expected, double[] actual) {
883         Assert.assertEquals(expected.length, actual.length);
884         for (int i = 0; i < expected.length; ++i) {
885             Assert.assertEquals(expected[i], actual[i], 0);
886         }
887     }
888 
889     @Test
890     public void testEqualsAndHashCode() {
891         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
892         Array2DRowRealMatrix m1 = (Array2DRowRealMatrix) m.copy();
893         Array2DRowRealMatrix mt = (Array2DRowRealMatrix) m.transpose();
894         Assert.assertTrue(m.hashCode() != mt.hashCode());
895         Assert.assertEquals(m.hashCode(), m1.hashCode());
896         Assert.assertEquals(m, m);
897         Assert.assertEquals(m, m1);
898         Assert.assertNotEquals(m, null);
899         Assert.assertNotEquals(m, mt);
900         Assert.assertNotEquals(m, new Array2DRowRealMatrix(bigSingular));
901     }
902 
903     @Test
904     public void testToString() {
905         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
906         Assert.assertEquals("Array2DRowRealMatrix{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}",
907                 m.toString());
908         m = new Array2DRowRealMatrix();
909         Assert.assertEquals("Array2DRowRealMatrix{}",
910                 m.toString());
911     }
912 
913     @Test
914     public void testSetSubMatrix() {
915         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
916         m.setSubMatrix(detData2,1,1);
917         RealMatrix expected = MatrixUtils.createRealMatrix
918             (new double[][] {{1.0,2.0,3.0},{2.0,1.0,3.0},{1.0,2.0,4.0}});
919         Assert.assertEquals(expected, m);
920 
921         m.setSubMatrix(detData2,0,0);
922         expected = MatrixUtils.createRealMatrix
923             (new double[][] {{1.0,3.0,3.0},{2.0,4.0,3.0},{1.0,2.0,4.0}});
924         Assert.assertEquals(expected, m);
925 
926         m.setSubMatrix(testDataPlus2,0,0);
927         expected = MatrixUtils.createRealMatrix
928             (new double[][] {{3.0,4.0,5.0},{4.0,7.0,5.0},{3.0,2.0,10.0}});
929         Assert.assertEquals(expected, m);
930 
931         // dimension overflow
932         try {
933             m.setSubMatrix(testData,1,1);
934             Assert.fail("expecting OutOfRangeException");
935         } catch (OutOfRangeException e) {
936             // expected
937         }
938         // dimension underflow
939         try {
940             m.setSubMatrix(testData,-1,1);
941             Assert.fail("expecting OutOfRangeException");
942         } catch (OutOfRangeException e) {
943             // expected
944         }
945         try {
946             m.setSubMatrix(testData,1,-1);
947             Assert.fail("expecting OutOfRangeException");
948         } catch (OutOfRangeException e) {
949             // expected
950         }
951 
952         // null
953         try {
954             m.setSubMatrix(null,1,1);
955             Assert.fail("expecting NullArgumentException");
956         } catch (NullArgumentException e) {
957             // expected
958         }
959         Array2DRowRealMatrix m2 = new Array2DRowRealMatrix();
960         try {
961             m2.setSubMatrix(testData,0,1);
962             Assert.fail("expecting MathIllegalStateException");
963         } catch (MathIllegalStateException e) {
964             // expected
965         }
966         try {
967             m2.setSubMatrix(testData,1,0);
968             Assert.fail("expecting MathIllegalStateException");
969         } catch (MathIllegalStateException e) {
970             // expected
971         }
972 
973         // ragged
974         try {
975             m.setSubMatrix(new double[][] {{1}, {2, 3}}, 0, 0);
976             Assert.fail("expecting MathIllegalArgumentException");
977         } catch (MathIllegalArgumentException e) {
978             // expected
979         }
980 
981         // empty
982         try {
983             m.setSubMatrix(new double[][] {{}}, 0, 0);
984             Assert.fail("expecting MathIllegalArgumentException");
985         } catch (MathIllegalArgumentException e) {
986             // expected
987         }
988     }
989 
990     @Test
991     public void testWalk() {
992         int rows    = 150;
993         int columns = 75;
994 
995         RealMatrix m = new Array2DRowRealMatrix(rows, columns);
996         m.walkInRowOrder(new SetVisitor());
997         GetVisitor getVisitor = new GetVisitor();
998         m.walkInOptimizedOrder(getVisitor);
999         Assert.assertEquals(rows * columns, getVisitor.getCount());
1000 
1001         m = new Array2DRowRealMatrix(rows, columns);
1002         m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
1003         getVisitor = new GetVisitor();
1004         m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2);
1005         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
1006         for (int i = 0; i < rows; ++i) {
1007             Assert.assertEquals(0.0, m.getEntry(i, 0), 0);
1008             Assert.assertEquals(0.0, m.getEntry(i, columns - 1), 0);
1009         }
1010         for (int j = 0; j < columns; ++j) {
1011             Assert.assertEquals(0.0, m.getEntry(0, j), 0);
1012             Assert.assertEquals(0.0, m.getEntry(rows - 1, j), 0);
1013         }
1014 
1015         m = new Array2DRowRealMatrix(rows, columns);
1016         m.walkInColumnOrder(new SetVisitor());
1017         getVisitor = new GetVisitor();
1018         m.walkInOptimizedOrder(getVisitor);
1019         Assert.assertEquals(rows * columns, getVisitor.getCount());
1020 
1021         m = new Array2DRowRealMatrix(rows, columns);
1022         m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
1023         getVisitor = new GetVisitor();
1024         m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2);
1025         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
1026         for (int i = 0; i < rows; ++i) {
1027             Assert.assertEquals(0.0, m.getEntry(i, 0), 0);
1028             Assert.assertEquals(0.0, m.getEntry(i, columns - 1), 0);
1029         }
1030         for (int j = 0; j < columns; ++j) {
1031             Assert.assertEquals(0.0, m.getEntry(0, j), 0);
1032             Assert.assertEquals(0.0, m.getEntry(rows - 1, j), 0);
1033         }
1034 
1035         m = new Array2DRowRealMatrix(rows, columns);
1036         m.walkInOptimizedOrder(new SetVisitor());
1037         getVisitor = new GetVisitor();
1038         m.walkInRowOrder(getVisitor);
1039         Assert.assertEquals(rows * columns, getVisitor.getCount());
1040 
1041         m = new Array2DRowRealMatrix(rows, columns);
1042         m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
1043         getVisitor = new GetVisitor();
1044         m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2);
1045         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
1046         for (int i = 0; i < rows; ++i) {
1047             Assert.assertEquals(0.0, m.getEntry(i, 0), 0);
1048             Assert.assertEquals(0.0, m.getEntry(i, columns - 1), 0);
1049         }
1050         for (int j = 0; j < columns; ++j) {
1051             Assert.assertEquals(0.0, m.getEntry(0, j), 0);
1052             Assert.assertEquals(0.0, m.getEntry(rows - 1, j), 0);
1053         }
1054 
1055         m = new Array2DRowRealMatrix(rows, columns);
1056         m.walkInOptimizedOrder(new SetVisitor());
1057         getVisitor = new GetVisitor();
1058         m.walkInColumnOrder(getVisitor);
1059         Assert.assertEquals(rows * columns, getVisitor.getCount());
1060 
1061         m = new Array2DRowRealMatrix(rows, columns);
1062         m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
1063         getVisitor = new GetVisitor();
1064         m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2);
1065         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
1066         for (int i = 0; i < rows; ++i) {
1067             Assert.assertEquals(0.0, m.getEntry(i, 0), 0);
1068             Assert.assertEquals(0.0, m.getEntry(i, columns - 1), 0);
1069         }
1070         for (int j = 0; j < columns; ++j) {
1071             Assert.assertEquals(0.0, m.getEntry(0, j), 0);
1072             Assert.assertEquals(0.0, m.getEntry(rows - 1, j), 0);
1073         }
1074     }
1075 
1076     @Test
1077     public void testSerial()  {
1078         Array2DRowRealMatrix m = new Array2DRowRealMatrix(testData);
1079         Assert.assertEquals(m,TestUtils.serializeAndRecover(m));
1080     }
1081 
1082 
1083     private static final class SetVisitor extends DefaultRealMatrixChangingVisitor {
1084         @Override
1085         public double visit(int i, int j, double value) {
1086             return i + j / 1024.0;
1087         }
1088     }
1089 
1090     private static final class GetVisitor extends DefaultRealMatrixPreservingVisitor {
1091         private int count = 0;
1092         @Override
1093         public void visit(int i, int j, double value) {
1094             ++count;
1095             Assert.assertEquals(i + j / 1024.0, value, 0.0);
1096         }
1097         public int getCount() {
1098             return count;
1099         }
1100     }
1101 
1102     //--------------- -----------------Protected methods
1103 
1104     /** extracts the l  and u matrices from compact lu representation */
1105     protected void splitLU(RealMatrix lu, double[][] lowerData, double[][] upperData) {
1106         if (!lu.isSquare()) {
1107             throw new NonSquareMatrixException(lu.getRowDimension(), lu.getColumnDimension());
1108         }
1109         if (lowerData.length != lowerData[0].length) {
1110             throw new DimensionMismatchException(lowerData.length, lowerData[0].length);
1111         }
1112         if (upperData.length != upperData[0].length) {
1113             throw new DimensionMismatchException(upperData.length, upperData[0].length);
1114         }
1115         if (lowerData.length != upperData.length) {
1116             throw new DimensionMismatchException(lowerData.length, upperData.length);
1117         }
1118         if (lowerData.length != lu.getRowDimension()) {
1119             throw new DimensionMismatchException(lowerData.length, lu.getRowDimension());
1120         }
1121 
1122         int n = lu.getRowDimension();
1123         for (int i = 0; i < n; i++) {
1124             for (int j = 0; j < n; j++) {
1125                 if (j < i) {
1126                     lowerData[i][j] = lu.getEntry(i, j);
1127                     upperData[i][j] = 0d;
1128                 } else if (i == j) {
1129                     lowerData[i][j] = 1d;
1130                     upperData[i][j] = lu.getEntry(i, j);
1131                 } else {
1132                     lowerData[i][j] = 0d;
1133                     upperData[i][j] = lu.getEntry(i, j);
1134                 }
1135             }
1136         }
1137     }
1138 
1139     /** Returns the result of applying the given row permutation to the matrix */
1140     protected RealMatrix permuteRows(RealMatrix matrix, int[] permutation) {
1141         if (!matrix.isSquare()) {
1142             throw new NonSquareMatrixException(matrix.getRowDimension(),
1143                                                matrix.getColumnDimension());
1144         }
1145         if (matrix.getRowDimension() != permutation.length) {
1146             throw new DimensionMismatchException(matrix.getRowDimension(), permutation.length);
1147         }
1148 
1149         int n = matrix.getRowDimension();
1150         int m = matrix.getColumnDimension();
1151         double out[][] = new double[m][n];
1152         for (int i = 0; i < n; i++) {
1153             for (int j = 0; j < m; j++) {
1154                 out[i][j] = matrix.getEntry(permutation[i], j);
1155             }
1156         }
1157         return new Array2DRowRealMatrix(out);
1158     }
1159 
1160 //    /** Useful for debugging */
1161 //    private void dumpMatrix(RealMatrix m) {
1162 //          for (int i = 0; i < m.getRowDimension(); i++) {
1163 //              String os = "";
1164 //              for (int j = 0; j < m.getColumnDimension(); j++) {
1165 //                  os += m.getEntry(i, j) + " ";
1166 //              }
1167 //              System.out.println(os);
1168 //          }
1169 //    }
1170 }
1171