View Javadoc
1   /*
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
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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.linear;
24  
25  import org.hipparchus.util.FastMath;
26  import org.junit.Assert;
27  import org.junit.Test;
28  
29  public class BiDiagonalTransformerTest {
30  
31      private double[][] testSquare = {
32              { 24.0 / 25.0, 43.0 / 25.0 },
33              { 57.0 / 25.0, 24.0 / 25.0 }
34      };
35  
36      private double[][] testNonSquare = {
37          {  -540.0 / 625.0,  963.0 / 625.0, -216.0 / 625.0 },
38          { -1730.0 / 625.0, -744.0 / 625.0, 1008.0 / 625.0 },
39          {  -720.0 / 625.0, 1284.0 / 625.0, -288.0 / 625.0 },
40          {  -360.0 / 625.0,  192.0 / 625.0, 1756.0 / 625.0 },
41      };
42  
43      @Test
44      public void testDimensions() {
45          checkdimensions(MatrixUtils.createRealMatrix(testSquare));
46          checkdimensions(MatrixUtils.createRealMatrix(testNonSquare));
47          checkdimensions(MatrixUtils.createRealMatrix(testNonSquare).transpose());
48      }
49  
50      private void checkdimensions(RealMatrix matrix) {
51          final int m = matrix.getRowDimension();
52          final int n = matrix.getColumnDimension();
53          BiDiagonalTransformer transformer = new BiDiagonalTransformer(matrix);
54          Assert.assertEquals(m, transformer.getU().getRowDimension());
55          Assert.assertEquals(m, transformer.getU().getColumnDimension());
56          Assert.assertEquals(m, transformer.getB().getRowDimension());
57          Assert.assertEquals(n, transformer.getB().getColumnDimension());
58          Assert.assertEquals(n, transformer.getV().getRowDimension());
59          Assert.assertEquals(n, transformer.getV().getColumnDimension());
60  
61      }
62  
63      @Test
64      public void testAEqualUSVt() {
65          checkAEqualUSVt(MatrixUtils.createRealMatrix(testSquare));
66          checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare));
67          checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare).transpose());
68      }
69  
70      private void checkAEqualUSVt(RealMatrix matrix) {
71          BiDiagonalTransformer transformer = new BiDiagonalTransformer(matrix);
72          RealMatrix u = transformer.getU();
73          RealMatrix b = transformer.getB();
74          RealMatrix v = transformer.getV();
75          double norm = u.multiply(b).multiplyTransposed(v).subtract(matrix).getNorm1();
76          Assert.assertEquals(0, norm, 1.0e-14);
77      }
78  
79      @Test
80      public void testUOrthogonal() {
81          checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getU());
82          checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getU());
83          checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getU());
84      }
85  
86      @Test
87      public void testVOrthogonal() {
88          checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getV());
89          checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getV());
90          checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getV());
91      }
92  
93      private void checkOrthogonal(RealMatrix m) {
94          RealMatrix mTm = m.transposeMultiply(m);
95          RealMatrix id  = MatrixUtils.createRealIdentityMatrix(mTm.getRowDimension());
96          Assert.assertEquals(0, mTm.subtract(id).getNorm1(), 1.0e-14);
97      }
98  
99      @Test
100     public void testBBiDiagonal() {
101         checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getB());
102         checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getB());
103         checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getB());
104     }
105 
106     private void checkBiDiagonal(RealMatrix m) {
107         final int rows = m.getRowDimension();
108         final int cols = m.getColumnDimension();
109         for (int i = 0; i < rows; ++i) {
110             for (int j = 0; j < cols; ++j) {
111                 if (rows < cols) {
112                     if ((i < j) || (i > j + 1)) {
113                         Assert.assertEquals(0, m.getEntry(i, j), 1.0e-16);
114                     }
115                 } else {
116                     if ((i < j - 1) || (i > j)) {
117                         Assert.assertEquals(0, m.getEntry(i, j), 1.0e-16);
118                     }
119                 }
120             }
121         }
122     }
123 
124     @Test
125     public void testSingularMatrix() {
126        BiDiagonalTransformer transformer =
127             new BiDiagonalTransformer(MatrixUtils.createRealMatrix(new double[][] {
128                 { 1.0, 2.0, 3.0 },
129                 { 2.0, 3.0, 4.0 },
130                 { 3.0, 5.0, 7.0 }
131             }));
132        final double s3  = FastMath.sqrt(3.0);
133        final double s14 = FastMath.sqrt(14.0);
134        final double s1553 = FastMath.sqrt(1553.0);
135        RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] {
136            {  -1.0 / s14,  5.0 / (s3 * s14),  1.0 / s3 },
137            {  -2.0 / s14, -4.0 / (s3 * s14),  1.0 / s3 },
138            {  -3.0 / s14,  1.0 / (s3 * s14), -1.0 / s3 }
139        });
140        RealMatrix bRef = MatrixUtils.createRealMatrix(new double[][] {
141            { -s14, s1553 / s14,   0.0 },
142            {  0.0, -87 * s3 / (s14 * s1553), -s3 * s14 / s1553 },
143            {  0.0, 0.0, 0.0 }
144        });
145        RealMatrix vRef = MatrixUtils.createRealMatrix(new double[][] {
146            { 1.0,   0.0,         0.0        },
147            { 0.0,  -23 / s1553,  32 / s1553 },
148            { 0.0,  -32 / s1553, -23 / s1553 }
149        });
150 
151        // check values against known references
152        RealMatrix u = transformer.getU();
153        Assert.assertEquals(0, u.subtract(uRef).getNorm1(), 1.0e-14);
154        RealMatrix b = transformer.getB();
155        Assert.assertEquals(0, b.subtract(bRef).getNorm1(), 1.0e-14);
156        RealMatrix v = transformer.getV();
157        Assert.assertEquals(0, v.subtract(vRef).getNorm1(), 1.0e-14);
158 
159        // check the same cached instance is returned the second time
160        Assert.assertTrue(u == transformer.getU());
161        Assert.assertTrue(b == transformer.getB());
162        Assert.assertTrue(v == transformer.getV());
163 
164     }
165 
166     @Test
167     public void testMatricesValues() {
168        BiDiagonalTransformer transformer =
169             new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare));
170        final double s17 = FastMath.sqrt(17.0);
171         RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] {
172                 {  -8 / (5 * s17), 19 / (5 * s17) },
173                 { -19 / (5 * s17), -8 / (5 * s17) }
174         });
175         RealMatrix bRef = MatrixUtils.createRealMatrix(new double[][] {
176                 { -3 * s17 / 5, 32 * s17 / 85 },
177                 {      0.0,     -5 * s17 / 17 }
178         });
179         RealMatrix vRef = MatrixUtils.createRealMatrix(new double[][] {
180                 { 1.0,  0.0 },
181                 { 0.0, -1.0 }
182         });
183 
184         // check values against known references
185         RealMatrix u = transformer.getU();
186         Assert.assertEquals(0, u.subtract(uRef).getNorm1(), 1.0e-14);
187         RealMatrix b = transformer.getB();
188         Assert.assertEquals(0, b.subtract(bRef).getNorm1(), 1.0e-14);
189         RealMatrix v = transformer.getV();
190         Assert.assertEquals(0, v.subtract(vRef).getNorm1(), 1.0e-14);
191 
192         // check the same cached instance is returned the second time
193         Assert.assertTrue(u == transformer.getU());
194         Assert.assertTrue(b == transformer.getB());
195         Assert.assertTrue(v == transformer.getV());
196 
197     }
198 
199     @Test
200     public void testUpperOrLower() {
201         Assert.assertTrue(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).isUpperBiDiagonal());
202         Assert.assertTrue(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).isUpperBiDiagonal());
203         Assert.assertFalse(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).isUpperBiDiagonal());
204     }
205 
206 }