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