View Javadoc
1   /*
2    * Licensed to the Hipparchus project 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 Hipparchus project 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    *      https://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.hipparchus.linear;
18  
19  import org.hipparchus.UnitTestUtils;
20  import org.hipparchus.complex.Complex;
21  import org.junit.jupiter.api.Test;
22  
23  import static org.junit.jupiter.api.Assertions.assertEquals;
24  import static org.junit.jupiter.api.Assertions.assertNotNull;
25  
26  class OrderedComplexEigenDecompositionTest {
27  
28      private final RealMatrix A = MatrixUtils.createRealMatrix(new double[][] {
29          { 3, -2 }, { 4, -1 } });
30  
31      @Test
32      void testDefinition() {
33          OrderedComplexEigenDecomposition eigenDecomp = new OrderedComplexEigenDecomposition(A);
34  
35          FieldMatrix<Complex> A = MatrixUtils.createFieldMatrix(new Complex[][] {
36              { new Complex(3, 0), new Complex(-2, 0) },
37              { new Complex(4, 0), new Complex(-1, 0) } });
38  
39          double threshold = 1.0e-15;
40  
41          // testing AV = lamba V - [0]
42          compareVectors(A.operate(eigenDecomp.getEigenvector(0)),
43                         eigenDecomp.getEigenvector(0).mapMultiply(eigenDecomp.getEigenvalues()[0]),
44                         threshold);
45  
46          // testing AV = lamba V - [1]
47          compareVectors(A.operate(eigenDecomp.getEigenvector(1)),
48                         eigenDecomp.getEigenvector(1).mapMultiply(eigenDecomp.getEigenvalues()[1]),
49                         threshold);
50  
51          // checking definition of the decomposition A*V = V*D
52          compareMatrices(A.multiply(eigenDecomp.getV()),
53                          eigenDecomp.getV().multiply(eigenDecomp.getD()),
54                          threshold);
55  
56      }
57  
58      @Test
59      void testIssue173() {
60  
61          OrderedComplexEigenDecomposition eigenDecomp = new OrderedComplexEigenDecomposition(A);
62  
63          UnitTestUtils.customAssertEquals(eigenDecomp.getEigenvalues()[0], eigenDecomp.getD().getEntry(0, 0), 1.0e-10);
64          UnitTestUtils.customAssertEquals(eigenDecomp.getEigenvalues()[1], eigenDecomp.getD().getEntry(1, 1), 1.0e-10);
65  
66          UnitTestUtils.customAssertEquals(eigenDecomp.getEigenvector(0).getEntry(0), eigenDecomp.getV().getEntry(0, 0), 1.0e-10);
67          UnitTestUtils.customAssertEquals(eigenDecomp.getEigenvector(0).getEntry(1), eigenDecomp.getV().getEntry(1, 0), 1.0e-10);
68          UnitTestUtils.customAssertEquals(eigenDecomp.getEigenvector(1).getEntry(0), eigenDecomp.getV().getEntry(0, 1), 1.0e-10);
69          UnitTestUtils.customAssertEquals(eigenDecomp.getEigenvector(1).getEntry(1), eigenDecomp.getV().getEntry(1, 0), 1.0e-10);
70  
71      }
72  
73      @Test
74      void testEqualEigenValues() {
75          double[][] d = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
76          Array2DRowRealMatrix matrix = new Array2DRowRealMatrix(d);
77          ComplexEigenDecomposition ed = new OrderedComplexEigenDecomposition(matrix);
78          for (Complex z : ed.getEigenvalues()) {
79              assertEquals(1.0, z.getReal(),      1.0e-15);
80              assertEquals(0.0, z.getImaginary(), 1.0e-15);
81          }
82      }
83  
84      @Test
85      void testIssue111A() {
86          RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
87              {-0.0,0.0000002463,-0.000000462,0.0,-0.2843196976,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
88              {-0.0000002463,-0.0,0.0000004577,0.0,-0.0,-0.2843196976,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
89              {0.000000462,-0.0000004577,-0.0,0.0,-0.0,-0.0,-0.2843196976,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
90              {-0.0000004577,-0.000000462,-0.0000002463,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
91              {0.0,0.0,0.0,0.0,-0.0000000015,0.0000005751,-0.0000015871,0.0,0.0,0.0,0.0,-0.0000104075,0.0,0.0},
92              {0.0,0.0,0.0,0.0,-0.000000421,-0.0000000048,0.0000013528,0.0,0.0,0.0,0.0,0.0,-0.000007717,0.0},
93              {0.0,0.0,0.0,0.0,0.0000005375,-0.00000062,0.0000000063,0.0,0.0,0.0,0.0,0.0,0.0,-0.0000035509},
94              {-1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0000002463,-0.000000462,0.0000004577,0.0,0.0,0.0},
95              {0.0,-1.0,0.0,0.0,0.0,0.0,0.0,-0.0000002463,0.0,0.0000004577,0.000000462,0.0,0.0,0.0},
96              {0.0,0.0,-1.0,0.0,0.0,0.0,0.0,0.000000462,-0.0000004577,0.0,0.0000002463,0.0,0.0,0.0},
97              {0.0,0.0,0.0,-1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
98              {0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.2843196976,0.0,0.0,0.0,0.0000000015,0.000000421,-0.0000005375},
99              {0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.2843196976,0.0,0.0,-0.0000005751,0.0000000048,0.00000062},
100             {0.0,0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.2843196976,0.0,0.0000015871,-0.0000013528,-0.0000000063}
101         });
102         
103         assertNotNull(new OrderedComplexEigenDecomposition(m,
104                                                                   1.0e-6,
105                                                                   ComplexEigenDecomposition.DEFAULT_EPSILON,
106                                                                   ComplexEigenDecomposition.DEFAULT_EPSILON_AV_VD_CHECK));
107         
108     }
109 
110 
111     @Test
112     void testIssue111B() {
113         RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
114             {-0.0,0.0000002463,-0.000000462,0.0,-0.1095029805,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
115             {-0.0000002463,-0.0,0.0000004577,0.0,-0.0,-0.1095029805,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
116             {0.000000462,-0.0000004577,-0.0,0.0,-0.0,-0.0,-0.1095029805,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
117             {-0.0000004577,-0.000000462,-0.0000002463,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
118             {0.0,0.0,0.0,0.0,-0.0000000015,0.0000005751,-0.0000015871,0.0,0.0,0.0,0.0,-0.0000104075,0.0,0.0},
119             {0.0,0.0,0.0,0.0,-0.000000421,-0.0000000048,0.0000013528,0.0,0.0,0.0,0.0,0.0,-0.000007717,0.0},
120             {0.0,0.0,0.0,0.0,0.0000005375,-0.00000062,0.0000000063,0.0,0.0,0.0,0.0,0.0,0.0,-0.0000035509},
121             {-1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0000002463,-0.000000462,0.0000004577,0.0,0.0,0.0},
122             {0.0,-1.0,0.0,0.0,0.0,0.0,0.0,-0.0000002463,0.0,0.0000004577,0.000000462,0.0,0.0,0.0},
123             {0.0,0.0,-1.0,0.0,0.0,0.0,0.0,0.000000462,-0.0000004577,0.0,0.0000002463,0.0,0.0,0.0},
124             {0.0,0.0,0.0,-1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
125             {0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.1095029805,0.0,0.0,0.0,0.0000000015,0.000000421,-0.0000005375},
126             {0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.1095029805,0.0,0.0,-0.0000005751,0.0000000048,0.00000062},
127             {0.0,0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.1095029805,0.0,0.0000015871,-0.0000013528,-0.0000000063}
128         });
129         
130         assertNotNull(new OrderedComplexEigenDecomposition(m,
131                                                                   1.0e-6,
132                                                                   ComplexEigenDecomposition.DEFAULT_EPSILON,
133                                                                   ComplexEigenDecomposition.DEFAULT_EPSILON_AV_VD_CHECK));
134         
135     }
136 
137     @Test
138     void testIssue111C() {
139         RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
140             {-0.0,0.0000002463,-0.000000462,0.0,-0.109502989,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
141             {-0.0000002463,-0.0,0.0000004577,0.0,-0.0,-0.109502989,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
142             {0.000000462,-0.0000004577,-0.0,0.0,-0.0,-0.0,-0.109502989,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
143             {-0.0000004577,-0.000000462,-0.0000002463,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
144             {0.0,0.0,0.0,0.0,-0.0000000015,0.0000005751,-0.0000015871,0.0,0.0,0.0,0.0,-0.0000104075,0.0,0.0},
145             {0.0,0.0,0.0,0.0,-0.000000421,-0.0000000048,0.0000013528,0.0,0.0,0.0,0.0,0.0,-0.000007717,0.0},
146             {0.0,0.0,0.0,0.0,0.0000005375,-0.00000062,0.0000000063,0.0,0.0,0.0,0.0,0.0,0.0,-0.0000035509},
147             {-1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0000002463,-0.000000462,0.0000004577,0.0,0.0,0.0},
148             {0.0,-1.0,0.0,0.0,0.0,0.0,0.0,-0.0000002463,0.0,0.0000004577,0.000000462,0.0,0.0,0.0},
149             {0.0,0.0,-1.0,0.0,0.0,0.0,0.0,0.000000462,-0.0000004577,0.0,0.0000002463,0.0,0.0,0.0},
150             {0.0,0.0,0.0,-1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
151             {0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.109502989,0.0,0.0,0.0,0.0000000015,0.000000421,-0.0000005375},
152             {0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.109502989,0.0,0.0,-0.0000005751,0.0000000048,0.00000062},
153             {0.0,0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.109502989,0.0,0.0000015871,-0.0000013528,-0.0000000063}
154         });
155         
156         assertNotNull(new OrderedComplexEigenDecomposition(m,
157                                                                   1.0e-6,
158                                                                   ComplexEigenDecomposition.DEFAULT_EPSILON,
159                                                                   ComplexEigenDecomposition.DEFAULT_EPSILON_AV_VD_CHECK));
160         
161     }
162 
163     /**
164      * Verify two complex vectors.
165      * @param vector1 first vector
166      * @param vector2 second vector
167      * @param threshold threshold
168      */
169     private static void compareVectors(final FieldVector<Complex> vector1,
170                                        final FieldVector<Complex> vector2,
171                                        final double threshold) {
172 
173         // Verify size
174         assertEquals(vector1.getDimension(), vector2.getDimension());
175 
176         // Loop on vector entries
177         for (int index = 0; index < vector1.getDimension(); index++) {
178             final Complex complex1 = vector1.getEntry(index);
179             final Complex complex2 = vector2.getEntry(index);
180             assertEquals(complex1.getReal(),      complex2.getReal(),      threshold);
181             assertEquals(complex1.getImaginary(), complex2.getImaginary(), threshold);
182         }
183 
184     }
185 
186     /**
187      * Verify two complex matrices.
188      * @param matrix1 first matrix
189      * @param matrix2 second matrix
190      * @param threshold threshold
191      */
192     private static void compareMatrices(final FieldMatrix<Complex> matrix1,
193                                         final FieldMatrix<Complex> matrix2,
194                                         final double threshold) {
195 
196         // Verify size
197         assertEquals(matrix1.getRowDimension(),    matrix2.getRowDimension());
198         assertEquals(matrix1.getColumnDimension(), matrix2.getColumnDimension());
199 
200         // Loop on matrices entries
201         for (int row = 0; row < matrix1.getRowDimension(); row++) {
202             for (int column = 0; column < matrix1.getColumnDimension(); column++) {
203                 final Complex complex1 = matrix1.getEntry(row, column);
204                 final Complex complex2 = matrix2.getEntry(row, column);
205                 assertEquals(complex1.getReal(),      complex2.getReal(),      threshold);
206                 assertEquals(complex1.getImaginary(), complex2.getImaginary(), threshold);
207             }
208 
209         }
210 
211     }
212 
213 }