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