View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.linear;
23  
24  import org.hipparchus.UnitTestUtils;
25  import org.hipparchus.exception.LocalizedCoreFormats;
26  import org.hipparchus.exception.MathIllegalArgumentException;
27  import org.hipparchus.exception.NullArgumentException;
28  import org.hipparchus.random.RandomGenerator;
29  import org.hipparchus.random.Well1024a;
30  import org.junit.jupiter.api.Test;
31  
32  import static org.junit.jupiter.api.Assertions.assertEquals;
33  import static org.junit.jupiter.api.Assertions.assertFalse;
34  import static org.junit.jupiter.api.Assertions.assertNotEquals;
35  import static org.junit.jupiter.api.Assertions.assertTrue;
36  import static org.junit.jupiter.api.Assertions.fail;
37  
38  /**
39   * Test cases for the {@link OpenMapRealMatrix} class.
40   *
41   */
42  final class SparseRealMatrixTest {
43  
44      // 3 x 3 identity matrix
45      protected double[][] id = { { 1d, 0d, 0d }, { 0d, 1d, 0d }, { 0d, 0d, 1d } };
46      // Test data for group operations
47      protected double[][] testData = { { 1d, 2d, 3d }, { 2d, 5d, 3d },
48              { 1d, 0d, 8d } };
49      protected double[][] testDataLU = { { 2d, 5d, 3d }, { .5d, -2.5d, 6.5d },
50              { 0.5d, 0.2d, .2d } };
51      protected double[][] testDataPlus2 = { { 3d, 4d, 5d }, { 4d, 7d, 5d },
52              { 3d, 2d, 10d } };
53      protected double[][] testDataMinus = { { -1d, -2d, -3d },
54              { -2d, -5d, -3d }, { -1d, 0d, -8d } };
55      protected double[] testDataRow1 = { 1d, 2d, 3d };
56      protected double[] testDataCol3 = { 3d, 3d, 8d };
57      protected double[][] testDataInv = { { -40d, 16d, 9d }, { 13d, -5d, -3d },
58              { 5d, -2d, -1d } };
59      protected double[] preMultTest = { 8, 12, 33 };
60      protected double[][] testData2 = { { 1d, 2d, 3d }, { 2d, 5d, 3d } };
61      protected double[][] testData2T = { { 1d, 2d }, { 2d, 5d }, { 3d, 3d } };
62      protected double[][] testDataPlusInv = { { -39d, 18d, 12d },
63              { 15d, 0d, 0d }, { 6d, -2d, 7d } };
64  
65      // lu decomposition tests
66      protected double[][] luData = { { 2d, 3d, 3d }, { 0d, 5d, 7d }, { 6d, 9d, 8d } };
67      protected double[][] luDataLUDecomposition = { { 6d, 9d, 8d },
68              { 0d, 5d, 7d }, { 0.33333333333333, 0d, 0.33333333333333 } };
69  
70      // singular matrices
71      protected double[][] singular = { { 2d, 3d }, { 2d, 3d } };
72      protected double[][] bigSingular = { { 1d, 2d, 3d, 4d },
73              { 2d, 5d, 3d, 4d }, { 7d, 3d, 256d, 1930d }, { 3d, 7d, 6d, 8d } }; // 4th
74  
75      // row
76      // =
77      // 1st
78      // +
79      // 2nd
80      protected double[][] detData = { { 1d, 2d, 3d }, { 4d, 5d, 6d },
81              { 7d, 8d, 10d } };
82      protected double[][] detData2 = { { 1d, 3d }, { 2d, 4d } };
83  
84      // vectors
85      protected double[] testVector = { 1, 2, 3 };
86      protected double[] testVector2 = { 1, 2, 3, 4 };
87  
88      // submatrix accessor tests
89      protected double[][] subTestData = { { 1, 2, 3, 4 },
90              { 1.5, 2.5, 3.5, 4.5 }, { 2, 4, 6, 8 }, { 4, 5, 6, 7 } };
91  
92      // array selections
93      protected double[][] subRows02Cols13 = { { 2, 4 }, { 4, 8 } };
94      protected double[][] subRows03Cols12 = { { 2, 3 }, { 5, 6 } };
95      protected double[][] subRows03Cols123 = { { 2, 3, 4 }, { 5, 6, 7 } };
96  
97      // effective permutations
98      protected double[][] subRows20Cols123 = { { 4, 6, 8 }, { 2, 3, 4 } };
99      protected double[][] subRows31Cols31 = { { 7, 5 }, { 4.5, 2.5 } };
100 
101     // contiguous ranges
102     protected double[][] subRows01Cols23 = { { 3, 4 }, { 3.5, 4.5 } };
103     protected double[][] subRows23Cols00 = { { 2 }, { 4 } };
104     protected double[][] subRows00Cols33 = { { 4 } };
105 
106     // row matrices
107     protected double[][] subRow0 = { { 1, 2, 3, 4 } };
108     protected double[][] subRow3 = { { 4, 5, 6, 7 } };
109 
110     // column matrices
111     protected double[][] subColumn1 = { { 2 }, { 2.5 }, { 4 }, { 5 } };
112     protected double[][] subColumn3 = { { 4 }, { 4.5 }, { 8 }, { 7 } };
113 
114     // tolerances
115     protected double entryTolerance = 10E-16;
116     protected double normTolerance = 10E-14;
117 
118     /** test dimensions */
119     @Test
120     void testDimensions() {
121         OpenMapRealMatrix m = createSparseMatrix(testData);
122         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
123         assertEquals(3, m.getRowDimension(), "testData row dimension");
124         assertEquals(3, m.getColumnDimension(), "testData column dimension");
125         assertTrue(m.isSquare(), "testData is square");
126         assertEquals(2, m2.getRowDimension(), "testData2 row dimension");
127         assertEquals(3, m2.getColumnDimension(), "testData2 column dimension");
128         assertFalse(m2.isSquare(), "testData2 is not square");
129     }
130 
131     /** test copy functions */
132     @Test
133     void testCopyFunctions() {
134         OpenMapRealMatrix m1 = createSparseMatrix(testData);
135         RealMatrix m2 = m1.copy();
136         assertEquals(m1.getClass(), m2.getClass());
137         assertEquals((m2), m1);
138         OpenMapRealMatrix m3 = createSparseMatrix(testData);
139         RealMatrix m4 = m3.copy();
140         assertEquals(m3.getClass(), m4.getClass());
141         assertEquals((m4), m3);
142     }
143 
144     /** test add */
145     @Test
146     void testAdd() {
147         OpenMapRealMatrix m = createSparseMatrix(testData);
148         OpenMapRealMatrix mInv = createSparseMatrix(testDataInv);
149         OpenMapRealMatrix mDataPlusInv = createSparseMatrix(testDataPlusInv);
150         RealMatrix mPlusMInv = m.add(mInv);
151         for (int row = 0; row < m.getRowDimension(); row++) {
152             for (int col = 0; col < m.getColumnDimension(); col++) {
153                 assertEquals(mDataPlusInv.getEntry(row, col), mPlusMInv.getEntry(row, col),
154                     entryTolerance,
155                     "sum entry entry");
156             }
157         }
158     }
159 
160     /** test add failure */
161     @Test
162     void testAddFail() {
163         OpenMapRealMatrix m = createSparseMatrix(testData);
164         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
165         try {
166             m.add(m2);
167             fail("MathIllegalArgumentException expected");
168         } catch (MathIllegalArgumentException ex) {
169             // ignored
170         }
171     }
172 
173     /** test norm */
174     @Test
175     void testNorm() {
176         OpenMapRealMatrix m = createSparseMatrix(testData);
177         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
178         assertEquals(14d, m.getNorm1(), entryTolerance, "testData norm");
179         assertEquals(7d, m2.getNorm1(), entryTolerance, "testData2 norm");
180         assertEquals(10d, m.getNormInfty(), entryTolerance, "testData norm");
181         assertEquals(10d, m2.getNormInfty(), entryTolerance, "testData2 norm");
182     }
183 
184     /** test m-n = m + -n */
185     @Test
186     void testPlusMinus() {
187         OpenMapRealMatrix m = createSparseMatrix(testData);
188         OpenMapRealMatrix n = createSparseMatrix(testDataInv);
189         customAssertClose("m-n = m + -n", m.subtract(n),
190                           n.scalarMultiply(-1d).add(m), entryTolerance);
191         try {
192             m.subtract(createSparseMatrix(testData2));
193             fail("Expecting illegalArgumentException");
194         } catch (MathIllegalArgumentException ex) {
195             // ignored
196         }
197     }
198 
199     /** test multiply */
200     @Test
201     void testMultiply() {
202         OpenMapRealMatrix m = createSparseMatrix(testData);
203         OpenMapRealMatrix mInv = createSparseMatrix(testDataInv);
204         OpenMapRealMatrix identity = createSparseMatrix(id);
205         OpenMapRealMatrix m2 = createSparseMatrix(testData2);
206         customAssertClose("inverse multiply", m.multiply(mInv), identity,
207                           entryTolerance);
208         customAssertClose("inverse multiply", m.multiply(new BlockRealMatrix(testDataInv)), identity,
209                           entryTolerance);
210         customAssertClose("inverse multiply", mInv.multiply(m), identity,
211                           entryTolerance);
212         customAssertClose("identity multiply", m.multiply(identity), m,
213                           entryTolerance);
214         customAssertClose("identity multiply", identity.multiply(mInv), mInv,
215                           entryTolerance);
216         customAssertClose("identity multiply", m2.multiply(identity), m2,
217                           entryTolerance);
218         try {
219             m.multiply(createSparseMatrix(bigSingular));
220             fail("Expecting illegalArgumentException");
221         } catch (MathIllegalArgumentException ex) {
222             // ignored
223         }
224     }
225 
226     // Additional Test for Array2DRowRealMatrixTest.testMultiply
227 
228     private double[][] d3 = new double[][] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } };
229     private double[][] d4 = new double[][] { { 1 }, { 2 }, { 3 }, { 4 } };
230     private double[][] d5 = new double[][] { { 30 }, { 70 } };
231 
232     @Test
233     void testMultiply2() {
234         RealMatrix m3 = createSparseMatrix(d3);
235         RealMatrix m4 = createSparseMatrix(d4);
236         RealMatrix m5 = createSparseMatrix(d5);
237         customAssertClose("m3*m4=m5", m3.multiply(m4), m5, entryTolerance);
238     }
239 
240     @Test
241     void testMultiplyTransposedSparseRealMatrix() {
242         RandomGenerator randomGenerator = new Well1024a(0x5f31d5645cf821efl);
243         final RealMatrixChangingVisitor randomSetter = new DefaultRealMatrixChangingVisitor() {
244             public double visit(final int row, final int column, final double value) {
245                 return randomGenerator.nextDouble();
246             }
247         };
248         for (int rows = 1; rows <= 64; rows += 7) {
249             for (int cols = 1; cols <= 64; cols += 7) {
250                 final OpenMapRealMatrix a = new OpenMapRealMatrix(rows, cols);
251                 a.walkInOptimizedOrder(randomSetter);
252                 for (int interm = 1; interm <= 64; interm += 7) {
253                     final OpenMapRealMatrix b = new OpenMapRealMatrix(interm, cols);
254                     b.walkInOptimizedOrder(randomSetter);
255                     assertEquals(0.0,
256                                         a.multiplyTransposed(b).subtract(a.multiply(b.transpose())).getNorm1(),
257                                         1.0e-15);
258                 }
259             }
260         }
261     }
262 
263     @Test
264     void testMultiplyTransposedWrongDimensions() {
265         try {
266             new OpenMapRealMatrix(2, 3).multiplyTransposed(new OpenMapRealMatrix(3, 2));
267             fail("an exception should have been thrown");
268         } catch (MathIllegalArgumentException miae) {
269             assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
270             assertEquals(3, ((Integer) miae.getParts()[0]).intValue());
271             assertEquals(2, ((Integer) miae.getParts()[1]).intValue());
272         }
273     }
274 
275     @Test
276     void testTransposeMultiplySparseRealMatrix() {
277         RandomGenerator randomGenerator = new Well1024a(0x5f31d5645cf821efl);
278         final RealMatrixChangingVisitor randomSetter = new DefaultRealMatrixChangingVisitor() {
279             public double visit(final int row, final int column, final double value) {
280                 return randomGenerator.nextDouble();
281             }
282         };
283         for (int rows = 1; rows <= 64; rows += 7) {
284             for (int cols = 1; cols <= 64; cols += 7) {
285                 final OpenMapRealMatrix a = new OpenMapRealMatrix(rows, cols);
286                 a.walkInOptimizedOrder(randomSetter);
287                 for (int interm = 1; interm <= 64; interm += 7) {
288                     final OpenMapRealMatrix b = new OpenMapRealMatrix(rows, interm);
289                     b.walkInOptimizedOrder(randomSetter);
290                     assertEquals(0.0,
291                                         a.transposeMultiply(b).subtract(a.transpose().multiply(b)).getNorm1(),
292                                         4.0e-13);
293                 }
294             }
295         }
296     }
297 
298     @Test
299     void testTransposeMultiplyWrongDimensions() {
300         try {
301             new OpenMapRealMatrix(2, 3).transposeMultiply(new OpenMapRealMatrix(3, 2));
302             fail("an exception should have been thrown");
303         } catch (MathIllegalArgumentException miae) {
304             assertEquals(LocalizedCoreFormats.DIMENSIONS_MISMATCH, miae.getSpecifier());
305             assertEquals(2, ((Integer) miae.getParts()[0]).intValue());
306             assertEquals(3, ((Integer) miae.getParts()[1]).intValue());
307         }
308     }
309 
310     /** test trace */
311     @Test
312     void testTrace() {
313         RealMatrix m = createSparseMatrix(id);
314         assertEquals(3d, m.getTrace(), entryTolerance, "identity trace");
315         m = createSparseMatrix(testData2);
316         try {
317             m.getTrace();
318             fail("Expecting MathIllegalArgumentException");
319         } catch (MathIllegalArgumentException ex) {
320             // ignored
321         }
322     }
323 
324     /** test sclarAdd */
325     @Test
326     void testScalarAdd() {
327         RealMatrix m = createSparseMatrix(testData);
328         customAssertClose("scalar add", createSparseMatrix(testDataPlus2),
329                           m.scalarAdd(2d), entryTolerance);
330     }
331 
332     /** test operate */
333     @Test
334     void testOperate() {
335         RealMatrix m = createSparseMatrix(id);
336         customAssertClose("identity operate", testVector, m.operate(testVector),
337                           entryTolerance);
338         customAssertClose("identity operate", testVector, m.operate(
339                 new ArrayRealVector(testVector)).toArray(), entryTolerance);
340         m = createSparseMatrix(bigSingular);
341         try {
342             m.operate(testVector);
343             fail("Expecting illegalArgumentException");
344         } catch (MathIllegalArgumentException ex) {
345             // ignored
346         }
347     }
348 
349     /** test issue MATH-209 */
350     @Test
351     void testMath209() {
352         RealMatrix a = createSparseMatrix(new double[][] {
353                 { 1, 2 }, { 3, 4 }, { 5, 6 } });
354         double[] b = a.operate(new double[] { 1, 1 });
355         assertEquals(a.getRowDimension(), b.length);
356         assertEquals(3.0, b[0], 1.0e-12);
357         assertEquals(7.0, b[1], 1.0e-12);
358         assertEquals(11.0, b[2], 1.0e-12);
359     }
360 
361     /** test transpose */
362     @Test
363     void testTranspose() {
364         RealMatrix m = createSparseMatrix(testData);
365         RealMatrix mIT = new LUDecomposition(m).getSolver().getInverse().transpose();
366         RealMatrix mTI = new LUDecomposition(m.transpose()).getSolver().getInverse();
367         customAssertClose("inverse-transpose", mIT, mTI, normTolerance);
368         m = createSparseMatrix(testData2);
369         RealMatrix mt = createSparseMatrix(testData2T);
370         customAssertClose("transpose", mt, m.transpose(), normTolerance);
371     }
372 
373     /** test preMultiply by vector */
374     @Test
375     void testPremultiplyVector() {
376         RealMatrix m = createSparseMatrix(testData);
377         customAssertClose("premultiply", m.preMultiply(testVector), preMultTest,
378                           normTolerance);
379         customAssertClose("premultiply", m.preMultiply(
380             new ArrayRealVector(testVector).toArray()), preMultTest, normTolerance);
381         m = createSparseMatrix(bigSingular);
382         try {
383             m.preMultiply(testVector);
384             fail("expecting MathIllegalArgumentException");
385         } catch (MathIllegalArgumentException ex) {
386             // ignored
387         }
388     }
389 
390     @Test
391     void testPremultiply() {
392         RealMatrix m3 = createSparseMatrix(d3);
393         RealMatrix m4 = createSparseMatrix(d4);
394         RealMatrix m5 = createSparseMatrix(d5);
395         customAssertClose("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance);
396 
397         OpenMapRealMatrix m = createSparseMatrix(testData);
398         OpenMapRealMatrix mInv = createSparseMatrix(testDataInv);
399         OpenMapRealMatrix identity = createSparseMatrix(id);
400         customAssertClose("inverse multiply", m.preMultiply(mInv), identity,
401                           entryTolerance);
402         customAssertClose("inverse multiply", mInv.preMultiply(m), identity,
403                           entryTolerance);
404         customAssertClose("identity multiply", m.preMultiply(identity), m,
405                           entryTolerance);
406         customAssertClose("identity multiply", identity.preMultiply(mInv), mInv,
407                           entryTolerance);
408         try {
409             m.preMultiply(createSparseMatrix(bigSingular));
410             fail("Expecting illegalArgumentException");
411         } catch (MathIllegalArgumentException ex) {
412             // ignored
413         }
414     }
415 
416     @Test
417     void testGetVectors() {
418         RealMatrix m = createSparseMatrix(testData);
419         customAssertClose("get row", m.getRow(0), testDataRow1, entryTolerance);
420         customAssertClose("get col", m.getColumn(2), testDataCol3, entryTolerance);
421         try {
422             m.getRow(10);
423             fail("expecting MathIllegalArgumentException");
424         } catch (MathIllegalArgumentException ex) {
425             // ignored
426         }
427         try {
428             m.getColumn(-1);
429             fail("expecting MathIllegalArgumentException");
430         } catch (MathIllegalArgumentException ex) {
431             // ignored
432         }
433     }
434 
435     @Test
436     void testGetEntry() {
437         RealMatrix m = createSparseMatrix(testData);
438         assertEquals(2d, m.getEntry(0, 1), entryTolerance, "get entry");
439         try {
440             m.getEntry(10, 4);
441             fail("Expecting MathIllegalArgumentException");
442         } catch (MathIllegalArgumentException ex) {
443             // expected
444         }
445     }
446 
447     /** test examples in user guide */
448     @Test
449     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 = createSparseMatrix(matrixData);
453         // One more with three rows, two columns
454         double[][] matrixData2 = { { 1d, 2d }, { 2d, 5d }, { 1d, 7d } };
455         RealMatrix n = createSparseMatrix(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 LUDecomposition(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 },
467                 { 4, -3, -5 } };
468         RealMatrix coefficients = createSparseMatrix(coefficientsData);
469         RealVector constants = new ArrayRealVector(new double[]{ 1, -2, 1 }, false);
470         RealVector solution = new LUDecomposition(coefficients).getSolver().solve(constants);
471         final double cst0 = constants.getEntry(0);
472         final double cst1 = constants.getEntry(1);
473         final double cst2 = constants.getEntry(2);
474         final double sol0 = solution.getEntry(0);
475         final double sol1 = solution.getEntry(1);
476         final double sol2 = solution.getEntry(2);
477         assertEquals(2 * sol0 + 3 * sol1 - 2 * sol2, cst0, 1E-12);
478         assertEquals(-1 * sol0 + 7 * sol1 + 6 * sol2, cst1, 1E-12);
479         assertEquals(4 * sol0 - 3 * sol1 - 5 * sol2, cst2, 1E-12);
480 
481     }
482 
483     // test submatrix accessors
484     @Test
485     void testSubMatrix() {
486         RealMatrix m = createSparseMatrix(subTestData);
487         RealMatrix mRows23Cols00 = createSparseMatrix(subRows23Cols00);
488         RealMatrix mRows00Cols33 = createSparseMatrix(subRows00Cols33);
489         RealMatrix mRows01Cols23 = createSparseMatrix(subRows01Cols23);
490         RealMatrix mRows02Cols13 = createSparseMatrix(subRows02Cols13);
491         RealMatrix mRows03Cols12 = createSparseMatrix(subRows03Cols12);
492         RealMatrix mRows03Cols123 = createSparseMatrix(subRows03Cols123);
493         RealMatrix mRows20Cols123 = createSparseMatrix(subRows20Cols123);
494         RealMatrix mRows31Cols31 = createSparseMatrix(subRows31Cols31);
495         assertEquals(mRows23Cols00, m.getSubMatrix(2, 3, 0, 0), "Rows23Cols00");
496         assertEquals(mRows00Cols33, m.getSubMatrix(0, 0, 3, 3), "Rows00Cols33");
497         assertEquals(mRows01Cols23, m.getSubMatrix(0, 1, 2, 3), "Rows01Cols23");
498         assertEquals(mRows02Cols13,
499             m.getSubMatrix(new int[] { 0, 2 }, new int[] { 1, 3 }),
500             "Rows02Cols13");
501         assertEquals(mRows03Cols12,
502             m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2 }),
503             "Rows03Cols12");
504         assertEquals(mRows03Cols123,
505             m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2, 3 }),
506             "Rows03Cols123");
507         assertEquals(mRows20Cols123,
508             m.getSubMatrix(new int[] { 2, 0 }, new int[] { 1, 2, 3 }),
509             "Rows20Cols123");
510         assertEquals(mRows31Cols31,
511             m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 }),
512             "Rows31Cols31");
513         assertEquals(mRows31Cols31,
514             m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 }),
515             "Rows31Cols31");
516 
517         try {
518             m.getSubMatrix(1, 0, 2, 4);
519             fail("Expecting MathIllegalArgumentException");
520         } catch (MathIllegalArgumentException ex) {
521             // expected
522         }
523         try {
524             m.getSubMatrix(-1, 1, 2, 2);
525             fail("Expecting MathIllegalArgumentException");
526         } catch (MathIllegalArgumentException ex) {
527             // expected
528         }
529         try {
530             m.getSubMatrix(1, 0, 2, 2);
531             fail("Expecting MathIllegalArgumentException");
532         } catch (MathIllegalArgumentException ex) {
533             // expected
534         }
535         try {
536             m.getSubMatrix(1, 0, 2, 4);
537             fail("Expecting MathIllegalArgumentException");
538         } catch (MathIllegalArgumentException ex) {
539             // expected
540         }
541         try {
542             m.getSubMatrix(new int[] {}, new int[] { 0 });
543             fail("Expecting MathIllegalArgumentException");
544         } catch (MathIllegalArgumentException ex) {
545             // expected
546         }
547         try {
548             m.getSubMatrix(new int[] { 0 }, new int[] { 4 });
549             fail("Expecting MathIllegalArgumentException");
550         } catch (MathIllegalArgumentException ex) {
551             // expected
552         }
553     }
554 
555     @Test
556     void testGetRowMatrix() {
557         RealMatrix m = createSparseMatrix(subTestData);
558         RealMatrix mRow0 = createSparseMatrix(subRow0);
559         RealMatrix mRow3 = createSparseMatrix(subRow3);
560         assertEquals(mRow0, m.getRowMatrix(0), "Row0");
561         assertEquals(mRow3, m.getRowMatrix(3), "Row3");
562         try {
563             m.getRowMatrix(-1);
564             fail("Expecting MathIllegalArgumentException");
565         } catch (MathIllegalArgumentException ex) {
566             // expected
567         }
568         try {
569             m.getRowMatrix(4);
570             fail("Expecting MathIllegalArgumentException");
571         } catch (MathIllegalArgumentException ex) {
572             // expected
573         }
574     }
575 
576     @Test
577     void testGetColumnMatrix() {
578         RealMatrix m = createSparseMatrix(subTestData);
579         RealMatrix mColumn1 = createSparseMatrix(subColumn1);
580         RealMatrix mColumn3 = createSparseMatrix(subColumn3);
581         assertEquals(mColumn1, m.getColumnMatrix(1), "Column1");
582         assertEquals(mColumn3, m.getColumnMatrix(3), "Column3");
583         try {
584             m.getColumnMatrix(-1);
585             fail("Expecting MathIllegalArgumentException");
586         } catch (MathIllegalArgumentException ex) {
587             // expected
588         }
589         try {
590             m.getColumnMatrix(4);
591             fail("Expecting MathIllegalArgumentException");
592         } catch (MathIllegalArgumentException ex) {
593             // expected
594         }
595     }
596 
597     @Test
598     void testGetRowVector() {
599         RealMatrix m = createSparseMatrix(subTestData);
600         RealVector mRow0 = new ArrayRealVector(subRow0[0]);
601         RealVector mRow3 = new ArrayRealVector(subRow3[0]);
602         assertEquals(mRow0, m.getRowVector(0), "Row0");
603         assertEquals(mRow3, m.getRowVector(3), "Row3");
604         try {
605             m.getRowVector(-1);
606             fail("Expecting MathIllegalArgumentException");
607         } catch (MathIllegalArgumentException ex) {
608             // expected
609         }
610         try {
611             m.getRowVector(4);
612             fail("Expecting MathIllegalArgumentException");
613         } catch (MathIllegalArgumentException ex) {
614             // expected
615         }
616     }
617 
618     @Test
619     void testGetColumnVector() {
620         RealMatrix m = createSparseMatrix(subTestData);
621         RealVector mColumn1 = columnToVector(subColumn1);
622         RealVector mColumn3 = columnToVector(subColumn3);
623         assertEquals(mColumn1, m.getColumnVector(1), "Column1");
624         assertEquals(mColumn3, m.getColumnVector(3), "Column3");
625         try {
626             m.getColumnVector(-1);
627             fail("Expecting MathIllegalArgumentException");
628         } catch (MathIllegalArgumentException ex) {
629             // expected
630         }
631         try {
632             m.getColumnVector(4);
633             fail("Expecting MathIllegalArgumentException");
634         } catch (MathIllegalArgumentException ex) {
635             // expected
636         }
637     }
638 
639     private RealVector columnToVector(double[][] column) {
640         double[] data = new double[column.length];
641         for (int i = 0; i < data.length; ++i) {
642             data[i] = column[i][0];
643         }
644         return new ArrayRealVector(data, false);
645     }
646 
647     @Test
648     void testEqualsAndHashCode() {
649         OpenMapRealMatrix m = createSparseMatrix(testData);
650         OpenMapRealMatrix m1 = m.copy();
651         OpenMapRealMatrix mt = (OpenMapRealMatrix) m.transpose();
652         assertTrue(m.hashCode() != mt.hashCode());
653         assertEquals(m.hashCode(), m1.hashCode());
654         assertEquals(m, m);
655         assertEquals(m, m1);
656         assertNotEquals(null, m);
657         assertNotEquals(m, mt);
658         assertNotEquals(m, createSparseMatrix(bigSingular));
659     }
660 
661     @Test
662     void testToString() {
663         OpenMapRealMatrix m = createSparseMatrix(testData);
664         assertEquals("OpenMapRealMatrix{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}",
665             m.toString());
666         m = new OpenMapRealMatrix(1, 1);
667         assertEquals("OpenMapRealMatrix{{0.0}}", m.toString());
668     }
669 
670     @Test
671     void testSetSubMatrix() {
672         OpenMapRealMatrix m = createSparseMatrix(testData);
673         m.setSubMatrix(detData2, 1, 1);
674         RealMatrix expected = createSparseMatrix(new double[][] {
675                 { 1.0, 2.0, 3.0 }, { 2.0, 1.0, 3.0 }, { 1.0, 2.0, 4.0 } });
676         assertEquals(expected, m);
677 
678         m.setSubMatrix(detData2, 0, 0);
679         expected = createSparseMatrix(new double[][] {
680                 { 1.0, 3.0, 3.0 }, { 2.0, 4.0, 3.0 }, { 1.0, 2.0, 4.0 } });
681         assertEquals(expected, m);
682 
683         m.setSubMatrix(testDataPlus2, 0, 0);
684         expected = createSparseMatrix(new double[][] {
685                 { 3.0, 4.0, 5.0 }, { 4.0, 7.0, 5.0 }, { 3.0, 2.0, 10.0 } });
686         assertEquals(expected, m);
687 
688         // javadoc example
689         OpenMapRealMatrix matrix =
690             createSparseMatrix(new double[][] {
691         { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 0, 1, 2 } });
692         matrix.setSubMatrix(new double[][] { { 3, 4 }, { 5, 6 } }, 1, 1);
693         expected = createSparseMatrix(new double[][] {
694                 { 1, 2, 3, 4 }, { 5, 3, 4, 8 }, { 9, 5, 6, 2 } });
695         assertEquals(expected, matrix);
696 
697         // dimension overflow
698         try {
699             m.setSubMatrix(testData, 1, 1);
700             fail("expecting MathIllegalArgumentException");
701         } catch (MathIllegalArgumentException e) {
702             // expected
703         }
704         // dimension underflow
705         try {
706             m.setSubMatrix(testData, -1, 1);
707             fail("expecting MathIllegalArgumentException");
708         } catch (MathIllegalArgumentException e) {
709             // expected
710         }
711         try {
712             m.setSubMatrix(testData, 1, -1);
713             fail("expecting MathIllegalArgumentException");
714         } catch (MathIllegalArgumentException e) {
715             // expected
716         }
717 
718         // null
719         try {
720             m.setSubMatrix(null, 1, 1);
721             fail("expecting NullArgumentException");
722         } catch (NullArgumentException e) {
723             // expected
724         }
725         try {
726             new OpenMapRealMatrix(0, 0);
727             fail("expecting MathIllegalArgumentException");
728         } catch (MathIllegalArgumentException e) {
729             // expected
730         }
731 
732         // ragged
733         try {
734             m.setSubMatrix(new double[][] { { 1 }, { 2, 3 } }, 0, 0);
735             fail("expecting MathIllegalArgumentException");
736         } catch (MathIllegalArgumentException e) {
737             // expected
738         }
739 
740         // empty
741         try {
742             m.setSubMatrix(new double[][] { {} }, 0, 0);
743             fail("expecting MathIllegalArgumentException");
744         } catch (MathIllegalArgumentException e) {
745             // expected
746         }
747 
748     }
749 
750     @Test
751     void testSerial()  {
752         OpenMapRealMatrix m = createSparseMatrix(testData);
753         assertEquals(m,UnitTestUtils.serializeAndRecover(m));
754     }
755 
756     // --------------- -----------------Protected methods
757 
758     /** verifies that two matrices are close (1-norm) */
759     protected void customAssertClose(String msg, RealMatrix m, RealMatrix n,
760                                      double tolerance) {
761         assertTrue(m.subtract(n).getNorm1() < tolerance, msg);
762     }
763 
764     /** verifies that two vectors are close (sup norm) */
765     protected void customAssertClose(String msg, double[] m, double[] n,
766                                      double tolerance) {
767         if (m.length != n.length) {
768             fail("vectors not same length");
769         }
770         for (int i = 0; i < m.length; i++) {
771             assertEquals(m[i], n[i],
772                     tolerance,
773                     msg + " " + i + " elements differ");
774         }
775     }
776 
777     private OpenMapRealMatrix createSparseMatrix(double[][] data) {
778         OpenMapRealMatrix matrix = new OpenMapRealMatrix(data.length, data[0].length);
779         for (int row = 0; row < data.length; row++) {
780             for (int col = 0; col < data[row].length; col++) {
781                 matrix.setEntry(row, col, data[row][col]);
782             }
783         }
784         return matrix;
785     }
786 }