001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.math.linear;
018    
019    import junit.framework.Test;
020    import junit.framework.TestCase;
021    import junit.framework.TestSuite;
022    
023    import org.apache.commons.math.TestUtils;
024    
025    /**
026     * Test cases for the {@link OpenMapRealMatrix} class.
027     * 
028     * @version $Revision: 790243 $ $Date: 2008-11-07 06:48:13 -0800 (Fri, 07 Nov
029     *          2008) $
030     */
031    public final class SparseRealMatrixTest extends TestCase {
032    
033        // 3 x 3 identity matrix
034        protected double[][] id = { { 1d, 0d, 0d }, { 0d, 1d, 0d }, { 0d, 0d, 1d } };
035        // Test data for group operations
036        protected double[][] testData = { { 1d, 2d, 3d }, { 2d, 5d, 3d },
037                { 1d, 0d, 8d } };
038        protected double[][] testDataLU = { { 2d, 5d, 3d }, { .5d, -2.5d, 6.5d },
039                { 0.5d, 0.2d, .2d } };
040        protected double[][] testDataPlus2 = { { 3d, 4d, 5d }, { 4d, 7d, 5d },
041                { 3d, 2d, 10d } };
042        protected double[][] testDataMinus = { { -1d, -2d, -3d },
043                { -2d, -5d, -3d }, { -1d, 0d, -8d } };
044        protected double[] testDataRow1 = { 1d, 2d, 3d };
045        protected double[] testDataCol3 = { 3d, 3d, 8d };
046        protected double[][] testDataInv = { { -40d, 16d, 9d }, { 13d, -5d, -3d },
047                { 5d, -2d, -1d } };
048        protected double[] preMultTest = { 8, 12, 33 };
049        protected double[][] testData2 = { { 1d, 2d, 3d }, { 2d, 5d, 3d } };
050        protected double[][] testData2T = { { 1d, 2d }, { 2d, 5d }, { 3d, 3d } };
051        protected double[][] testDataPlusInv = { { -39d, 18d, 12d },
052                { 15d, 0d, 0d }, { 6d, -2d, 7d } };
053    
054        // lu decomposition tests
055        protected double[][] luData = { { 2d, 3d, 3d }, { 0d, 5d, 7d }, { 6d, 9d, 8d } };
056        protected double[][] luDataLUDecomposition = { { 6d, 9d, 8d },
057                { 0d, 5d, 7d }, { 0.33333333333333, 0d, 0.33333333333333 } };
058    
059        // singular matrices
060        protected double[][] singular = { { 2d, 3d }, { 2d, 3d } };
061        protected double[][] bigSingular = { { 1d, 2d, 3d, 4d },
062                { 2d, 5d, 3d, 4d }, { 7d, 3d, 256d, 1930d }, { 3d, 7d, 6d, 8d } }; // 4th
063    
064        // row
065        // =
066        // 1st
067        // +
068        // 2nd
069        protected double[][] detData = { { 1d, 2d, 3d }, { 4d, 5d, 6d },
070                { 7d, 8d, 10d } };
071        protected double[][] detData2 = { { 1d, 3d }, { 2d, 4d } };
072    
073        // vectors
074        protected double[] testVector = { 1, 2, 3 };
075        protected double[] testVector2 = { 1, 2, 3, 4 };
076    
077        // submatrix accessor tests
078        protected double[][] subTestData = { { 1, 2, 3, 4 },
079                { 1.5, 2.5, 3.5, 4.5 }, { 2, 4, 6, 8 }, { 4, 5, 6, 7 } };
080    
081        // array selections
082        protected double[][] subRows02Cols13 = { { 2, 4 }, { 4, 8 } };
083        protected double[][] subRows03Cols12 = { { 2, 3 }, { 5, 6 } };
084        protected double[][] subRows03Cols123 = { { 2, 3, 4 }, { 5, 6, 7 } };
085    
086        // effective permutations
087        protected double[][] subRows20Cols123 = { { 4, 6, 8 }, { 2, 3, 4 } };
088        protected double[][] subRows31Cols31 = { { 7, 5 }, { 4.5, 2.5 } };
089    
090        // contiguous ranges
091        protected double[][] subRows01Cols23 = { { 3, 4 }, { 3.5, 4.5 } };
092        protected double[][] subRows23Cols00 = { { 2 }, { 4 } };
093        protected double[][] subRows00Cols33 = { { 4 } };
094    
095        // row matrices
096        protected double[][] subRow0 = { { 1, 2, 3, 4 } };
097        protected double[][] subRow3 = { { 4, 5, 6, 7 } };
098    
099        // 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    }