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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
package org.apache.commons.math.linear;
19
import junit.framework.Test;
20
import junit.framework.TestCase;
21
import junit.framework.TestSuite;
24
* Test cases for the {@link RealMatrixImpl} class.
26
* @version $Revision: 611480 $ $Date: 2008-01-12 14:04:42 -0700 (Sat, 12 Jan 2008) $
29
public final class RealMatrixImplTest extends TestCase {
31
// 3 x 3 identity matrix
32
protected double[][] id = { {1d,0d,0d}, {0d,1d,0d}, {0d,0d,1d} };
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},
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} };
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} };
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}};
63
protected double[] testVector = {1,2,3};
64
protected double[] testVector2 = {1,2,3,4};
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}};
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}};
77
protected double[][] subRows01Cols23 = {{3,4} , {3.5, 4.5}};
78
protected double[][] subRows23Cols00 = {{2} , {4}};
79
protected double[][] subRows00Cols33 = {{4}};
81
protected double[][] subRow0 = {{1,2,3,4}};
82
protected double[][] subRow3 = {{4,5,6,7}};
84
protected double[][] subColumn1 = {{2}, {2.5}, {4}, {5}};
85
protected double[][] subColumn3 = {{4}, {4.5}, {8}, {7}};
88
protected double entryTolerance = 10E-16;
89
protected double normTolerance = 10E-14;
91
public RealMatrixImplTest(String name) {
99
public static Test suite() {
100
TestSuite suite = new TestSuite(RealMatrixImplTest.class);
101
suite.setName("RealMatrixImpl Tests");
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());
117
/** test copy functions */
118
public void testCopyFunctions() {
119
RealMatrixImpl m = new RealMatrixImpl(testData);
120
RealMatrixImpl m2 = new RealMatrixImpl(m.getData());
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],
139
/** test add failure */
140
public void testAddFail() {
141
RealMatrixImpl m = new RealMatrixImpl(testData);
142
RealMatrixImpl m2 = new RealMatrixImpl(testData2);
145
fail("IllegalArgumentException expected");
146
} catch (IllegalArgumentException ex) {
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);
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);
166
m.subtract(new RealMatrixImpl(testData2));
167
fail("Expecting illegalArgumentException");
168
} catch (IllegalArgumentException ex) {
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),
185
assertClose("identity multiply",identity.multiply(mInv),
186
mInv,entryTolerance);
187
assertClose("identity multiply",m2.multiply(identity),
190
m.multiply(new RealMatrixImpl(bigSingular));
191
fail("Expecting illegalArgumentException");
192
} catch (IllegalArgumentException ex) {
197
//Additional Test for RealMatrixImplTest.testMultiply
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}};
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);
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());
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);
230
m = new RealMatrixImpl(testData2);
233
fail("Expecting InvalidMatrixException");
234
} catch (InvalidMatrixException ex) {
239
m = new RealMatrixImpl(singular);
242
fail("Expecting InvalidMatrixException");
243
} catch (InvalidMatrixException ex) {
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);
256
m.solve(testVector2);
257
fail("expecting IllegalArgumentException");
258
} catch (IllegalArgumentException ex) {
261
RealMatrix bs = new RealMatrixImpl(bigSingular);
264
fail("Expecting InvalidMatrixException");
265
} catch (InvalidMatrixException ex) {
270
fail("Expecting IllegalArgumentException");
271
} catch (IllegalArgumentException ex) {
275
new RealMatrixImpl(testData2).solve(bs);
276
fail("Expecting illegalArgumentException");
277
} catch (IllegalArgumentException ex) {
281
(new RealMatrixImpl(testData2)).luDecompose();
282
fail("Expecting InvalidMatrixException");
283
} catch (InvalidMatrixException ex) {
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);
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);
302
new RealMatrixImpl(testData2).getDeterminant();
303
fail("Expecting InvalidMatrixException");
304
} catch (InvalidMatrixException ex) {
310
public void testTrace() {
311
RealMatrix m = new RealMatrixImpl(id);
312
assertEquals("identity trace",3d,m.getTrace(),entryTolerance);
313
m = new RealMatrixImpl(testData2);
316
fail("Expecting illegalArgumentException");
317
} catch (IllegalArgumentException ex) {
323
public void testScalarAdd() {
324
RealMatrix m = new RealMatrixImpl(testData);
325
assertClose("scalar add",new RealMatrixImpl(testDataPlus2),
326
m.scalarAdd(2d),entryTolerance);
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);
336
m.operate(testVector);
337
fail("Expecting illegalArgumentException");
338
} catch (IllegalArgumentException ex) {
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);
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);
359
m.preMultiply(testVector);
360
fail("expecting IllegalArgumentException");
361
} catch (IllegalArgumentException ex) {
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);
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),
381
assertClose("identity multiply",identity.preMultiply(mInv),
382
mInv,entryTolerance);
384
m.preMultiply(new RealMatrixImpl(bigSingular));
385
fail("Expecting illegalArgumentException");
386
} catch (IllegalArgumentException ex) {
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);
397
fail("expecting MatrixIndexException");
398
} catch (MatrixIndexException ex) {
403
fail("expecting MatrixIndexException");
404
} catch (MatrixIndexException ex) {
409
public void testGetEntry() {
410
RealMatrix m = new RealMatrixImpl(testData);
411
assertEquals("get entry",m.getEntry(0,1),2d,entryTolerance);
414
fail ("Expecting MatrixIndexException");
415
} catch (MatrixIndexException ex) {
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);
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);
441
m = new RealMatrixImpl(bigSingular); // singular
442
lu = m.getLUMatrix();
443
fail("Expecting InvalidMatrixException");
444
} catch (InvalidMatrixException ex) {
448
m = new RealMatrixImpl(testData2); // not square
449
lu = m.getLUMatrix();
450
fail("Expecting InvalidMatrixException");
451
} catch (InvalidMatrixException ex) {
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());
469
RealMatrix pInverse = p.inverse();
470
assertEquals(2, pInverse.getRowDimension());
471
assertEquals(2, pInverse.getColumnDimension());
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);
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}));
515
m.getSubMatrix(1,0,2,4);
516
fail("Expecting MatrixIndexException");
517
} catch (MatrixIndexException ex) {
521
m.getSubMatrix(-1,1,2,2);
522
fail("Expecting MatrixIndexException");
523
} catch (MatrixIndexException ex) {
527
m.getSubMatrix(1,0,2,2);
528
fail("Expecting MatrixIndexException");
529
} catch (MatrixIndexException ex) {
533
m.getSubMatrix(1,0,2,4);
534
fail("Expecting MatrixIndexException");
535
} catch (MatrixIndexException ex) {
539
m.getSubMatrix(new int[] {}, new int[] {0});
540
fail("Expecting MatrixIndexException");
541
} catch (MatrixIndexException ex) {
545
m.getSubMatrix(new int[] {0}, new int[] {4});
546
fail("Expecting MatrixIndexException");
547
} catch (MatrixIndexException ex) {
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,
558
assertEquals("Row3", mRow3,
562
fail("Expecting MatrixIndexException");
563
} catch (MatrixIndexException ex) {
568
fail("Expecting MatrixIndexException");
569
} catch (MatrixIndexException ex) {
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));
583
m.getColumnMatrix(-1);
584
fail("Expecting MatrixIndexException");
585
} catch (MatrixIndexException ex) {
589
m.getColumnMatrix(4);
590
fail("Expecting MatrixIndexException");
591
} catch (MatrixIndexException ex) {
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());
604
assertFalse(m.equals(null));
605
assertFalse(m.equals(mt));
606
assertFalse(m.equals(new RealMatrixImpl(bigSingular)));
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}}",
613
m = new RealMatrixImpl();
614
assertEquals("RealMatrixImpl{}",
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);
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);
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);
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);
643
// dimension overflow
645
m.setSubMatrix(testData,1,1);
646
fail("expecting MatrixIndexException");
647
} catch (MatrixIndexException e) {
650
// dimension underflow
652
m.setSubMatrix(testData,-1,1);
653
fail("expecting MatrixIndexException");
654
} catch (MatrixIndexException e) {
658
m.setSubMatrix(testData,1,-1);
659
fail("expecting MatrixIndexException");
660
} catch (MatrixIndexException e) {
666
m.setSubMatrix(null,1,1);
667
fail("expecting NullPointerException");
668
} catch (NullPointerException e) {
671
RealMatrixImpl m2 = new RealMatrixImpl();
673
m2.setSubMatrix(testData,0,1);
674
fail("expecting MatrixIndexException");
675
} catch (MatrixIndexException e) {
679
m2.setSubMatrix(testData,1,0);
680
fail("expecting MatrixIndexException");
681
} catch (MatrixIndexException e) {
687
m.setSubMatrix(new double[][] {{1}, {2, 3}}, 0, 0);
688
fail("expecting IllegalArgumentException");
689
} catch (IllegalArgumentException e) {
695
m.setSubMatrix(new double[][] {{}}, 0, 0);
696
fail("expecting IllegalArgumentException");
697
} catch (IllegalArgumentException e) {
703
//--------------- -----------------Protected methods
705
/** verifies that two matrices are close (1-norm) */
706
protected void assertClose(String msg, RealMatrix m, RealMatrix n,
708
assertTrue(msg,m.subtract(n).getNorm() < tolerance);
711
/** verifies that two vectors are close (sup norm) */
712
protected void assertClose(String msg, double[] m, double[] n,
714
if (m.length != n.length) {
715
fail("vectors not same length");
717
for (int i = 0; i < m.length; i++) {
718
assertEquals(msg + " " + i + " elements differ",
719
m[i],n[i],tolerance);
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");
730
int n = lu.getRowDimension();
731
for (int i = 0; i < n; i++) {
732
for (int j = 0; j < n; j++) {
734
lowerData[i][j] = lu.getEntry(i, j);
735
upperData[i][j] = 0d;
737
lowerData[i][j] = 1d;
738
upperData[i][j] = lu.getEntry(i, j);
740
lowerData[i][j] = 0d;
741
upperData[i][j] = lu.getEntry(i, j);
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");
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);
760
return new RealMatrixImpl(out);
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);
777
// /** Useful for debugging */
778
// private void dumpMatrix(RealMatrix m) {
779
// for (int i = 0; i < m.getRowDimension(); i++) {
781
// for (int j = 0; j < m.getColumnDimension(); j++) {
782
// os += m.getEntry(i, j) + " ";
784
// System.out.println(os);