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 RealMatrixImpl} class.
027     *
028     * @version $Revision: 783702 $ $Date: 2009-06-11 04:54:02 -0400 (Thu, 11 Jun 2009) $
029     */
030    @Deprecated
031    public final class RealMatrixImplTest extends TestCase {
032        
033        // 3 x 3 identity matrix
034        protected double[][] id = { {1d,0d,0d}, {0d,1d,0d}, {0d,0d,1d} };
035        
036        // Test data for group operations
037        protected double[][] testData = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} };
038        protected double[][] testDataLU = {{2d, 5d, 3d}, {.5d, -2.5d, 6.5d}, {0.5d, 0.2d, .2d}};
039        protected double[][] testDataPlus2 = { {3d,4d,5d}, {4d,7d,5d}, {3d,2d,10d} };
040        protected double[][] testDataMinus = { {-1d,-2d,-3d}, {-2d,-5d,-3d}, 
041           {-1d,0d,-8d} };
042        protected double[] testDataRow1 = {1d,2d,3d};
043        protected double[] testDataCol3 = {3d,3d,8d};
044        protected double[][] testDataInv = 
045            { {-40d,16d,9d}, {13d,-5d,-3d}, {5d,-2d,-1d} };
046        protected double[] preMultTest = {8,12,33};
047        protected double[][] testData2 ={ {1d,2d,3d}, {2d,5d,3d}};
048        protected double[][] testData2T = { {1d,2d}, {2d,5d}, {3d,3d}};
049        protected double[][] testDataPlusInv = 
050            { {-39d,18d,12d}, {15d,0d,0d}, {6d,-2d,7d} };
051        
052        // lu decomposition tests
053        protected double[][] luData = { {2d,3d,3d}, {0d,5d,7d}, {6d,9d,8d} };
054        protected double[][] luDataLUDecomposition = { {6d,9d,8d}, {0d,5d,7d},
055                {0.33333333333333,0d,0.33333333333333} };
056        
057        // singular matrices
058        protected double[][] singular = { {2d,3d}, {2d,3d} };
059        protected double[][] bigSingular = {{1d,2d,3d,4d}, {2d,5d,3d,4d},
060            {7d,3d,256d,1930d}, {3d,7d,6d,8d}}; // 4th row = 1st + 2nd
061        protected double[][] detData = { {1d,2d,3d}, {4d,5d,6d}, {7d,8d,10d} };
062        protected double[][] detData2 = { {1d, 3d}, {2d, 4d}};
063        
064        // vectors
065        protected double[] testVector = {1,2,3};
066        protected double[] testVector2 = {1,2,3,4};
067        
068        // submatrix accessor tests
069        protected double[][] subTestData = {{1, 2, 3, 4}, {1.5, 2.5, 3.5, 4.5},
070                {2, 4, 6, 8}, {4, 5, 6, 7}}; 
071        // array selections
072        protected double[][] subRows02Cols13 = { {2, 4}, {4, 8}};
073        protected double[][] subRows03Cols12 = { {2, 3}, {5, 6}};
074        protected double[][] subRows03Cols123 = { {2, 3, 4} , {5, 6, 7}};
075        // effective permutations
076        protected double[][] subRows20Cols123 = { {4, 6, 8} , {2, 3, 4}};
077        protected double[][] subRows31Cols31 = {{7, 5}, {4.5, 2.5}};
078        // contiguous ranges
079        protected double[][] subRows01Cols23 = {{3,4} , {3.5, 4.5}};
080        protected double[][] subRows23Cols00 = {{2} , {4}};
081        protected double[][] subRows00Cols33 = {{4}};
082        // row matrices
083        protected double[][] subRow0 = {{1,2,3,4}};
084        protected double[][] subRow3 = {{4,5,6,7}};
085        // column matrices
086        protected double[][] subColumn1 = {{2}, {2.5}, {4}, {5}};
087        protected double[][] subColumn3 = {{4}, {4.5}, {8}, {7}};
088        
089        // tolerances
090        protected double entryTolerance = 10E-16;
091        protected double normTolerance = 10E-14;
092        
093        public RealMatrixImplTest(String name) {
094            super(name);
095        }
096        
097        public static Test suite() {
098            TestSuite suite = new TestSuite(RealMatrixImplTest.class);
099            suite.setName("RealMatrixImpl Tests");
100            return suite;
101        }
102        
103        /** test dimensions */
104        public void testDimensions() {
105            RealMatrixImpl m = new RealMatrixImpl(testData);
106            RealMatrixImpl m2 = new RealMatrixImpl(testData2);
107            assertEquals("testData row dimension",3,m.getRowDimension());
108            assertEquals("testData column dimension",3,m.getColumnDimension());
109            assertTrue("testData is square",m.isSquare());
110            assertEquals("testData2 row dimension",m2.getRowDimension(),2);
111            assertEquals("testData2 column dimension",m2.getColumnDimension(),3);
112            assertTrue("testData2 is not square",!m2.isSquare());
113        } 
114        
115        /** test copy functions */
116        public void testCopyFunctions() {
117            RealMatrixImpl m1 = new RealMatrixImpl(testData);
118            RealMatrixImpl m2 = new RealMatrixImpl(m1.getData());
119            assertEquals(m2,m1);
120            RealMatrixImpl m3 = new RealMatrixImpl(testData);
121            RealMatrixImpl m4 = new RealMatrixImpl(m3.getData(), false);
122            assertEquals(m4,m3);
123        }           
124        
125        /** test add */
126        public void testAdd() {
127            RealMatrixImpl m = new RealMatrixImpl(testData);
128            RealMatrixImpl mInv = new RealMatrixImpl(testDataInv);
129            RealMatrix mPlusMInv = m.add(mInv);
130            double[][] sumEntries = mPlusMInv.getData();
131            for (int row = 0; row < m.getRowDimension(); row++) {
132                for (int col = 0; col < m.getColumnDimension(); col++) {
133                    assertEquals("sum entry entry",
134                        testDataPlusInv[row][col],sumEntries[row][col],
135                            entryTolerance);
136                }
137            }    
138        }
139        
140        /** test add failure */
141        public void testAddFail() {
142            RealMatrixImpl m = new RealMatrixImpl(testData);
143            RealMatrixImpl m2 = new RealMatrixImpl(testData2);
144            try {
145                m.add(m2);
146                fail("IllegalArgumentException expected");
147            } catch (IllegalArgumentException ex) {
148                // ignored
149            }
150        }
151        
152        /** test norm */
153        public void testNorm() {
154            RealMatrixImpl m = new RealMatrixImpl(testData);
155            RealMatrixImpl m2 = new RealMatrixImpl(testData2);
156            assertEquals("testData norm",14d,m.getNorm(),entryTolerance);
157            assertEquals("testData2 norm",7d,m2.getNorm(),entryTolerance);
158        }
159        
160        /** test Frobenius norm */
161        public void testFrobeniusNorm() {
162            RealMatrixImpl m = new RealMatrixImpl(testData);
163            RealMatrixImpl m2 = new RealMatrixImpl(testData2);
164            assertEquals("testData Frobenius norm", Math.sqrt(117.0), m.getFrobeniusNorm(), entryTolerance);
165            assertEquals("testData2 Frobenius norm", Math.sqrt(52.0), m2.getFrobeniusNorm(), entryTolerance);
166        }
167        
168         /** test m-n = m + -n */
169        public void testPlusMinus() {
170            RealMatrixImpl m = new RealMatrixImpl(testData);
171            RealMatrixImpl m2 = new RealMatrixImpl(testDataInv);
172            TestUtils.assertEquals("m-n = m + -n",m.subtract(m2),
173                m2.scalarMultiply(-1d).add(m),entryTolerance);        
174            try {
175                m.subtract(new RealMatrixImpl(testData2));
176                fail("Expecting illegalArgumentException");
177            } catch (IllegalArgumentException ex) {
178                // ignored
179            }      
180        }
181       
182        /** test multiply */
183         public void testMultiply() {
184            RealMatrixImpl m = new RealMatrixImpl(testData);
185            RealMatrixImpl mInv = new RealMatrixImpl(testDataInv);
186            RealMatrixImpl identity = new RealMatrixImpl(id);
187            RealMatrixImpl m2 = new RealMatrixImpl(testData2);
188            TestUtils.assertEquals("inverse multiply",m.multiply(mInv),
189                identity,entryTolerance);
190            TestUtils.assertEquals("inverse multiply",mInv.multiply(m),
191                identity,entryTolerance);
192            TestUtils.assertEquals("identity multiply",m.multiply(identity),
193                m,entryTolerance);
194            TestUtils.assertEquals("identity multiply",identity.multiply(mInv),
195                mInv,entryTolerance);
196            TestUtils.assertEquals("identity multiply",m2.multiply(identity),
197                m2,entryTolerance); 
198            try {
199                m.multiply(new RealMatrixImpl(bigSingular));
200                fail("Expecting illegalArgumentException");
201            } catch (IllegalArgumentException ex) {
202                // ignored
203            }      
204        }   
205        
206        //Additional Test for RealMatrixImplTest.testMultiply
207    
208        private double[][] d3 = new double[][] {{1,2,3,4},{5,6,7,8}};
209        private double[][] d4 = new double[][] {{1},{2},{3},{4}};
210        private double[][] d5 = new double[][] {{30},{70}};
211         
212        public void testMultiply2() { 
213           RealMatrix m3 = new RealMatrixImpl(d3);   
214           RealMatrix m4 = new RealMatrixImpl(d4);
215           RealMatrix m5 = new RealMatrixImpl(d5);
216           TestUtils.assertEquals("m3*m4=m5", m3.multiply(m4), m5, entryTolerance);
217       }  
218            
219        /** test trace */
220        public void testTrace() {
221            RealMatrix m = new RealMatrixImpl(id);
222            assertEquals("identity trace",3d,m.getTrace(),entryTolerance);
223            m = new RealMatrixImpl(testData2);
224            try {
225                m.getTrace();
226                fail("Expecting NonSquareMatrixException");
227            } catch (NonSquareMatrixException ex) {
228                // ignored
229            }      
230        }
231        
232        /** test sclarAdd */
233        public void testScalarAdd() {
234            RealMatrix m = new RealMatrixImpl(testData);
235            TestUtils.assertEquals("scalar add",new RealMatrixImpl(testDataPlus2),
236                m.scalarAdd(2d),entryTolerance);
237        }
238                        
239        /** test operate */
240        public void testOperate() {
241            RealMatrix m = new RealMatrixImpl(id);
242            TestUtils.assertEquals("identity operate", testVector,
243                        m.operate(testVector), entryTolerance);
244            TestUtils.assertEquals("identity operate", testVector,
245                        m.operate(new ArrayRealVector(testVector)).getData(), entryTolerance);
246            m = new RealMatrixImpl(bigSingular);
247            try {
248                m.operate(testVector);
249                fail("Expecting illegalArgumentException");
250            } catch (IllegalArgumentException ex) {
251                // ignored
252            }      
253        }
254    
255        /** test issue MATH-209 */
256        public void testMath209() {
257            RealMatrix a = new RealMatrixImpl(new double[][] {
258                    { 1, 2 }, { 3, 4 }, { 5, 6 }
259            }, false);
260            double[] b = a.operate(new double[] { 1, 1 });
261            assertEquals(a.getRowDimension(), b.length);
262            assertEquals( 3.0, b[0], 1.0e-12);
263            assertEquals( 7.0, b[1], 1.0e-12);
264            assertEquals(11.0, b[2], 1.0e-12);
265        }
266        
267        /** test transpose */
268        public void testTranspose() {
269            RealMatrix m = new RealMatrixImpl(testData); 
270            RealMatrix mIT = new LUDecompositionImpl(m).getSolver().getInverse().transpose();
271            RealMatrix mTI = new LUDecompositionImpl(m.transpose()).getSolver().getInverse();
272            TestUtils.assertEquals("inverse-transpose", mIT, mTI, normTolerance);
273            m = new RealMatrixImpl(testData2);
274            RealMatrix mt = new RealMatrixImpl(testData2T);
275            TestUtils.assertEquals("transpose",mt,m.transpose(),normTolerance);
276        }
277        
278        /** test preMultiply by vector */
279        public void testPremultiplyVector() {
280            RealMatrix m = new RealMatrixImpl(testData);
281            TestUtils.assertEquals("premultiply", m.preMultiply(testVector),
282                        preMultTest, normTolerance);
283            TestUtils.assertEquals("premultiply", m.preMultiply(new ArrayRealVector(testVector).getData()),
284                        preMultTest, normTolerance);
285            m = new RealMatrixImpl(bigSingular);
286            try {
287                m.preMultiply(testVector);
288                fail("expecting IllegalArgumentException");
289            } catch (IllegalArgumentException ex) {
290                // ignored
291            }
292        }
293        
294        public void testPremultiply() {
295            RealMatrix m3 = new RealMatrixImpl(d3);   
296            RealMatrix m4 = new RealMatrixImpl(d4);
297            RealMatrix m5 = new RealMatrixImpl(d5);
298            TestUtils.assertEquals("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance);
299            
300            RealMatrixImpl m = new RealMatrixImpl(testData);
301            RealMatrixImpl mInv = new RealMatrixImpl(testDataInv);
302            RealMatrixImpl identity = new RealMatrixImpl(id);
303            TestUtils.assertEquals("inverse multiply",m.preMultiply(mInv),
304                    identity,entryTolerance);
305            TestUtils.assertEquals("inverse multiply",mInv.preMultiply(m),
306                    identity,entryTolerance);
307            TestUtils.assertEquals("identity multiply",m.preMultiply(identity),
308                    m,entryTolerance);
309            TestUtils.assertEquals("identity multiply",identity.preMultiply(mInv),
310                    mInv,entryTolerance);
311            try {
312                m.preMultiply(new RealMatrixImpl(bigSingular));
313                fail("Expecting illegalArgumentException");
314            } catch (IllegalArgumentException ex) {
315                // ignored
316            }      
317        }
318        
319        public void testGetVectors() {
320            RealMatrix m = new RealMatrixImpl(testData);
321            TestUtils.assertEquals("get row",m.getRow(0),testDataRow1,entryTolerance);
322            TestUtils.assertEquals("get col",m.getColumn(2),testDataCol3,entryTolerance);
323            try {
324                m.getRow(10);
325                fail("expecting MatrixIndexException");
326            } catch (MatrixIndexException ex) {
327                // ignored
328            }
329            try {
330                m.getColumn(-1);
331                fail("expecting MatrixIndexException");
332            } catch (MatrixIndexException ex) {
333                // ignored
334            }
335        }
336        
337        public void testGetEntry() {
338            RealMatrix m = new RealMatrixImpl(testData);
339            assertEquals("get entry",m.getEntry(0,1),2d,entryTolerance);
340            try {
341                m.getEntry(10, 4);
342                fail ("Expecting MatrixIndexException");
343            } catch (MatrixIndexException ex) {
344                // expected
345            }
346        }
347            
348        /** test examples in user guide */
349        public void testExamples() {
350            // Create a real matrix with two rows and three columns
351            double[][] matrixData = { {1d,2d,3d}, {2d,5d,3d}};
352            RealMatrix m = new RealMatrixImpl(matrixData);
353            // One more with three rows, two columns
354            double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}};
355            RealMatrix n = new RealMatrixImpl(matrixData2);
356            // Now multiply m by n
357            RealMatrix p = m.multiply(n);
358            assertEquals(2, p.getRowDimension());
359            assertEquals(2, p.getColumnDimension());
360            // Invert p
361            RealMatrix pInverse = new LUDecompositionImpl(p).getSolver().getInverse(); 
362            assertEquals(2, pInverse.getRowDimension());
363            assertEquals(2, pInverse.getColumnDimension());
364            
365            // Solve example
366            double[][] coefficientsData = {{2, 3, -2}, {-1, 7, 6}, {4, -3, -5}};
367            RealMatrix coefficients = new RealMatrixImpl(coefficientsData);
368            double[] constants = {1, -2, 1};
369            double[] solution = new LUDecompositionImpl(coefficients).getSolver().solve(constants);
370            assertEquals(2 * solution[0] + 3 * solution[1] -2 * solution[2], constants[0], 1E-12);
371            assertEquals(-1 * solution[0] + 7 * solution[1] + 6 * solution[2], constants[1], 1E-12);
372            assertEquals(4 * solution[0] - 3 * solution[1] -5 * solution[2], constants[2], 1E-12);   
373            
374        }
375        
376        // test submatrix accessors
377        public void testGetSubMatrix() {
378            RealMatrix m = new RealMatrixImpl(subTestData);
379            checkGetSubMatrix(m, subRows23Cols00,  2 , 3 , 0, 0, false);
380            checkGetSubMatrix(m, subRows00Cols33,  0 , 0 , 3, 3, false);
381            checkGetSubMatrix(m, subRows01Cols23,  0 , 1 , 2, 3, false);   
382            checkGetSubMatrix(m, subRows02Cols13,  new int[] { 0, 2 }, new int[] { 1, 3 },    false);  
383            checkGetSubMatrix(m, subRows03Cols12,  new int[] { 0, 3 }, new int[] { 1, 2 },    false);  
384            checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false); 
385            checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false); 
386            checkGetSubMatrix(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false); 
387            checkGetSubMatrix(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false); 
388            checkGetSubMatrix(m, null,  1, 0, 2, 4, true);
389            checkGetSubMatrix(m, null, -1, 1, 2, 2, true);
390            checkGetSubMatrix(m, null,  1, 0, 2, 2, true);
391            checkGetSubMatrix(m, null,  1, 0, 2, 4, true);
392            checkGetSubMatrix(m, null, new int[] {},    new int[] { 0 }, true);
393            checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }, true);
394        }
395    
396        private void checkGetSubMatrix(RealMatrix m, double[][] reference,
397                                       int startRow, int endRow, int startColumn, int endColumn,
398                                       boolean mustFail) {
399            try {
400                RealMatrix sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn);
401                assertEquals(new RealMatrixImpl(reference), sub);
402                if (mustFail) {
403                    fail("Expecting MatrixIndexException");
404                }
405            } catch (MatrixIndexException e) {
406                if (!mustFail) {
407                    throw e;
408                }
409            }
410        }
411        
412        private void checkGetSubMatrix(RealMatrix m, double[][] reference,
413                                       int[] selectedRows, int[] selectedColumns,
414                                       boolean mustFail) {
415            try {
416                RealMatrix sub = m.getSubMatrix(selectedRows, selectedColumns);
417                assertEquals(new RealMatrixImpl(reference), sub);
418                if (mustFail) {
419                    fail("Expecting MatrixIndexException");
420                }
421            } catch (MatrixIndexException e) {
422                if (!mustFail) {
423                    throw e;
424                }
425            }
426        }
427    
428        public void testCopySubMatrix() {
429            RealMatrix m = new RealMatrixImpl(subTestData);
430            checkCopy(m, subRows23Cols00,  2 , 3 , 0, 0, false);
431            checkCopy(m, subRows00Cols33,  0 , 0 , 3, 3, false);
432            checkCopy(m, subRows01Cols23,  0 , 1 , 2, 3, false);   
433            checkCopy(m, subRows02Cols13,  new int[] { 0, 2 }, new int[] { 1, 3 },    false);  
434            checkCopy(m, subRows03Cols12,  new int[] { 0, 3 }, new int[] { 1, 2 },    false);  
435            checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }, false); 
436            checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }, false); 
437            checkCopy(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false); 
438            checkCopy(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 },    false); 
439            
440            checkCopy(m, null,  1, 0, 2, 4, true);
441            checkCopy(m, null, -1, 1, 2, 2, true);
442            checkCopy(m, null,  1, 0, 2, 2, true);
443            checkCopy(m, null,  1, 0, 2, 4, true);
444            checkCopy(m, null, new int[] {},    new int[] { 0 }, true);
445            checkCopy(m, null, new int[] { 0 }, new int[] { 4 }, true);
446        }
447    
448        private void checkCopy(RealMatrix m, double[][] reference,
449                               int startRow, int endRow, int startColumn, int endColumn,
450                               boolean mustFail) {
451            try {
452                double[][] sub = (reference == null) ?
453                                 new double[1][1] :
454                                 new double[reference.length][reference[0].length];
455                m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub);
456                assertEquals(new RealMatrixImpl(reference), new RealMatrixImpl(sub));
457                if (mustFail) {
458                    fail("Expecting MatrixIndexException");
459                }
460            } catch (MatrixIndexException e) {
461                if (!mustFail) {
462                    throw e;
463                }
464            }
465        }
466        
467        private void checkCopy(RealMatrix m, double[][] reference,
468                               int[] selectedRows, int[] selectedColumns,
469                               boolean mustFail) {
470            try {
471                double[][] sub = (reference == null) ?
472                        new double[1][1] :
473                        new double[reference.length][reference[0].length];
474                m.copySubMatrix(selectedRows, selectedColumns, sub);
475                assertEquals(new RealMatrixImpl(reference), new RealMatrixImpl(sub));
476                if (mustFail) {
477                    fail("Expecting MatrixIndexException");
478                }
479            } catch (MatrixIndexException e) {
480                if (!mustFail) {
481                    throw e;
482                }
483            }
484        }
485    
486        public void testGetRowMatrix() {
487            RealMatrix m = new RealMatrixImpl(subTestData);
488            RealMatrix mRow0 = new RealMatrixImpl(subRow0);
489            RealMatrix mRow3 = new RealMatrixImpl(subRow3);
490            assertEquals("Row0", mRow0, 
491                    m.getRowMatrix(0));
492            assertEquals("Row3", mRow3, 
493                    m.getRowMatrix(3));
494            try {
495                m.getRowMatrix(-1);
496                fail("Expecting MatrixIndexException");
497            } catch (MatrixIndexException ex) {
498                // expected
499            }
500            try {
501                m.getRowMatrix(4);
502                fail("Expecting MatrixIndexException");
503            } catch (MatrixIndexException ex) {
504                // expected
505            }
506        }
507        
508        public void testSetRowMatrix() {
509            RealMatrix m = new RealMatrixImpl(subTestData);
510            RealMatrix mRow3 = new RealMatrixImpl(subRow3);
511            assertNotSame(mRow3, m.getRowMatrix(0));
512            m.setRowMatrix(0, mRow3);
513            assertEquals(mRow3, m.getRowMatrix(0));
514            try {
515                m.setRowMatrix(-1, mRow3);
516                fail("Expecting MatrixIndexException");
517            } catch (MatrixIndexException ex) {
518                // expected
519            }
520            try {
521                m.setRowMatrix(0, m);
522                fail("Expecting InvalidMatrixException");
523            } catch (InvalidMatrixException ex) {
524                // expected
525            }
526        }
527        
528        public void testGetColumnMatrix() {
529            RealMatrix m = new RealMatrixImpl(subTestData);
530            RealMatrix mColumn1 = new RealMatrixImpl(subColumn1);
531            RealMatrix mColumn3 = new RealMatrixImpl(subColumn3);
532            assertEquals("Column1", mColumn1, 
533                    m.getColumnMatrix(1));
534            assertEquals("Column3", mColumn3, 
535                    m.getColumnMatrix(3));
536            try {
537                m.getColumnMatrix(-1);
538                fail("Expecting MatrixIndexException");
539            } catch (MatrixIndexException ex) {
540                // expected
541            }
542            try {
543                m.getColumnMatrix(4);
544                fail("Expecting MatrixIndexException");
545            } catch (MatrixIndexException ex) {
546                // expected
547            }
548        }
549    
550        public void testSetColumnMatrix() {
551            RealMatrix m = new RealMatrixImpl(subTestData);
552            RealMatrix mColumn3 = new RealMatrixImpl(subColumn3);
553            assertNotSame(mColumn3, m.getColumnMatrix(1));
554            m.setColumnMatrix(1, mColumn3);
555            assertEquals(mColumn3, m.getColumnMatrix(1));
556            try {
557                m.setColumnMatrix(-1, mColumn3);
558                fail("Expecting MatrixIndexException");
559            } catch (MatrixIndexException ex) {
560                // expected
561            }
562            try {
563                m.setColumnMatrix(0, m);
564                fail("Expecting InvalidMatrixException");
565            } catch (InvalidMatrixException ex) {
566                // expected
567            }
568        }
569    
570        public void testGetRowVector() {
571            RealMatrix m = new RealMatrixImpl(subTestData);
572            RealVector mRow0 = new ArrayRealVector(subRow0[0]);
573            RealVector mRow3 = new ArrayRealVector(subRow3[0]);
574            assertEquals("Row0", mRow0, m.getRowVector(0));
575            assertEquals("Row3", mRow3, m.getRowVector(3));
576            try {
577                m.getRowVector(-1);
578                fail("Expecting MatrixIndexException");
579            } catch (MatrixIndexException ex) {
580                // expected
581            }
582            try {
583                m.getRowVector(4);
584                fail("Expecting MatrixIndexException");
585            } catch (MatrixIndexException ex) {
586                // expected
587            }
588        }
589    
590        public void testSetRowVector() {
591            RealMatrix m = new RealMatrixImpl(subTestData);
592            RealVector mRow3 = new ArrayRealVector(subRow3[0]);
593            assertNotSame(mRow3, m.getRowMatrix(0));
594            m.setRowVector(0, mRow3);
595            assertEquals(mRow3, m.getRowVector(0));
596            try {
597                m.setRowVector(-1, mRow3);
598                fail("Expecting MatrixIndexException");
599            } catch (MatrixIndexException ex) {
600                // expected
601            }
602            try {
603                m.setRowVector(0, new ArrayRealVector(5));
604                fail("Expecting InvalidMatrixException");
605            } catch (InvalidMatrixException ex) {
606                // expected
607            }
608        }
609        
610        public void testGetColumnVector() {
611            RealMatrix m = new RealMatrixImpl(subTestData);
612            RealVector mColumn1 = columnToVector(subColumn1);
613            RealVector mColumn3 = columnToVector(subColumn3);
614            assertEquals("Column1", mColumn1, m.getColumnVector(1));
615            assertEquals("Column3", mColumn3, m.getColumnVector(3));
616            try {
617                m.getColumnVector(-1);
618                fail("Expecting MatrixIndexException");
619            } catch (MatrixIndexException ex) {
620                // expected
621            }
622            try {
623                m.getColumnVector(4);
624                fail("Expecting MatrixIndexException");
625            } catch (MatrixIndexException ex) {
626                // expected
627            }
628        }
629    
630        public void testSetColumnVector() {
631            RealMatrix m = new RealMatrixImpl(subTestData);
632            RealVector mColumn3 = columnToVector(subColumn3);
633            assertNotSame(mColumn3, m.getColumnVector(1));
634            m.setColumnVector(1, mColumn3);
635            assertEquals(mColumn3, m.getColumnVector(1));
636            try {
637                m.setColumnVector(-1, mColumn3);
638                fail("Expecting MatrixIndexException");
639            } catch (MatrixIndexException ex) {
640                // expected
641            }
642            try {
643                m.setColumnVector(0, new ArrayRealVector(5));
644                fail("Expecting InvalidMatrixException");
645            } catch (InvalidMatrixException ex) {
646                // expected
647            }
648        }
649    
650        private RealVector columnToVector(double[][] column) {
651            double[] data = new double[column.length];
652            for (int i = 0; i < data.length; ++i) {
653                data[i] = column[i][0];
654            }
655            return new ArrayRealVector(data, false);
656        }
657    
658        public void testGetRow() {
659            RealMatrix m = new RealMatrixImpl(subTestData);
660            checkArrays(subRow0[0], m.getRow(0));
661            checkArrays(subRow3[0], m.getRow(3));
662            try {
663                m.getRow(-1);
664                fail("Expecting MatrixIndexException");
665            } catch (MatrixIndexException ex) {
666                // expected
667            }
668            try {
669                m.getRow(4);
670                fail("Expecting MatrixIndexException");
671            } catch (MatrixIndexException ex) {
672                // expected
673            }
674        }
675    
676        public void testSetRow() {
677            RealMatrix m = new RealMatrixImpl(subTestData);
678            assertTrue(subRow3[0][0] != m.getRow(0)[0]);
679            m.setRow(0, subRow3[0]);
680            checkArrays(subRow3[0], m.getRow(0));
681            try {
682                m.setRow(-1, subRow3[0]);
683                fail("Expecting MatrixIndexException");
684            } catch (MatrixIndexException ex) {
685                // expected
686            }
687            try {
688                m.setRow(0, new double[5]);
689                fail("Expecting InvalidMatrixException");
690            } catch (InvalidMatrixException ex) {
691                // expected
692            }
693        }
694        
695        public void testGetColumn() {
696            RealMatrix m = new RealMatrixImpl(subTestData);
697            double[] mColumn1 = columnToArray(subColumn1);
698            double[] mColumn3 = columnToArray(subColumn3);
699            checkArrays(mColumn1, m.getColumn(1));
700            checkArrays(mColumn3, m.getColumn(3));
701            try {
702                m.getColumn(-1);
703                fail("Expecting MatrixIndexException");
704            } catch (MatrixIndexException ex) {
705                // expected
706            }
707            try {
708                m.getColumn(4);
709                fail("Expecting MatrixIndexException");
710            } catch (MatrixIndexException ex) {
711                // expected
712            }
713        }
714    
715        public void testSetColumn() {
716            RealMatrix m = new RealMatrixImpl(subTestData);
717            double[] mColumn3 = columnToArray(subColumn3);
718            assertTrue(mColumn3[0] != m.getColumn(1)[0]);
719            m.setColumn(1, mColumn3);
720            checkArrays(mColumn3, m.getColumn(1));
721            try {
722                m.setColumn(-1, mColumn3);
723                fail("Expecting MatrixIndexException");
724            } catch (MatrixIndexException ex) {
725                // expected
726            }
727            try {
728                m.setColumn(0, new double[5]);
729                fail("Expecting InvalidMatrixException");
730            } catch (InvalidMatrixException ex) {
731                // expected
732            }
733        }
734    
735        private double[] columnToArray(double[][] column) {
736            double[] data = new double[column.length];
737            for (int i = 0; i < data.length; ++i) {
738                data[i] = column[i][0];
739            }
740            return data;
741        }
742    
743        private void checkArrays(double[] expected, double[] actual) {
744            assertEquals(expected.length, actual.length);
745            for (int i = 0; i < expected.length; ++i) {
746                assertEquals(expected[i], actual[i]);            
747            }
748        }
749        
750        public void testEqualsAndHashCode() {
751            RealMatrixImpl m = new RealMatrixImpl(testData);
752            RealMatrixImpl m1 = (RealMatrixImpl) m.copy();
753            RealMatrixImpl mt = (RealMatrixImpl) m.transpose();
754            assertTrue(m.hashCode() != mt.hashCode());
755            assertEquals(m.hashCode(), m1.hashCode());
756            assertEquals(m, m);
757            assertEquals(m, m1);
758            assertFalse(m.equals(null));
759            assertFalse(m.equals(mt));
760            assertFalse(m.equals(new RealMatrixImpl(bigSingular))); 
761        }
762        
763        public void testToString() {
764            RealMatrixImpl m = new RealMatrixImpl(testData);
765            assertEquals("RealMatrixImpl{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}",
766                    m.toString());
767            m = new RealMatrixImpl();
768            assertEquals("RealMatrixImpl{}",
769                    m.toString());
770        }
771        
772        public void testSetSubMatrix() throws Exception {
773            RealMatrixImpl m = new RealMatrixImpl(testData);
774            m.setSubMatrix(detData2,1,1);
775            RealMatrix expected = MatrixUtils.createRealMatrix
776                (new double[][] {{1.0,2.0,3.0},{2.0,1.0,3.0},{1.0,2.0,4.0}});
777            assertEquals(expected, m);  
778            
779            m.setSubMatrix(detData2,0,0);
780            expected = MatrixUtils.createRealMatrix
781                (new double[][] {{1.0,3.0,3.0},{2.0,4.0,3.0},{1.0,2.0,4.0}});
782            assertEquals(expected, m);  
783            
784            m.setSubMatrix(testDataPlus2,0,0);      
785            expected = MatrixUtils.createRealMatrix
786                (new double[][] {{3.0,4.0,5.0},{4.0,7.0,5.0},{3.0,2.0,10.0}});
787            assertEquals(expected, m);   
788            
789            // dimension overflow
790            try {  
791                m.setSubMatrix(testData,1,1);
792                fail("expecting MatrixIndexException");
793            } catch (MatrixIndexException e) {
794                // expected
795            }
796            // dimension underflow
797            try {  
798                m.setSubMatrix(testData,-1,1);
799                fail("expecting MatrixIndexException");
800            } catch (MatrixIndexException e) {
801                // expected
802            }
803            try {  
804                m.setSubMatrix(testData,1,-1);
805                fail("expecting MatrixIndexException");
806            } catch (MatrixIndexException e) {
807                // expected
808            }
809            
810            // null
811            try {
812                m.setSubMatrix(null,1,1);
813                fail("expecting NullPointerException");
814            } catch (NullPointerException e) {
815                // expected
816            }
817            RealMatrixImpl m2 = new RealMatrixImpl();
818            try {
819                m2.setSubMatrix(testData,0,1);
820                fail("expecting IllegalStateException");
821            } catch (IllegalStateException e) {
822                // expected
823            }
824            try {
825                m2.setSubMatrix(testData,1,0);
826                fail("expecting IllegalStateException");
827            } catch (IllegalStateException e) {
828                // expected
829            }
830            
831            // ragged
832            try {
833                m.setSubMatrix(new double[][] {{1}, {2, 3}}, 0, 0);
834                fail("expecting IllegalArgumentException");
835            } catch (IllegalArgumentException e) {
836                // expected
837            }
838           
839            // empty
840            try {
841                m.setSubMatrix(new double[][] {{}}, 0, 0);
842                fail("expecting IllegalArgumentException");
843            } catch (IllegalArgumentException e) {
844                // expected
845            }
846            
847        }
848    
849        public void testWalk() {
850            int rows    = 150;
851            int columns = 75;
852    
853            RealMatrix m = new RealMatrixImpl(rows, columns);
854            m.walkInRowOrder(new SetVisitor());
855            GetVisitor getVisitor = new GetVisitor();
856            m.walkInOptimizedOrder(getVisitor);
857            assertEquals(rows * columns, getVisitor.getCount());
858    
859            m = new RealMatrixImpl(rows, columns);
860            m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
861            getVisitor = new GetVisitor();
862            m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2);
863            assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
864            for (int i = 0; i < rows; ++i) {
865                assertEquals(0.0, m.getEntry(i, 0), 0);                    
866                assertEquals(0.0, m.getEntry(i, columns - 1), 0);
867            }
868            for (int j = 0; j < columns; ++j) {
869                assertEquals(0.0, m.getEntry(0, j), 0);                    
870                assertEquals(0.0, m.getEntry(rows - 1, j), 0);
871            }
872    
873            m = new RealMatrixImpl(rows, columns);
874            m.walkInColumnOrder(new SetVisitor());
875            getVisitor = new GetVisitor();
876            m.walkInOptimizedOrder(getVisitor);
877            assertEquals(rows * columns, getVisitor.getCount());
878    
879            m = new RealMatrixImpl(rows, columns);
880            m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
881            getVisitor = new GetVisitor();
882            m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2);
883            assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
884            for (int i = 0; i < rows; ++i) {
885                assertEquals(0.0, m.getEntry(i, 0), 0);                    
886                assertEquals(0.0, m.getEntry(i, columns - 1), 0);
887            }
888            for (int j = 0; j < columns; ++j) {
889                assertEquals(0.0, m.getEntry(0, j), 0);                    
890                assertEquals(0.0, m.getEntry(rows - 1, j), 0);
891            }
892    
893            m = new RealMatrixImpl(rows, columns);
894            m.walkInOptimizedOrder(new SetVisitor());
895            getVisitor = new GetVisitor();
896            m.walkInRowOrder(getVisitor);
897            assertEquals(rows * columns, getVisitor.getCount());
898    
899            m = new RealMatrixImpl(rows, columns);
900            m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
901            getVisitor = new GetVisitor();
902            m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2);
903            assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
904            for (int i = 0; i < rows; ++i) {
905                assertEquals(0.0, m.getEntry(i, 0), 0);                    
906                assertEquals(0.0, m.getEntry(i, columns - 1), 0);
907            }
908            for (int j = 0; j < columns; ++j) {
909                assertEquals(0.0, m.getEntry(0, j), 0);                    
910                assertEquals(0.0, m.getEntry(rows - 1, j), 0);
911            }
912    
913            m = new RealMatrixImpl(rows, columns);
914            m.walkInOptimizedOrder(new SetVisitor());
915            getVisitor = new GetVisitor();
916            m.walkInColumnOrder(getVisitor);
917            assertEquals(rows * columns, getVisitor.getCount());
918    
919            m = new RealMatrixImpl(rows, columns);
920            m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
921            getVisitor = new GetVisitor();
922            m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2);
923            assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
924            for (int i = 0; i < rows; ++i) {
925                assertEquals(0.0, m.getEntry(i, 0), 0);                    
926                assertEquals(0.0, m.getEntry(i, columns - 1), 0);
927            }
928            for (int j = 0; j < columns; ++j) {
929                assertEquals(0.0, m.getEntry(0, j), 0);                    
930                assertEquals(0.0, m.getEntry(rows - 1, j), 0);
931            }
932    
933        }
934    
935        public void testSerial()  {
936            RealMatrixImpl m = new RealMatrixImpl(testData);
937            assertEquals(m,TestUtils.serializeAndRecover(m));
938        }
939        
940        
941        private static class SetVisitor extends DefaultRealMatrixChangingVisitor {
942            @Override
943            public double visit(int i, int j, double value) {
944                return i + j / 1024.0;
945            }
946        }
947    
948        private static class GetVisitor extends DefaultRealMatrixPreservingVisitor {
949            private int count = 0;
950            @Override
951            public void visit(int i, int j, double value) {
952                ++count;
953                assertEquals(i + j / 1024.0, value, 0.0);
954            }
955            public int getCount() {
956                return count;
957            }
958        }
959    
960        //--------------- -----------------Protected methods
961        
962        /** extracts the l  and u matrices from compact lu representation */
963        protected void splitLU(RealMatrix lu, double[][] lowerData, double[][] upperData) throws InvalidMatrixException {   
964            if (!lu.isSquare() || lowerData.length != lowerData[0].length || upperData.length != upperData[0].length ||
965                    lowerData.length != upperData.length
966                    || lowerData.length != lu.getRowDimension()) {
967                throw new InvalidMatrixException("incorrect dimensions");
968            }    
969            int n = lu.getRowDimension();
970            for (int i = 0; i < n; i++) {
971                for (int j = 0; j < n; j++) {
972                    if (j < i) {
973                        lowerData[i][j] = lu.getEntry(i, j);
974                        upperData[i][j] = 0d;
975                    } else if (i == j) {
976                        lowerData[i][j] = 1d;
977                        upperData[i][j] = lu.getEntry(i, j);
978                    } else {
979                        lowerData[i][j] = 0d;
980                        upperData[i][j] = lu.getEntry(i, j);
981                    }   
982                }
983            }
984        }
985        
986        /** Returns the result of applying the given row permutation to the matrix */
987        protected RealMatrix permuteRows(RealMatrix matrix, int[] permutation) {
988            if (!matrix.isSquare() || matrix.getRowDimension() != permutation.length) {
989                throw new IllegalArgumentException("dimension mismatch");
990            }
991            int n = matrix.getRowDimension();
992            int m = matrix.getColumnDimension();
993            double out[][] = new double[m][n];
994            for (int i = 0; i < n; i++) {
995                for (int j = 0; j < m; j++) {
996                    out[i][j] = matrix.getEntry(permutation[i], j);
997                }
998            }
999            return new RealMatrixImpl(out);
1000        }
1001        
1002    //    /** Useful for debugging */
1003    //    private void dumpMatrix(RealMatrix m) {
1004    //          for (int i = 0; i < m.getRowDimension(); i++) {
1005    //              String os = "";
1006    //              for (int j = 0; j < m.getColumnDimension(); j++) {
1007    //                  os += m.getEntry(i, j) + " ";
1008    //              }
1009    //              System.out.println(os);
1010    //          }
1011    //    }
1012            
1013    }
1014