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