001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.math.linear;
019
020 import org.apache.commons.math.linear.BiDiagonalTransformer;
021 import org.apache.commons.math.linear.MatrixUtils;
022 import org.apache.commons.math.linear.RealMatrix;
023
024 import junit.framework.Test;
025 import junit.framework.TestCase;
026 import junit.framework.TestSuite;
027
028 public class BiDiagonalTransformerTest extends TestCase {
029
030 private double[][] testSquare = {
031 { 24.0 / 25.0, 43.0 / 25.0 },
032 { 57.0 / 25.0, 24.0 / 25.0 }
033 };
034
035 private double[][] testNonSquare = {
036 { -540.0 / 625.0, 963.0 / 625.0, -216.0 / 625.0 },
037 { -1730.0 / 625.0, -744.0 / 625.0, 1008.0 / 625.0 },
038 { -720.0 / 625.0, 1284.0 / 625.0, -288.0 / 625.0 },
039 { -360.0 / 625.0, 192.0 / 625.0, 1756.0 / 625.0 },
040 };
041
042 public BiDiagonalTransformerTest(String name) {
043 super(name);
044 }
045
046 public void testDimensions() {
047 checkdimensions(MatrixUtils.createRealMatrix(testSquare));
048 checkdimensions(MatrixUtils.createRealMatrix(testNonSquare));
049 checkdimensions(MatrixUtils.createRealMatrix(testNonSquare).transpose());
050 }
051
052 private void checkdimensions(RealMatrix matrix) {
053 final int m = matrix.getRowDimension();
054 final int n = matrix.getColumnDimension();
055 BiDiagonalTransformer transformer = new BiDiagonalTransformer(matrix);
056 assertEquals(m, transformer.getU().getRowDimension());
057 assertEquals(m, transformer.getU().getColumnDimension());
058 assertEquals(m, transformer.getB().getRowDimension());
059 assertEquals(n, transformer.getB().getColumnDimension());
060 assertEquals(n, transformer.getV().getRowDimension());
061 assertEquals(n, transformer.getV().getColumnDimension());
062
063 }
064
065 public void testAEqualUSVt() {
066 checkAEqualUSVt(MatrixUtils.createRealMatrix(testSquare));
067 checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare));
068 checkAEqualUSVt(MatrixUtils.createRealMatrix(testNonSquare).transpose());
069 }
070
071 private void checkAEqualUSVt(RealMatrix matrix) {
072 BiDiagonalTransformer transformer = new BiDiagonalTransformer(matrix);
073 RealMatrix u = transformer.getU();
074 RealMatrix b = transformer.getB();
075 RealMatrix v = transformer.getV();
076 double norm = u.multiply(b).multiply(v.transpose()).subtract(matrix).getNorm();
077 assertEquals(0, norm, 1.0e-14);
078 }
079
080 public void testUOrthogonal() {
081 checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getU());
082 checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getU());
083 checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getU());
084 }
085
086 public void testVOrthogonal() {
087 checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getV());
088 checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getV());
089 checkOrthogonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getV());
090 }
091
092 private void checkOrthogonal(RealMatrix m) {
093 RealMatrix mTm = m.transpose().multiply(m);
094 RealMatrix id = MatrixUtils.createRealIdentityMatrix(mTm.getRowDimension());
095 assertEquals(0, mTm.subtract(id).getNorm(), 1.0e-14);
096 }
097
098 public void testBBiDiagonal() {
099 checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).getB());
100 checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).getB());
101 checkBiDiagonal(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).getB());
102 }
103
104 private void checkBiDiagonal(RealMatrix m) {
105 final int rows = m.getRowDimension();
106 final int cols = m.getColumnDimension();
107 for (int i = 0; i < rows; ++i) {
108 for (int j = 0; j < cols; ++j) {
109 if (rows < cols) {
110 if ((i < j) || (i > j + 1)) {
111 assertEquals(0, m.getEntry(i, j), 1.0e-16);
112 }
113 } else {
114 if ((i < j - 1) || (i > j)) {
115 assertEquals(0, m.getEntry(i, j), 1.0e-16);
116 }
117 }
118 }
119 }
120 }
121
122 public void testMatricesValues() {
123 BiDiagonalTransformer transformer =
124 new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare));
125 final double s17 = Math.sqrt(17.0);
126 RealMatrix uRef = MatrixUtils.createRealMatrix(new double[][] {
127 { -8 / (5 * s17), 19 / (5 * s17) },
128 { -19 / (5 * s17), -8 / (5 * s17) }
129 });
130 RealMatrix bRef = MatrixUtils.createRealMatrix(new double[][] {
131 { -3 * s17 / 5, 32 * s17 / 85 },
132 { 0.0, -5 * s17 / 17 }
133 });
134 RealMatrix vRef = MatrixUtils.createRealMatrix(new double[][] {
135 { 1.0, 0.0 },
136 { 0.0, -1.0 }
137 });
138
139 // check values against known references
140 RealMatrix u = transformer.getU();
141 assertEquals(0, u.subtract(uRef).getNorm(), 1.0e-14);
142 RealMatrix b = transformer.getB();
143 assertEquals(0, b.subtract(bRef).getNorm(), 1.0e-14);
144 RealMatrix v = transformer.getV();
145 assertEquals(0, v.subtract(vRef).getNorm(), 1.0e-14);
146
147 // check the same cached instance is returned the second time
148 assertTrue(u == transformer.getU());
149 assertTrue(b == transformer.getB());
150 assertTrue(v == transformer.getV());
151
152 }
153
154 public void testUpperOrLower() {
155 assertTrue(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testSquare)).isUpperBiDiagonal());
156 assertTrue(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare)).isUpperBiDiagonal());
157 assertFalse(new BiDiagonalTransformer(MatrixUtils.createRealMatrix(testNonSquare).transpose()).isUpperBiDiagonal());
158 }
159
160 public static Test suite() {
161 return new TestSuite(BiDiagonalTransformerTest.class);
162 }
163
164 }