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.UnitTestUtils;
26 import org.hipparchus.complex.Complex;
27 import org.hipparchus.complex.ComplexComparator;
28 import org.hipparchus.complex.ComplexField;
29 import org.hipparchus.random.RandomDataGenerator;
30 import org.hipparchus.random.RandomGenerator;
31 import org.hipparchus.random.Well1024a;
32 import org.hipparchus.util.FastMath;
33 import org.hipparchus.util.Precision;
34 import org.junit.jupiter.api.AfterEach;
35 import org.junit.jupiter.api.BeforeEach;
36 import org.junit.jupiter.api.Test;
37
38 import java.util.Arrays;
39 import java.util.Random;
40
41 import static org.junit.jupiter.api.Assertions.assertEquals;
42 import static org.junit.jupiter.api.Assertions.assertNotNull;
43 import static org.junit.jupiter.api.Assertions.assertTrue;
44 import static org.junit.jupiter.api.Assertions.fail;
45
46 public class EigenDecompositionNonSymmetricTest {
47
48 private Complex[] refValues;
49 private RealMatrix matrix;
50
51
52 @Test
53 void testDimensions() {
54 final int m = matrix.getRowDimension();
55 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(matrix);
56 assertEquals(m, ed.getV().getRowDimension());
57 assertEquals(m, ed.getV().getColumnDimension());
58 assertEquals(m, ed.getD().getColumnDimension());
59 assertEquals(m, ed.getD().getColumnDimension());
60 assertEquals(m, ed.getVInv().getRowDimension());
61 assertEquals(m, ed.getVInv().getColumnDimension());
62 }
63
64
65 @Test
66 void testEigenvalues() {
67 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(matrix);
68 Complex[] eigenValues = ed.getEigenvalues();
69 assertEquals(refValues.length, eigenValues.length);
70 for (int i = 0; i < refValues.length; ++i) {
71 assertEquals(refValues[i].getRealPart(), eigenValues[i].getRealPart(), 3.0e-15);
72 assertEquals(refValues[i].getImaginaryPart(), eigenValues[i].getImaginaryPart(), 3.0e-15);
73 }
74 }
75
76 @Test
77 void testNonSymmetric() {
78
79 double[][] vData = { { -1.0, 1.0, -1.0, 1.0 },
80 { -8.0, 4.0, -2.0, 1.0 },
81 { 27.0, 9.0, 3.0, 1.0 },
82 { 64.0, 16.0, 4.0, 1.0 } };
83 checkNonSymmetricMatrix(MatrixUtils.createRealMatrix(vData));
84
85 RealMatrix randMatrix = MatrixUtils.createRealMatrix(new double[][] {
86 {0, 1, 0, 0},
87 {1, 0, 2.e-7, 0},
88 {0, -2.e-7, 0, 1},
89 {0, 0, 1, 0}
90 });
91 checkNonSymmetricMatrix(randMatrix);
92
93
94 double[][] randData2 = {
95 { 0.680, -0.3300, -0.2700, -0.717, -0.687, 0.0259 },
96 { -0.211, 0.5360, 0.0268, 0.214, -0.198, 0.6780 },
97 { 0.566, -0.4440, 0.9040, -0.967, -0.740, 0.2250 },
98 { 0.597, 0.1080, 0.8320, -0.514, -0.782, -0.4080 },
99 { 0.823, -0.0452, 0.2710, -0.726, 0.998, 0.2750 },
100 { -0.605, 0.2580, 0.4350, 0.608, -0.563, 0.0486 }
101 };
102 checkNonSymmetricMatrix(MatrixUtils.createRealMatrix(randData2));
103 }
104
105 @Test
106 void testRandomNonSymmetricMatrix() {
107 for (int run = 0; run < 100; run++) {
108 RandomGenerator r = new Well1024a(0x171956baefeac83el);
109
110
111 int size = r.nextInt(20) + 4;
112
113 double[][] data = new double[size][size];
114 for (int i = 0; i < size; i++) {
115 for (int j = 0; j < size; j++) {
116 data[i][j] = r.nextInt(100);
117 }
118 }
119
120 RealMatrix m = MatrixUtils.createRealMatrix(data);
121 checkNonSymmetricMatrix(m);
122 }
123 }
124
125
126
127
128
129
130
131 @Test
132 void testMath1051() {
133 double[][] data = {
134 {0,0,0,0,0},
135 {0,0,0,0,1},
136 {0,0,0,1,0},
137 {1,1,0,0,1},
138 {1,0,1,0,1}
139 };
140
141 RealMatrix m = MatrixUtils.createRealMatrix(data);
142 checkNonSymmetricMatrix(m);
143 }
144
145 @Test
146 void testNormalDistributionNonSymmetricMatrix() {
147 for (int run = 0; run < 100; run++) {
148 final RandomGenerator r = new Well1024a(0x511d8551a5641ea2l);
149 final RandomDataGenerator gen = new RandomDataGenerator(100);
150
151
152 int size = r.nextInt(20) + 4;
153
154 double[][] data = new double[size][size];
155 for (int i = 0; i < size; i++) {
156 for (int j = 0; j < size; j++) {
157 data[i][j] = gen.nextNormal(0.0, r.nextDouble() * 5);
158 }
159 }
160
161 RealMatrix m = MatrixUtils.createRealMatrix(data);
162 checkNonSymmetricMatrix(m);
163 }
164 }
165
166 @Test
167 void testMath848() {
168 double[][] data = {
169 { 0.1849449280, -0.0646971046, 0.0774755812, -0.0969651755, -0.0692648806, 0.3282344352, -0.0177423074, 0.2063136340},
170 {-0.0742700134, -0.0289063030, -0.0017269460, -0.0375550146, -0.0487737922, -0.2616837868, -0.0821201295, -0.2530000167},
171 { 0.2549910127, 0.0995733692, -0.0009718388, 0.0149282808, 0.1791878897, -0.0823182816, 0.0582629256, 0.3219545182},
172 {-0.0694747557, -0.1880649148, -0.2740630911, 0.0720096468, -0.1800836914, -0.3518996425, 0.2486747833, 0.6257938167},
173 { 0.0536360918, -0.1339297778, 0.2241579764, -0.0195327484, -0.0054103808, 0.0347564518, 0.5120802482, -0.0329902864},
174 {-0.5933332356, -0.2488721082, 0.2357173629, 0.0177285473, 0.0856630593, -0.3567126300, -0.1600668126, -0.1010899621},
175 {-0.0514349819, -0.0854319435, 0.1125050061, 0.0063453560, -0.2250000688, -0.2209343090, 0.1964623477, -0.1512329924},
176 { 0.0197395947, -0.1997170581, -0.1425959019, -0.2749477910, -0.0969467073, 0.0603688520, -0.2826905192, 0.1794315473}};
177 RealMatrix m = MatrixUtils.createRealMatrix(data);
178 checkNonSymmetricMatrix(m);
179 }
180
181
182
183
184
185 private void checkNonSymmetricMatrix(final RealMatrix m) {
186 try {
187 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(m, 1.0e-15);
188
189 RealMatrix d = ed.getD();
190 RealMatrix v = ed.getV();
191
192 RealMatrix x = m.multiply(v);
193 RealMatrix y = v.multiply(d);
194
195 double diffNorm = x.subtract(y).getNorm1();
196 assertTrue(x.subtract(y).getNorm1() < 1000 * Precision.EPSILON * FastMath.max(x.getNorm1(), y.getNorm1()),
197 "The norm of (X-Y) is too large: " + diffNorm + ", matrix=" + m.toString());
198
199 RealMatrix invV = new LUDecomposition(v).getSolver().getInverse();
200 double norm = v.multiply(d).multiply(invV).subtract(m).getNorm1();
201 assertEquals(0.0, norm, 1.0e-10);
202 } catch (Exception e) {
203 fail("Failed to create EigenDecomposition for matrix " + m.toString() + ", ex=" + e.toString());
204 }
205 }
206
207
208 @Test
209 void testEigenvectors() {
210 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(matrix);
211 FieldMatrix<Complex> cMatrix = MatrixUtils.createFieldMatrix(ComplexField.getInstance(),
212 matrix.getRowDimension(),
213 matrix.getColumnDimension());
214 for (int i = 0; i < matrix.getRowDimension(); ++i) {
215 for (int j = 0; j < matrix.getColumnDimension(); ++j) {
216 cMatrix.setEntry(i, j, new Complex(matrix.getEntry(j, i)));
217 }
218 }
219
220 for (int i = 0; i < matrix.getRowDimension(); ++i) {
221 final Complex lambda = ed.getEigenvalue(i);
222 final FieldVector<Complex> v = ed.getEigenvector(i);
223 final FieldVector<Complex> mV = cMatrix.operate(v);
224 for (int k = 0; k < v.getDimension(); ++k) {
225 assertEquals(0, mV.getEntry(k).subtract(v.getEntry(k).multiply(lambda)).norm(), 1.0e-13);
226 }
227 }
228 }
229
230
231 @Test
232 void testAEqualVDVInv() {
233 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(matrix);
234 RealMatrix v = ed.getV();
235 RealMatrix d = ed.getD();
236 RealMatrix vI = MatrixUtils.inverse(v);
237 double norm = v.multiply(d).multiply(vI).subtract(matrix).getNorm1();
238 assertEquals(0, norm, 6.0e-13);
239 }
240
241
242
243
244 @Test
245 void testDistinctEigenvalues() {
246 RealMatrix distinct = MatrixUtils.createRealMatrix(new double[][] {
247 {3, 1, -4},
248 {1, 3, -4},
249 {-4, -4, 8}
250 });
251 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(distinct);
252 checkEigenValues((new Complex[] { new Complex( 2), new Complex( 0), new Complex(12) }), ed, 1E-12);
253 checkEigenVector((new Complex[] { new Complex( 1), new Complex(-1), new Complex( 0) }), ed, 1E-12);
254 checkEigenVector((new Complex[] { new Complex( 1), new Complex( 1), new Complex( 1) }), ed, 1E-12);
255 checkEigenVector((new Complex[] { new Complex(-1), new Complex(-1), new Complex( 2) }), ed, 1E-12);
256 }
257
258
259
260
261 @Test
262 void testZeroDivide() {
263 RealMatrix indefinite = MatrixUtils.createRealMatrix(new double [][] {
264 { 0.0, 1.0, -1.0 },
265 { 1.0, 1.0, 0.0 },
266 { -1.0,0.0, 1.0 }
267 });
268 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(indefinite);
269 checkEigenValues((new Complex[] { new Complex(2), new Complex(1), new Complex(-1) }), ed, 1E-12);
270 Complex isqrt3 = new Complex(1 / FastMath.sqrt(3.0));
271 checkEigenVector((new Complex[] {isqrt3, isqrt3, isqrt3.negate() }), ed, 1E-12);
272 Complex isqrt2 = new Complex(1 / FastMath.sqrt(2.0));
273 checkEigenVector((new Complex[] { new Complex(0.0), isqrt2.negate(), isqrt2.negate() }), ed, 1E-12);
274 Complex isqrt6 = new Complex(1 / FastMath.sqrt(6.0));
275 checkEigenVector((new Complex[] { isqrt6.multiply(2), isqrt6.negate(), isqrt6 }), ed, 1E-12);
276 }
277
278
279 @Test
280 void testBigMatrix() {
281 Random r = new Random(17748333525117l);
282 double[] bigValues = new double[200];
283 for (int i = 0; i < bigValues.length; ++i) {
284 bigValues[i] = 2 * r.nextDouble() - 1;
285 }
286 Arrays.sort(bigValues);
287 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(createTestMatrix(r, bigValues));
288 Complex[] eigenValues = ed.getEigenvalues();
289 Arrays.sort(eigenValues, new ComplexComparator());
290 assertEquals(bigValues.length, eigenValues.length);
291 for (int i = 0; i < bigValues.length; ++i) {
292 assertEquals(bigValues[i], eigenValues[i].getRealPart(), 2.0e-14);
293 }
294 }
295
296
297
298
299
300 @Test
301 void testTinyValues() {
302 final double tiny = 1.0e-100;
303 RealMatrix distinct = MatrixUtils.createRealMatrix(new double[][] {
304 {3, 1, -4},
305 {1, 3, -4},
306 {-4, -4, 8}
307 });
308 distinct = distinct.scalarMultiply(tiny);
309
310 final EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(distinct);
311 checkEigenValues(new Complex[] { new Complex(2).multiply(tiny), new Complex(0).multiply(tiny), new Complex(12).multiply(tiny) },
312 ed, 1e-12 * tiny);
313 checkEigenVector(new Complex[] { new Complex( 1), new Complex(-1), new Complex(0) }, ed, 1e-12);
314 checkEigenVector(new Complex[] { new Complex( 1), new Complex( 1), new Complex(1) }, ed, 1e-12);
315 checkEigenVector(new Complex[] { new Complex(-1), new Complex(-1), new Complex(2) }, ed, 1e-12);
316 }
317
318 @Test
319 void testDeterminantWithCompleEigenValues() {
320 final RealMatrix m = MatrixUtils.createRealMatrix(new double[][] { { -3, -1.5, -3 }, { 0, -1, 0 }, { 1, 0, 0 } });
321 EigenDecompositionNonSymmetric decomposition = new EigenDecompositionNonSymmetric(m);
322 assertEquals(-3.0, decomposition.getDeterminant().getRealPart(), 1.0e-15);
323 assertEquals( 0.0, decomposition.getDeterminant().getImaginaryPart(), 1.0e-15);
324 }
325
326 @Test
327 void testReal() {
328
329
330 RealMatrix A = MatrixUtils.createRealMatrix(new double[][] {
331 { 1, 2 }, { 1, -3 }
332 });
333
334 EigenDecompositionNonSymmetric ed = new EigenDecompositionNonSymmetric(A);
335
336 assertNotNull(ed.getD());
337 assertNotNull(ed.getV());
338
339 final double s2 = FastMath.sqrt(2);
340 final double s3 = FastMath.sqrt(3);
341 RealMatrix D_expected = MatrixUtils.createRealMatrix(new double[][] {
342 { s2 * s3 - 1.0, 0 }, { 0, -1 - s2 * s3 }
343 });
344
345 RealMatrix V_expected = MatrixUtils.createRealMatrix(new double[][] {
346 { (s2 + 2 * s3) / 5, (s3 - 3 * s2) / 6 },
347 { (2 * s2 - s3) / 5, (4 * s3 + 3 * s2) / 12 }
348 });
349
350 UnitTestUtils.customAssertEquals("D", D_expected, ed.getD(), 1.0e-15);
351 UnitTestUtils.customAssertEquals("V", V_expected, ed.getV(), 1.0e-15);
352
353
354 UnitTestUtils.customAssertEquals("A", A,
355 ed.getV().multiply(ed.getD()).multiply(MatrixUtils.inverse(ed.getV())),
356 2.0e-15);
357
358 }
359
360 @Test
361 void testImaginary() {
362
363
364 RealMatrix A = MatrixUtils.createRealMatrix(new double[][] {
365 { 3, -2 }, { 4, -1 }
366 });
367
368 EigenDecompositionNonSymmetric ordEig = new EigenDecompositionNonSymmetric(A);
369
370 assertNotNull(ordEig.getD());
371 assertNotNull(ordEig.getV());
372
373 RealMatrix D_expected = MatrixUtils.createRealMatrix(new double[][] {
374 { 1, 2 }, { -2, 1 }
375 });
376
377 RealMatrix V_expected = MatrixUtils.createRealMatrix(new double[][] {
378 { -0.5, 0.5 }, { 0, 1 }
379 });
380
381 UnitTestUtils.customAssertEquals("D", D_expected, ordEig.getD(), 1.0e-15);
382 UnitTestUtils.customAssertEquals("V", V_expected, ordEig.getV(), 1.0e-15);
383
384
385 UnitTestUtils.customAssertEquals("A", A, ordEig.getV().multiply(ordEig.getD()).multiply(MatrixUtils.inverse(ordEig.getV())), 1.0e-15);
386
387
388 FieldMatrix<Complex> ac = new Array2DRowFieldMatrix<>(ComplexField.getInstance(), 2, 2);
389 for (int i = 0; i < ac.getRowDimension(); ++i) {
390 for (int j = 0; j < ac.getColumnDimension(); ++j) {
391 ac.setEntry(i, j, new Complex(A.getEntry(i, j)));
392 }
393 }
394 for (int i = 0; i < ordEig.getEigenvalues().length; ++i) {
395 final Complex li = ordEig.getEigenvalue(i);
396 final FieldVector<Complex> ei = ordEig.getEigenvector(i);
397 final FieldVector<Complex> aei = ac.operate(ei);
398 for (int j = 0; j < ei.getDimension(); ++j) {
399 assertEquals(aei.getEntry(j).getRealPart(), li.multiply(ei.getEntry(j)).getRealPart(), 1.0e-10);
400 assertEquals(aei.getEntry(j).getImaginaryPart(), li.multiply(ei.getEntry(j)).getImaginaryPart(), 1.0e-10);
401 }
402 }
403
404 }
405
406 @Test
407 void testImaginary33() {
408
409
410 RealMatrix A = MatrixUtils.createRealMatrix(new double[][] {
411 { 3, -2, 0 }, { 4, -1, 0 }, { 1, 1, 1 }
412 });
413
414 EigenDecompositionNonSymmetric ordEig = new EigenDecompositionNonSymmetric(A);
415
416 assertNotNull(ordEig.getD());
417 assertNotNull(ordEig.getV());
418
419 RealMatrix D_expected = MatrixUtils.createRealMatrix(new double[][] {
420 { 1, 2, 0 }, { -2, 1, 0}, {0, 0, 1 }
421 });
422
423 final double a = FastMath.sqrt(8.0 / 17.0);
424 final double b = FastMath.sqrt(17.0) / 2.0;
425 RealMatrix V_expected = MatrixUtils.createRealMatrix(new double[][] {
426 { 0, a, 0 },
427 { a, a, 0 },
428 { a, -0.5 * a, b }
429 });
430 UnitTestUtils.customAssertEquals("D", D_expected, ordEig.getD(), 1.0e-15);
431 UnitTestUtils.customAssertEquals("V", V_expected, ordEig.getV(), 1.0e-15);
432
433
434 UnitTestUtils.customAssertEquals("A", A,
435 ordEig.getV().multiply(ordEig.getD()).multiply(MatrixUtils.inverse(ordEig.getV())),
436 8.0e-15);
437
438
439 FieldMatrix<Complex> ac = new Array2DRowFieldMatrix<>(ComplexField.getInstance(), 3, 3);
440 for (int i = 0; i < ac.getRowDimension(); ++i) {
441 for (int j = 0; j < ac.getColumnDimension(); ++j) {
442 ac.setEntry(i, j, new Complex(A.getEntry(i, j)));
443 }
444 }
445 for (int i = 0; i < ordEig.getEigenvalues().length; ++i) {
446 final Complex li = ordEig.getEigenvalue(i);
447 final FieldVector<Complex> ei = ordEig.getEigenvector(i);
448 final FieldVector<Complex> aei = ac.operate(ei);
449 for (int j = 0; j < ei.getDimension(); ++j) {
450 assertEquals(aei.getEntry(j).getRealPart(), li.multiply(ei.getEntry(j)).getRealPart(), 1.0e-10);
451 assertEquals(aei.getEntry(j).getImaginaryPart(), li.multiply(ei.getEntry(j)).getImaginaryPart(), 1.0e-10);
452 }
453 }
454
455 }
456
457 @Test
458 void testImaginaryNullEigenvalue() {
459
460
461 RealMatrix A = MatrixUtils.createRealMatrix(new double[][] {
462 { 3, -2, 0 }, { 4, -1, 0 }, { 3, -2, 0 }
463 });
464
465 EigenDecompositionNonSymmetric ordEig = new EigenDecompositionNonSymmetric(A);
466
467 assertNotNull(ordEig.getD());
468 assertNotNull(ordEig.getV());
469
470 RealMatrix D_expected = MatrixUtils.createRealMatrix(new double[][] {
471 { 1, 2, 0 }, { -2, 1, 0 }, { 0, 0, 0 }
472 });
473
474 final double a = FastMath.sqrt(11.0 / 50.0);
475 final double s2 = FastMath.sqrt(2.0);
476 RealMatrix V_expected = MatrixUtils.createRealMatrix(new double[][] {
477 { -a, -2 * a, 0.0 },
478 { -3 * a, -a, 0.0 },
479 { -a, -2 * a, s2 }
480 });
481
482 UnitTestUtils.customAssertEquals("D", D_expected, ordEig.getD(), 1.0e-15);
483 UnitTestUtils.customAssertEquals("V", V_expected, ordEig.getV(), 2.0e-15);
484
485
486 UnitTestUtils.customAssertEquals("A", A,
487 ordEig.getV().multiply(ordEig.getD()).multiply(MatrixUtils.inverse(ordEig.getV())),
488 1.0e-14);
489
490
491 FieldMatrix<Complex> ac = new Array2DRowFieldMatrix<>(ComplexField.getInstance(), 3, 3);
492 for (int i = 0; i < ac.getRowDimension(); ++i) {
493 for (int j = 0; j < ac.getColumnDimension(); ++j) {
494 ac.setEntry(i, j, new Complex(A.getEntry(i, j)));
495 }
496 }
497
498 for (int i = 0; i < ordEig.getEigenvalues().length; ++i) {
499 final Complex li = ordEig.getEigenvalue(i);
500 final FieldVector<Complex> ei = ordEig.getEigenvector(i);
501 final FieldVector<Complex> aei = ac.operate(ei);
502 for (int j = 0; j < ei.getDimension(); ++j) {
503 assertEquals(aei.getEntry(j).getRealPart(), li.multiply(ei.getEntry(j)).getRealPart(), 1.0e-10);
504 assertEquals(aei.getEntry(j).getImaginaryPart(), li.multiply(ei.getEntry(j)).getImaginaryPart(), 1.0e-10);
505 }
506 }
507
508 }
509
510
511
512
513
514
515 protected void checkEigenValues(Complex[] targetValues,
516 EigenDecompositionNonSymmetric ed, double tolerance) {
517 Complex[] observed = ed.getEigenvalues();
518 for (int i = 0; i < observed.length; i++) {
519 assertTrue(isIncludedValue(observed[i], targetValues, tolerance));
520 assertTrue(isIncludedValue(targetValues[i], observed, tolerance));
521 }
522 }
523
524
525
526
527
528
529 private boolean isIncludedValue(Complex value, Complex[] searchArray, double tolerance) {
530 boolean found = false;
531 int i = 0;
532 while (!found && i < searchArray.length) {
533 if (value.subtract(searchArray[i]).norm() < tolerance) {
534 found = true;
535 }
536 i++;
537 }
538 return found;
539 }
540
541
542
543
544
545
546 protected void checkEigenVector(Complex[] eigenVector, EigenDecompositionNonSymmetric ed, double tolerance) {
547 assertTrue(isIncludedColumn(eigenVector, ed.getV(), tolerance));
548 }
549
550
551
552
553
554 private boolean isIncludedColumn(Complex[] column, RealMatrix searchMatrix, double tolerance) {
555 boolean found = false;
556 int i = 0;
557 while (!found && i < searchMatrix.getColumnDimension()) {
558 Complex multiplier = Complex.ONE;
559 boolean matching = true;
560 int j = 0;
561 while (matching && j < searchMatrix.getRowDimension()) {
562 double colEntry = searchMatrix.getEntry(j, i);
563
564 if (multiplier.subtract(1).norm() <= FastMath.ulp(1.0) && FastMath.abs(colEntry) > 1E-14
565 && column[j].norm() > 1e-14) {
566 multiplier = column[j].reciprocal().multiply(colEntry);
567 }
568 if (column[j].multiply(multiplier).subtract(colEntry).norm() > tolerance) {
569 matching = false;
570 }
571 j++;
572 }
573 found = matching;
574 i++;
575 }
576 return found;
577 }
578
579 @BeforeEach
580 void setUp() {
581 double[] real = {
582 0.001, 1.000, 1.001, 2.001, 2.002, 2.003
583 };
584 refValues = new Complex[real.length];
585 for (int i = 0; i < refValues.length; ++i) {
586 refValues[i] = new Complex(real[i]);
587 }
588 matrix = createTestMatrix(new Random(35992629946426l), real);
589 }
590
591 @AfterEach
592 void tearDown() {
593 refValues = null;
594 matrix = null;
595 }
596
597 static RealMatrix createTestMatrix(final Random r, final double[] eigenValues) {
598 final int n = eigenValues.length;
599 final RealMatrix v = createOrthogonalMatrix(r, n);
600 final RealMatrix d = MatrixUtils.createRealDiagonalMatrix(eigenValues);
601 return v.multiply(d).multiplyTransposed(v);
602 }
603
604 public static RealMatrix createOrthogonalMatrix(final Random r, final int size) {
605
606 final double[][] data = new double[size][size];
607
608 for (int i = 0; i < size; ++i) {
609 final double[] dataI = data[i];
610 double norm2 = 0;
611 do {
612
613
614 for (int j = 0; j < size; ++j) {
615 dataI[j] = 2 * r.nextDouble() - 1;
616 }
617
618
619 for (int k = 0; k < i; ++k) {
620 final double[] dataK = data[k];
621 double dotProduct = 0;
622 for (int j = 0; j < size; ++j) {
623 dotProduct += dataI[j] * dataK[j];
624 }
625 for (int j = 0; j < size; ++j) {
626 dataI[j] -= dotProduct * dataK[j];
627 }
628 }
629
630
631 norm2 = 0;
632 for (final double dataIJ : dataI) {
633 norm2 += dataIJ * dataIJ;
634 }
635 final double inv = 1.0 / FastMath.sqrt(norm2);
636 for (int j = 0; j < size; ++j) {
637 dataI[j] *= inv;
638 }
639
640 } while (norm2 * size < 0.01);
641 }
642
643 return MatrixUtils.createRealMatrix(data);
644
645 }
646 }