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 }