~ubuntu-branches/ubuntu/karmic/commons-math/karmic

« back to all changes in this revision

Viewing changes to src/test/org/apache/commons/math/linear/RealMatrixImplTest.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-03-15 20:20:21 UTC
  • Revision ID: james.westby@ubuntu.com-20090315202021-zto3nmvqgcf3ami4
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

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