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 junit.framework.Test;
20  import junit.framework.TestCase;
21  import junit.framework.TestSuite;
22  
23  import org.apache.commons.math.TestUtils;
24  
25  /**
26   * Test cases for the {@link OpenMapRealMatrix} class.
27   * 
28   * @version $Revision: 790243 $ $Date: 2008-11-07 06:48:13 -0800 (Fri, 07 Nov
29   *          2008) $
30   */
31  public final class SparseRealMatrixTest extends TestCase {
32  
33      // 3 x 3 identity matrix
34      protected double[][] id = { { 1d, 0d, 0d }, { 0d, 1d, 0d }, { 0d, 0d, 1d } };
35      // Test data for group operations
36      protected double[][] testData = { { 1d, 2d, 3d }, { 2d, 5d, 3d },
37              { 1d, 0d, 8d } };
38      protected double[][] testDataLU = { { 2d, 5d, 3d }, { .5d, -2.5d, 6.5d },
39              { 0.5d, 0.2d, .2d } };
40      protected double[][] testDataPlus2 = { { 3d, 4d, 5d }, { 4d, 7d, 5d },
41              { 3d, 2d, 10d } };
42      protected double[][] testDataMinus = { { -1d, -2d, -3d },
43              { -2d, -5d, -3d }, { -1d, 0d, -8d } };
44      protected double[] testDataRow1 = { 1d, 2d, 3d };
45      protected double[] testDataCol3 = { 3d, 3d, 8d };
46      protected double[][] testDataInv = { { -40d, 16d, 9d }, { 13d, -5d, -3d },
47              { 5d, -2d, -1d } };
48      protected double[] preMultTest = { 8, 12, 33 };
49      protected double[][] testData2 = { { 1d, 2d, 3d }, { 2d, 5d, 3d } };
50      protected double[][] testData2T = { { 1d, 2d }, { 2d, 5d }, { 3d, 3d } };
51      protected double[][] testDataPlusInv = { { -39d, 18d, 12d },
52              { 15d, 0d, 0d }, { 6d, -2d, 7d } };
53  
54      // lu decomposition tests
55      protected double[][] luData = { { 2d, 3d, 3d }, { 0d, 5d, 7d }, { 6d, 9d, 8d } };
56      protected double[][] luDataLUDecomposition = { { 6d, 9d, 8d },
57              { 0d, 5d, 7d }, { 0.33333333333333, 0d, 0.33333333333333 } };
58  
59      // singular matrices
60      protected double[][] singular = { { 2d, 3d }, { 2d, 3d } };
61      protected double[][] bigSingular = { { 1d, 2d, 3d, 4d },
62              { 2d, 5d, 3d, 4d }, { 7d, 3d, 256d, 1930d }, { 3d, 7d, 6d, 8d } }; // 4th
63  
64      // row
65      // =
66      // 1st
67      // +
68      // 2nd
69      protected double[][] detData = { { 1d, 2d, 3d }, { 4d, 5d, 6d },
70              { 7d, 8d, 10d } };
71      protected double[][] detData2 = { { 1d, 3d }, { 2d, 4d } };
72  
73      // vectors
74      protected double[] testVector = { 1, 2, 3 };
75      protected double[] testVector2 = { 1, 2, 3, 4 };
76  
77      // submatrix accessor tests
78      protected double[][] subTestData = { { 1, 2, 3, 4 },
79              { 1.5, 2.5, 3.5, 4.5 }, { 2, 4, 6, 8 }, { 4, 5, 6, 7 } };
80  
81      // array selections
82      protected double[][] subRows02Cols13 = { { 2, 4 }, { 4, 8 } };
83      protected double[][] subRows03Cols12 = { { 2, 3 }, { 5, 6 } };
84      protected double[][] subRows03Cols123 = { { 2, 3, 4 }, { 5, 6, 7 } };
85  
86      // effective permutations
87      protected double[][] subRows20Cols123 = { { 4, 6, 8 }, { 2, 3, 4 } };
88      protected double[][] subRows31Cols31 = { { 7, 5 }, { 4.5, 2.5 } };
89  
90      // contiguous ranges
91      protected double[][] subRows01Cols23 = { { 3, 4 }, { 3.5, 4.5 } };
92      protected double[][] subRows23Cols00 = { { 2 }, { 4 } };
93      protected double[][] subRows00Cols33 = { { 4 } };
94  
95      // row matrices
96      protected double[][] subRow0 = { { 1, 2, 3, 4 } };
97      protected double[][] subRow3 = { { 4, 5, 6, 7 } };
98  
99      // column matrices
100     protected double[][] subColumn1 = { { 2 }, { 2.5 }, { 4 }, { 5 } };
101     protected double[][] subColumn3 = { { 4 }, { 4.5 }, { 8 }, { 7 } };
102 
103     // tolerances
104     protected double entryTolerance = 10E-16;
105     protected double normTolerance = 10E-14;
106 
107     public SparseRealMatrixTest(String name) {
108         super(name);
109     }
110 
111     public static Test suite() {
112         TestSuite suite = new TestSuite(SparseRealMatrixTest.class);
113         suite.setName("SparseRealMatrix Tests");
114         return suite;
115     }
116 
117     /** test dimensions */
118     public void testDimensions() {
119         OpenMapRealMatrix m = createSparseMatrix(testData);
120         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
121         assertEquals("testData row dimension", 3, m.getRowDimension());
122         assertEquals("testData column dimension", 3, m.getColumnDimension());
123         assertTrue("testData is square", m.isSquare());
124         assertEquals("testData2 row dimension", m2.getRowDimension(), 2);
125         assertEquals("testData2 column dimension", m2.getColumnDimension(), 3);
126         assertTrue("testData2 is not square", !m2.isSquare());
127     }
128 
129     /** test copy functions */
130     public void testCopyFunctions() {
131         OpenMapRealMatrix m1 = createSparseMatrix(testData);
132         RealMatrix m2 = m1.copy();
133         assertEquals(m1.getClass(), m2.getClass());
134         assertEquals((m2), m1);
135         OpenMapRealMatrix m3 = createSparseMatrix(testData);
136         RealMatrix m4 = m3.copy();
137         assertEquals(m3.getClass(), m4.getClass());
138         assertEquals((m4), m3);
139     }
140 
141     /** test add */
142     public void testAdd() {
143         OpenMapRealMatrix m = createSparseMatrix(testData);
144         OpenMapRealMatrix mInv = createSparseMatrix(testDataInv);
145         OpenMapRealMatrix mDataPlusInv = createSparseMatrix(testDataPlusInv);
146         RealMatrix mPlusMInv = m.add(mInv);
147         for (int row = 0; row < m.getRowDimension(); row++) {
148             for (int col = 0; col < m.getColumnDimension(); col++) {
149                 assertEquals("sum entry entry", 
150                     mDataPlusInv.getEntry(row, col), mPlusMInv.getEntry(row, col), 
151                     entryTolerance);
152             }
153         }
154     }
155 
156     /** test add failure */
157     public void testAddFail() {
158         OpenMapRealMatrix m = createSparseMatrix(testData);
159         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
160         try {
161             m.add(m2);
162             fail("IllegalArgumentException expected");
163         } catch (IllegalArgumentException ex) {
164             // ignored
165         }
166     }
167 
168     /** test norm */
169     public void testNorm() {
170         OpenMapRealMatrix m = createSparseMatrix(testData);
171         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
172         assertEquals("testData norm", 14d, m.getNorm(), entryTolerance);
173         assertEquals("testData2 norm", 7d, m2.getNorm(), entryTolerance);
174     }
175 
176     /** test m-n = m + -n */
177     public void testPlusMinus() {
178         OpenMapRealMatrix m = createSparseMatrix(testData);
179         OpenMapRealMatrix n = createSparseMatrix(testDataInv);
180         assertClose("m-n = m + -n", m.subtract(n),
181             n.scalarMultiply(-1d).add(m), entryTolerance);
182         try {
183             m.subtract(createSparseMatrix(testData2));
184             fail("Expecting illegalArgumentException");
185         } catch (IllegalArgumentException ex) {
186             // ignored
187         }
188     }
189 
190     /** test multiply */
191     public void testMultiply() {
192         OpenMapRealMatrix m = createSparseMatrix(testData);
193         OpenMapRealMatrix mInv = createSparseMatrix(testDataInv);
194         OpenMapRealMatrix identity = createSparseMatrix(id);
195         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
196         assertClose("inverse multiply", m.multiply(mInv), identity,
197                 entryTolerance);
198         assertClose("inverse multiply", m.multiply(new BlockRealMatrix(testDataInv)), identity,
199                     entryTolerance);
200         assertClose("inverse multiply", mInv.multiply(m), identity,
201                 entryTolerance);
202         assertClose("identity multiply", m.multiply(identity), m,
203                 entryTolerance);
204         assertClose("identity multiply", identity.multiply(mInv), mInv,
205                 entryTolerance);
206         assertClose("identity multiply", m2.multiply(identity), m2,
207                 entryTolerance);
208         try {
209             m.multiply(createSparseMatrix(bigSingular));
210             fail("Expecting illegalArgumentException");
211         } catch (IllegalArgumentException ex) {
212             // ignored
213         }
214     }
215 
216     // Additional Test for Array2DRowRealMatrixTest.testMultiply
217 
218     private double[][] d3 = new double[][] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } };
219     private double[][] d4 = new double[][] { { 1 }, { 2 }, { 3 }, { 4 } };
220     private double[][] d5 = new double[][] { { 30 }, { 70 } };
221 
222     public void testMultiply2() {
223         RealMatrix m3 = createSparseMatrix(d3);
224         RealMatrix m4 = createSparseMatrix(d4);
225         RealMatrix m5 = createSparseMatrix(d5);
226         assertClose("m3*m4=m5", m3.multiply(m4), m5, entryTolerance);
227     }
228 
229     /** test trace */
230     public void testTrace() {
231         RealMatrix m = createSparseMatrix(id);
232         assertEquals("identity trace", 3d, m.getTrace(), entryTolerance);
233         m = createSparseMatrix(testData2);
234         try {
235             m.getTrace();
236             fail("Expecting NonSquareMatrixException");
237         } catch (NonSquareMatrixException ex) {
238             // ignored
239         }
240     }
241 
242     /** test sclarAdd */
243     public void testScalarAdd() {
244         RealMatrix m = createSparseMatrix(testData);
245         assertClose("scalar add", createSparseMatrix(testDataPlus2), 
246             m.scalarAdd(2d), entryTolerance);
247     }
248 
249     /** test operate */
250     public void testOperate() {
251         RealMatrix m = createSparseMatrix(id);
252         assertClose("identity operate", testVector, m.operate(testVector),
253                 entryTolerance);
254         assertClose("identity operate", testVector, m.operate(
255                 new ArrayRealVector(testVector)).getData(), entryTolerance);
256         m = createSparseMatrix(bigSingular);
257         try {
258             m.operate(testVector);
259             fail("Expecting illegalArgumentException");
260         } catch (IllegalArgumentException ex) {
261             // ignored
262         }
263     }
264 
265     /** test issue MATH-209 */
266     public void testMath209() {
267         RealMatrix a = createSparseMatrix(new double[][] {
268                 { 1, 2 }, { 3, 4 }, { 5, 6 } });
269         double[] b = a.operate(new double[] { 1, 1 });
270         assertEquals(a.getRowDimension(), b.length);
271         assertEquals(3.0, b[0], 1.0e-12);
272         assertEquals(7.0, b[1], 1.0e-12);
273         assertEquals(11.0, b[2], 1.0e-12);
274     }
275 
276     /** test transpose */
277     public void testTranspose() {
278         
279         RealMatrix m = createSparseMatrix(testData); 
280         RealMatrix mIT = new LUDecompositionImpl(m).getSolver().getInverse().transpose();
281         RealMatrix mTI = new LUDecompositionImpl(m.transpose()).getSolver().getInverse();
282         assertClose("inverse-transpose", mIT, mTI, normTolerance);
283         m = createSparseMatrix(testData2);
284         RealMatrix mt = createSparseMatrix(testData2T);
285         assertClose("transpose",mt,m.transpose(),normTolerance);
286     }
287 
288     /** test preMultiply by vector */
289     public void testPremultiplyVector() {
290         RealMatrix m = createSparseMatrix(testData);
291         assertClose("premultiply", m.preMultiply(testVector), preMultTest,
292             normTolerance);
293         assertClose("premultiply", m.preMultiply(
294             new ArrayRealVector(testVector).getData()), preMultTest, normTolerance);
295         m = createSparseMatrix(bigSingular);
296         try {
297             m.preMultiply(testVector);
298             fail("expecting IllegalArgumentException");
299         } catch (IllegalArgumentException ex) {
300             // ignored
301         }
302     }
303 
304     public void testPremultiply() {
305         RealMatrix m3 = createSparseMatrix(d3);
306         RealMatrix m4 = createSparseMatrix(d4);
307         RealMatrix m5 = createSparseMatrix(d5);
308         assertClose("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance);
309 
310         OpenMapRealMatrix m = createSparseMatrix(testData);
311         OpenMapRealMatrix mInv = createSparseMatrix(testDataInv);
312         OpenMapRealMatrix identity = createSparseMatrix(id);
313         assertClose("inverse multiply", m.preMultiply(mInv), identity,
314                 entryTolerance);
315         assertClose("inverse multiply", mInv.preMultiply(m), identity,
316                 entryTolerance);
317         assertClose("identity multiply", m.preMultiply(identity), m,
318                 entryTolerance);
319         assertClose("identity multiply", identity.preMultiply(mInv), mInv,
320                 entryTolerance);
321         try {
322             m.preMultiply(createSparseMatrix(bigSingular));
323             fail("Expecting illegalArgumentException");
324         } catch (IllegalArgumentException ex) {
325             // ignored
326         }
327     }
328 
329     public void testGetVectors() {
330         RealMatrix m = createSparseMatrix(testData);
331         assertClose("get row", m.getRow(0), testDataRow1, entryTolerance);
332         assertClose("get col", m.getColumn(2), testDataCol3, entryTolerance);
333         try {
334             m.getRow(10);
335             fail("expecting MatrixIndexException");
336         } catch (MatrixIndexException ex) {
337             // ignored
338         }
339         try {
340             m.getColumn(-1);
341             fail("expecting MatrixIndexException");
342         } catch (MatrixIndexException ex) {
343             // ignored
344         }
345     }
346 
347     public void testGetEntry() {
348         RealMatrix m = createSparseMatrix(testData);
349         assertEquals("get entry", m.getEntry(0, 1), 2d, entryTolerance);
350         try {
351             m.getEntry(10, 4);
352             fail("Expecting MatrixIndexException");
353         } catch (MatrixIndexException ex) {
354             // expected
355         }
356     }
357 
358     /** test examples in user guide */
359     public void testExamples() {
360         // Create a real matrix with two rows and three columns
361         double[][] matrixData = { { 1d, 2d, 3d }, { 2d, 5d, 3d } };
362         RealMatrix m = createSparseMatrix(matrixData);
363         // One more with three rows, two columns
364         double[][] matrixData2 = { { 1d, 2d }, { 2d, 5d }, { 1d, 7d } };
365         RealMatrix n = createSparseMatrix(matrixData2);
366         // Now multiply m by n
367         RealMatrix p = m.multiply(n);
368         assertEquals(2, p.getRowDimension());
369         assertEquals(2, p.getColumnDimension());
370         // Invert p
371         RealMatrix pInverse = new LUDecompositionImpl(p).getSolver().getInverse(); 
372         assertEquals(2, pInverse.getRowDimension());
373         assertEquals(2, pInverse.getColumnDimension());
374 
375         // Solve example
376         double[][] coefficientsData = { { 2, 3, -2 }, { -1, 7, 6 },
377                 { 4, -3, -5 } };
378         RealMatrix coefficients = createSparseMatrix(coefficientsData);
379         double[] constants = { 1, -2, 1 };
380         double[] solution = new LUDecompositionImpl(coefficients).getSolver().solve(constants);
381         assertEquals(2 * solution[0] + 3 * solution[1] - 2 * solution[2],
382                 constants[0], 1E-12);
383         assertEquals(-1 * solution[0] + 7 * solution[1] + 6 * solution[2],
384                 constants[1], 1E-12);
385         assertEquals(4 * solution[0] - 3 * solution[1] - 5 * solution[2],
386                 constants[2], 1E-12);
387 
388     }
389 
390     // test submatrix accessors
391     public void testSubMatrix() {
392         RealMatrix m = createSparseMatrix(subTestData);
393         RealMatrix mRows23Cols00 = createSparseMatrix(subRows23Cols00);
394         RealMatrix mRows00Cols33 = createSparseMatrix(subRows00Cols33);
395         RealMatrix mRows01Cols23 = createSparseMatrix(subRows01Cols23);
396         RealMatrix mRows02Cols13 = createSparseMatrix(subRows02Cols13);
397         RealMatrix mRows03Cols12 = createSparseMatrix(subRows03Cols12);
398         RealMatrix mRows03Cols123 = createSparseMatrix(subRows03Cols123);
399         RealMatrix mRows20Cols123 = createSparseMatrix(subRows20Cols123);
400         RealMatrix mRows31Cols31 = createSparseMatrix(subRows31Cols31);
401         assertEquals("Rows23Cols00", mRows23Cols00, m.getSubMatrix(2, 3, 0, 0));
402         assertEquals("Rows00Cols33", mRows00Cols33, m.getSubMatrix(0, 0, 3, 3));
403         assertEquals("Rows01Cols23", mRows01Cols23, m.getSubMatrix(0, 1, 2, 3));
404         assertEquals("Rows02Cols13", mRows02Cols13, 
405             m.getSubMatrix(new int[] { 0, 2 }, new int[] { 1, 3 }));
406         assertEquals("Rows03Cols12", mRows03Cols12, 
407             m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2 }));
408         assertEquals("Rows03Cols123", mRows03Cols123, 
409             m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2, 3 }));
410         assertEquals("Rows20Cols123", mRows20Cols123, 
411             m.getSubMatrix(new int[] { 2, 0 }, new int[] { 1, 2, 3 }));
412         assertEquals("Rows31Cols31", mRows31Cols31, 
413             m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 }));
414         assertEquals("Rows31Cols31", mRows31Cols31, 
415             m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 }));
416 
417         try {
418             m.getSubMatrix(1, 0, 2, 4);
419             fail("Expecting MatrixIndexException");
420         } catch (MatrixIndexException ex) {
421             // expected
422         }
423         try {
424             m.getSubMatrix(-1, 1, 2, 2);
425             fail("Expecting MatrixIndexException");
426         } catch (MatrixIndexException ex) {
427             // expected
428         }
429         try {
430             m.getSubMatrix(1, 0, 2, 2);
431             fail("Expecting MatrixIndexException");
432         } catch (MatrixIndexException ex) {
433             // expected
434         }
435         try {
436             m.getSubMatrix(1, 0, 2, 4);
437             fail("Expecting MatrixIndexException");
438         } catch (MatrixIndexException ex) {
439             // expected
440         }
441         try {
442             m.getSubMatrix(new int[] {}, new int[] { 0 });
443             fail("Expecting MatrixIndexException");
444         } catch (MatrixIndexException ex) {
445             // expected
446         }
447         try {
448             m.getSubMatrix(new int[] { 0 }, new int[] { 4 });
449             fail("Expecting MatrixIndexException");
450         } catch (MatrixIndexException ex) {
451             // expected
452         }
453     }
454 
455     public void testGetRowMatrix() {
456         RealMatrix m = createSparseMatrix(subTestData);
457         RealMatrix mRow0 = createSparseMatrix(subRow0);
458         RealMatrix mRow3 = createSparseMatrix(subRow3);
459         assertEquals("Row0", mRow0, m.getRowMatrix(0));
460         assertEquals("Row3", mRow3, m.getRowMatrix(3));
461         try {
462             m.getRowMatrix(-1);
463             fail("Expecting MatrixIndexException");
464         } catch (MatrixIndexException ex) {
465             // expected
466         }
467         try {
468             m.getRowMatrix(4);
469             fail("Expecting MatrixIndexException");
470         } catch (MatrixIndexException ex) {
471             // expected
472         }
473     }
474 
475     public void testGetColumnMatrix() {
476         RealMatrix m = createSparseMatrix(subTestData);
477         RealMatrix mColumn1 = createSparseMatrix(subColumn1);
478         RealMatrix mColumn3 = createSparseMatrix(subColumn3);
479         assertEquals("Column1", mColumn1, m.getColumnMatrix(1));
480         assertEquals("Column3", mColumn3, m.getColumnMatrix(3));
481         try {
482             m.getColumnMatrix(-1);
483             fail("Expecting MatrixIndexException");
484         } catch (MatrixIndexException ex) {
485             // expected
486         }
487         try {
488             m.getColumnMatrix(4);
489             fail("Expecting MatrixIndexException");
490         } catch (MatrixIndexException ex) {
491             // expected
492         }
493     }
494 
495     public void testGetRowVector() {
496         RealMatrix m = createSparseMatrix(subTestData);
497         RealVector mRow0 = new ArrayRealVector(subRow0[0]);
498         RealVector mRow3 = new ArrayRealVector(subRow3[0]);
499         assertEquals("Row0", mRow0, m.getRowVector(0));
500         assertEquals("Row3", mRow3, m.getRowVector(3));
501         try {
502             m.getRowVector(-1);
503             fail("Expecting MatrixIndexException");
504         } catch (MatrixIndexException ex) {
505             // expected
506         }
507         try {
508             m.getRowVector(4);
509             fail("Expecting MatrixIndexException");
510         } catch (MatrixIndexException ex) {
511             // expected
512         }
513     }
514 
515     public void testGetColumnVector() {
516         RealMatrix m = createSparseMatrix(subTestData);
517         RealVector mColumn1 = columnToVector(subColumn1);
518         RealVector mColumn3 = columnToVector(subColumn3);
519         assertEquals("Column1", mColumn1, m.getColumnVector(1));
520         assertEquals("Column3", mColumn3, m.getColumnVector(3));
521         try {
522             m.getColumnVector(-1);
523             fail("Expecting MatrixIndexException");
524         } catch (MatrixIndexException ex) {
525             // expected
526         }
527         try {
528             m.getColumnVector(4);
529             fail("Expecting MatrixIndexException");
530         } catch (MatrixIndexException ex) {
531             // expected
532         }
533     }
534 
535     private RealVector columnToVector(double[][] column) {
536         double[] data = new double[column.length];
537         for (int i = 0; i < data.length; ++i) {
538             data[i] = column[i][0];
539         }
540         return new ArrayRealVector(data, false);
541     }
542 
543     public void testEqualsAndHashCode() {
544         OpenMapRealMatrix m = createSparseMatrix(testData);
545         OpenMapRealMatrix m1 = (OpenMapRealMatrix) m.copy();
546         OpenMapRealMatrix mt = (OpenMapRealMatrix) m.transpose();
547         assertTrue(m.hashCode() != mt.hashCode());
548         assertEquals(m.hashCode(), m1.hashCode());
549         assertEquals(m, m);
550         assertEquals(m, m1);
551         assertFalse(m.equals(null));
552         assertFalse(m.equals(mt));
553         assertFalse(m.equals(createSparseMatrix(bigSingular)));
554     }
555 
556     public void testToString() {
557         OpenMapRealMatrix m = createSparseMatrix(testData);
558         assertEquals("OpenMapRealMatrix{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}", 
559             m.toString());
560         m = new OpenMapRealMatrix(1, 1);
561         assertEquals("OpenMapRealMatrix{{0.0}}", m.toString());
562     }
563 
564     public void testSetSubMatrix() throws Exception {
565         OpenMapRealMatrix m = createSparseMatrix(testData);
566         m.setSubMatrix(detData2, 1, 1);
567         RealMatrix expected = createSparseMatrix(new double[][] {
568                 { 1.0, 2.0, 3.0 }, { 2.0, 1.0, 3.0 }, { 1.0, 2.0, 4.0 } });
569         assertEquals(expected, m);
570 
571         m.setSubMatrix(detData2, 0, 0);
572         expected = createSparseMatrix(new double[][] {
573                 { 1.0, 3.0, 3.0 }, { 2.0, 4.0, 3.0 }, { 1.0, 2.0, 4.0 } });
574         assertEquals(expected, m);
575 
576         m.setSubMatrix(testDataPlus2, 0, 0);
577         expected = createSparseMatrix(new double[][] {
578                 { 3.0, 4.0, 5.0 }, { 4.0, 7.0, 5.0 }, { 3.0, 2.0, 10.0 } });
579         assertEquals(expected, m);
580 
581         // javadoc example
582         OpenMapRealMatrix matrix = 
583             createSparseMatrix(new double[][] { 
584         { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 0, 1, 2 } });
585         matrix.setSubMatrix(new double[][] { { 3, 4 }, { 5, 6 } }, 1, 1);
586         expected = createSparseMatrix(new double[][] {
587                 { 1, 2, 3, 4 }, { 5, 3, 4, 8 }, { 9, 5, 6, 2 } });
588         assertEquals(expected, matrix);
589 
590         // dimension overflow
591         try {
592             m.setSubMatrix(testData, 1, 1);
593             fail("expecting MatrixIndexException");
594         } catch (MatrixIndexException e) {
595             // expected
596         }
597         // dimension underflow
598         try {
599             m.setSubMatrix(testData, -1, 1);
600             fail("expecting MatrixIndexException");
601         } catch (MatrixIndexException e) {
602             // expected
603         }
604         try {
605             m.setSubMatrix(testData, 1, -1);
606             fail("expecting MatrixIndexException");
607         } catch (MatrixIndexException e) {
608             // expected
609         }
610 
611         // null
612         try {
613             m.setSubMatrix(null, 1, 1);
614             fail("expecting NullPointerException");
615         } catch (NullPointerException e) {
616             // expected
617         }
618         try {
619             new OpenMapRealMatrix(0, 0);
620             fail("expecting IllegalArgumentException");
621         } catch (IllegalArgumentException e) {
622             // expected
623         }
624 
625         // ragged
626         try {
627             m.setSubMatrix(new double[][] { { 1 }, { 2, 3 } }, 0, 0);
628             fail("expecting IllegalArgumentException");
629         } catch (IllegalArgumentException e) {
630             // expected
631         }
632 
633         // empty
634         try {
635             m.setSubMatrix(new double[][] { {} }, 0, 0);
636             fail("expecting IllegalArgumentException");
637         } catch (IllegalArgumentException e) {
638             // expected
639         }
640 
641     }
642 
643     public void testSerial()  {
644         OpenMapRealMatrix m = createSparseMatrix(testData);
645         assertEquals(m,TestUtils.serializeAndRecover(m));
646     }
647 
648     // --------------- -----------------Protected methods
649 
650     /** verifies that two matrices are close (1-norm) */
651     protected void assertClose(String msg, RealMatrix m, RealMatrix n,
652             double tolerance) {
653         assertTrue(msg, m.subtract(n).getNorm() < tolerance);
654     }
655 
656     /** verifies that two vectors are close (sup norm) */
657     protected void assertClose(String msg, double[] m, double[] n,
658             double tolerance) {
659         if (m.length != n.length) {
660             fail("vectors not same length");
661         }
662         for (int i = 0; i < m.length; i++) {
663             assertEquals(msg + " " + i + " elements differ", m[i], n[i],
664                     tolerance);
665         }
666     }
667     
668     private OpenMapRealMatrix createSparseMatrix(double[][] data) {
669         OpenMapRealMatrix matrix = new OpenMapRealMatrix(data.length, data[0].length);
670         for (int row = 0; row < data.length; row++) {
671             for (int col = 0; col < data[row].length; col++) {
672                 matrix.setEntry(row, col, data[row][col]);
673             }
674         }
675         return matrix;
676     }
677 
678 
679 }