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 junit.framework.Test;
021 import junit.framework.TestCase;
022 import junit.framework.TestSuite;
023
024 import org.apache.commons.math.MathException;
025 import org.apache.commons.math.linear.CholeskyDecompositionImpl;
026 import org.apache.commons.math.linear.DecompositionSolver;
027 import org.apache.commons.math.linear.MatrixUtils;
028 import org.apache.commons.math.linear.RealMatrix;
029 import org.apache.commons.math.linear.ArrayRealVector;
030
031 public class CholeskySolverTest extends TestCase {
032
033 private double[][] testData = new double[][] {
034 { 1, 2, 4, 7, 11 },
035 { 2, 13, 23, 38, 58 },
036 { 4, 23, 77, 122, 182 },
037 { 7, 38, 122, 294, 430 },
038 { 11, 58, 182, 430, 855 }
039 };
040
041 public CholeskySolverTest(String name) {
042 super(name);
043 }
044
045 public static Test suite() {
046 TestSuite suite = new TestSuite(CholeskySolverTest.class);
047 suite.setName("LUSolver Tests");
048 return suite;
049 }
050
051 /** test solve dimension errors */
052 public void testSolveDimensionErrors() throws MathException {
053 DecompositionSolver solver =
054 new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(testData)).getSolver();
055 RealMatrix b = MatrixUtils.createRealMatrix(new double[2][2]);
056 try {
057 solver.solve(b);
058 fail("an exception should have been thrown");
059 } catch (IllegalArgumentException iae) {
060 // expected behavior
061 } catch (Exception e) {
062 fail("wrong exception caught");
063 }
064 try {
065 solver.solve(b.getColumn(0));
066 fail("an exception should have been thrown");
067 } catch (IllegalArgumentException iae) {
068 // expected behavior
069 } catch (Exception e) {
070 fail("wrong exception caught");
071 }
072 try {
073 solver.solve(new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(0)));
074 fail("an exception should have been thrown");
075 } catch (IllegalArgumentException iae) {
076 // expected behavior
077 } catch (Exception e) {
078 fail("wrong exception caught");
079 }
080 }
081
082 /** test solve */
083 public void testSolve() throws MathException {
084 DecompositionSolver solver =
085 new CholeskyDecompositionImpl(MatrixUtils.createRealMatrix(testData)).getSolver();
086 RealMatrix b = MatrixUtils.createRealMatrix(new double[][] {
087 { 78, -13, 1 },
088 { 414, -62, -1 },
089 { 1312, -202, -37 },
090 { 2989, -542, 145 },
091 { 5510, -1465, 201 }
092 });
093 RealMatrix xRef = MatrixUtils.createRealMatrix(new double[][] {
094 { 1, 0, 1 },
095 { 0, 1, 1 },
096 { 2, 1, -4 },
097 { 2, 2, 2 },
098 { 5, -3, 0 }
099 });
100
101 // using RealMatrix
102 assertEquals(0, solver.solve(b).subtract(xRef).getNorm(), 1.0e-13);
103
104 // using double[]
105 for (int i = 0; i < b.getColumnDimension(); ++i) {
106 assertEquals(0,
107 new ArrayRealVector(solver.solve(b.getColumn(i))).subtract(xRef.getColumnVector(i)).getNorm(),
108 1.0e-13);
109 }
110
111 // using ArrayRealVector
112 for (int i = 0; i < b.getColumnDimension(); ++i) {
113 assertEquals(0,
114 solver.solve(b.getColumnVector(i)).subtract(xRef.getColumnVector(i)).getNorm(),
115 1.0e-13);
116 }
117
118 // using RealVector with an alternate implementation
119 for (int i = 0; i < b.getColumnDimension(); ++i) {
120 ArrayRealVectorTest.RealVectorTestImpl v =
121 new ArrayRealVectorTest.RealVectorTestImpl(b.getColumn(i));
122 assertEquals(0,
123 solver.solve(v).subtract(xRef.getColumnVector(i)).getNorm(),
124 1.0e-13);
125 }
126
127 }
128
129 /** test determinant */
130 public void testDeterminant() throws MathException {
131 assertEquals(7290000.0, getDeterminant(MatrixUtils.createRealMatrix(testData)), 1.0e-15);
132 }
133
134 private double getDeterminant(RealMatrix m) throws MathException {
135 return new CholeskyDecompositionImpl(m).getDeterminant();
136 }
137
138 }