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