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