1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.linear;
19
20 import java.util.Random;
21
22 import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
23 import org.apache.commons.numbers.core.Precision;
24 import org.junit.Test;
25 import org.junit.Assert;
26
27 public class EigenSolverTest {
28
29 private double[][] bigSingular = {
30 { 1.0, 2.0, 3.0, 4.0 },
31 { 2.0, 5.0, 3.0, 4.0 },
32 { 7.0, 3.0, 256.0, 1930.0 },
33 { 3.0, 7.0, 6.0, 8.0 }
34 };
35
36
37 @Test
38 public void testNonInvertible() {
39 Random r = new Random(9994100315209L);
40 RealMatrix m =
41 EigenDecompositionTest.createTestMatrix(r, new double[] { 1.0, 0.0, -1.0, -2.0, -3.0 });
42 DecompositionSolver es = new EigenDecomposition(m).getSolver();
43 Assert.assertFalse(es.isNonSingular());
44 try {
45 es.getInverse();
46 Assert.fail("an exception should have been thrown");
47 } catch (SingularMatrixException ime) {
48
49 }
50 }
51
52
53 @Test
54 public void testInvertible() {
55 Random r = new Random(9994100315209L);
56 RealMatrix m =
57 EigenDecompositionTest.createTestMatrix(r, new double[] { 1.0, 0.5, -1.0, -2.0, -3.0 });
58 DecompositionSolver es = new EigenDecomposition(m).getSolver();
59 Assert.assertTrue(es.isNonSingular());
60 RealMatrix inverse = es.getInverse();
61 RealMatrix error =
62 m.multiply(inverse).subtract(MatrixUtils.createRealIdentityMatrix(m.getRowDimension()));
63 Assert.assertEquals(0, error.getNorm(), 4.0e-15);
64 }
65
66
67
68
69
70 @Test
71 public void testInvertibleTinyValues() {
72 final double tiny = 1e-100;
73 RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
74 {3, 2, 4},
75 {2, 0, 2},
76 {4, 2, 3}
77 });
78 m = m.scalarMultiply(tiny);
79
80 final EigenDecomposition ed = new EigenDecomposition(m);
81 RealMatrix inv = ed.getSolver().getInverse();
82
83 final RealMatrix id = m.multiply(inv);
84 for (int i = 0; i < m.getRowDimension(); i++) {
85 for (int j = 0; j < m.getColumnDimension(); j++) {
86 if (i == j) {
87 Assert.assertTrue(Precision.equals(1, id.getEntry(i, j), 1e-15));
88 } else {
89 Assert.assertTrue(Precision.equals(0, id.getEntry(i, j), 1e-15));
90 }
91 }
92 }
93 }
94
95 @Test(expected=SingularMatrixException.class)
96 public void testNonInvertibleMath1045() {
97 EigenDecomposition eigen =
98 new EigenDecomposition(MatrixUtils.createRealMatrix(bigSingular));
99 eigen.getSolver().getInverse();
100 }
101
102 @Test(expected=SingularMatrixException.class)
103 public void testZeroMatrix() {
104 EigenDecomposition eigen =
105 new EigenDecomposition(MatrixUtils.createRealMatrix(new double[][] {{0}}));
106 eigen.getSolver().getInverse();
107 }
108
109 @Test
110 public void testIsNonSingularTinyOutOfOrderEigenvalue() {
111 final EigenDecomposition eigen
112 = new EigenDecomposition(MatrixUtils.createRealMatrix(new double[][] {
113 { 1e-13, 0 },
114 { 1, 1 },
115 }));
116 Assert.assertFalse("Singular matrix not detected",
117 eigen.getSolver().isNonSingular());
118 }
119
120
121 @Test
122 public void testSolveDimensionErrors() {
123 final double[] refValues = new double[] {
124 2.003, 2.002, 2.001, 1.001, 1.000, 0.001
125 };
126 final RealMatrix matrix = EigenDecompositionTest.createTestMatrix(new Random(35992629946426L), refValues);
127
128 DecompositionSolver es = new EigenDecomposition(matrix).getSolver();
129 RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]);
130 try {
131 es.solve(b);
132 Assert.fail("an exception should have been thrown");
133 } catch (MathIllegalArgumentException iae) {
134
135 }
136 try {
137 es.solve(b.getColumnVector(0));
138 Assert.fail("an exception should have been thrown");
139 } catch (MathIllegalArgumentException iae) {
140
141 }
142 try {
143 es.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0)));
144 Assert.fail("an exception should have been thrown");
145 } catch (MathIllegalArgumentException iae) {
146
147 }
148 }
149
150
151 @Test
152 public void testSolve() {
153 RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
154 { 91, 5, 29, 32, 40, 14 },
155 { 5, 34, -1, 0, 2, -1 },
156 { 29, -1, 12, 9, 21, 8 },
157 { 32, 0, 9, 14, 9, 0 },
158 { 40, 2, 21, 9, 51, 19 },
159 { 14, -1, 8, 0, 19, 14 }
160 });
161 DecompositionSolver es = new EigenDecomposition(m).getSolver();
162 RealMatrix b = MatrixUtils.createRealMatrix(new double[][] {
163 { 1561, 269, 188 },
164 { 69, -21, 70 },
165 { 739, 108, 63 },
166 { 324, 86, 59 },
167 { 1624, 194, 107 },
168 { 796, 69, 36 }
169 });
170 RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] {
171 { 1, 2, 1 },
172 { 2, -1, 2 },
173 { 4, 2, 3 },
174 { 8, -1, 0 },
175 { 16, 2, 0 },
176 { 32, -1, 0 }
177 });
178
179
180 RealMatrix solution=es.solve(b);
181 Assert.assertEquals(0, solution.subtract(xRef).getNorm(), 2.5e-12);
182
183
184 for (int i = 0; i < b.getColumnDimension(); ++i) {
185 Assert.assertEquals(0,
186 es.solve(b.getColumnVector(i)).subtract(xRef.getColumnVector(i)).getNorm(),
187 2.0e-11);
188 }
189
190
191 for (int i = 0; i < b.getColumnDimension(); ++i) {
192 ArrayRealVectorTest.RealVectorTestImpl v =
193 new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i));
194 Assert.assertEquals(0,
195 es.solve(v).subtract(xRef.getColumnVector(i)).getNorm(),
196 2.0e-11);
197 }
198 }
199 }