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    *      http://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  package org.apache.commons.math4.legacy.linear;
19  
20  import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
21  import org.apache.commons.math4.legacy.core.dfp.Dfp;
22  import org.junit.Assert;
23  import org.junit.Test;
24  
25  public class FieldLUSolverTest {
26      private int[][] testData = {
27              { 1, 2, 3},
28              { 2, 5, 3},
29              { 1, 0, 8}
30      };
31      private int[][] luData = {
32              { 2, 3, 3 },
33              { 0, 5, 7 },
34              { 6, 9, 8 }
35      };
36  
37      // singular matrices
38      private int[][] singular = {
39              { 2, 3 },
40              { 2, 3 }
41      };
42      private int[][] bigSingular = {
43              { 1, 2,   3,    4 },
44              { 2, 5,   3,    4 },
45              { 7, 3, 256, 1930 },
46              { 3, 7,   6,    8 }
47      }; // 4th row = 1st + 2nd
48  
49      public static FieldMatrix<Dfp> createDfpMatrix(final int[][] data) {
50          final int numRows = data.length;
51          final int numCols = data[0].length;
52          final Array2DRowFieldMatrix<Dfp> m;
53          m = new Array2DRowFieldMatrix<>(Dfp25.getField(),
54                                                  numRows, numCols);
55          for (int i = 0; i < numRows; i++) {
56              for (int j = 0; j < numCols; j++) {
57                  m.setEntry(i, j, Dfp25.of(data[i][j], 1));
58              }
59          }
60          return m;
61      }
62  
63      /** test singular */
64      @Test
65      public void testSingular() {
66          FieldDecompositionSolver<Dfp> solver;
67          solver = new FieldLUDecomposition<>(createDfpMatrix(testData))
68              .getSolver();
69          Assert.assertTrue(solver.isNonSingular());
70          solver = new FieldLUDecomposition<>(createDfpMatrix(singular))
71              .getSolver();
72          Assert.assertFalse(solver.isNonSingular());
73          solver = new FieldLUDecomposition<>(createDfpMatrix(bigSingular))
74              .getSolver();
75          Assert.assertFalse(solver.isNonSingular());
76      }
77  
78      /** test solve dimension errors */
79      @Test
80      public void testSolveDimensionErrors() {
81          FieldDecompositionSolver<Dfp> solver;
82          solver = new FieldLUDecomposition<>(createDfpMatrix(testData))
83              .getSolver();
84          FieldMatrix<Dfp> b = createDfpMatrix(new int[2][2]);
85          try {
86              solver.solve(b);
87              Assert.fail("an exception should have been thrown");
88          } catch (MathIllegalArgumentException iae) {
89              // expected behavior
90          }
91          try {
92              solver.solve(b.getColumnVector(0));
93              Assert.fail("an exception should have been thrown");
94          } catch (MathIllegalArgumentException iae) {
95              // expected behavior
96          }
97      }
98  
99      /** test solve singularity errors */
100     @Test
101     public void testSolveSingularityErrors() {
102         FieldDecompositionSolver<Dfp> solver;
103         solver = new FieldLUDecomposition<>(createDfpMatrix(singular))
104             .getSolver();
105         FieldMatrix<Dfp> b = createDfpMatrix(new int[2][2]);
106         try {
107             solver.solve(b);
108             Assert.fail("an exception should have been thrown");
109         } catch (SingularMatrixException ime) {
110             // expected behavior
111         }
112         try {
113             solver.solve(b.getColumnVector(0));
114             Assert.fail("an exception should have been thrown");
115         } catch (SingularMatrixException ime) {
116             // expected behavior
117         }
118     }
119 
120     /** test solve */
121     @Test
122     public void testSolve() {
123         FieldDecompositionSolver<Dfp> solver;
124         solver = new FieldLUDecomposition<>(createDfpMatrix(testData))
125             .getSolver();
126         FieldMatrix<Dfp> b = createDfpMatrix(new int[][] {
127                 { 1, 0 }, { 2, -5 }, { 3, 1 }
128         });
129         FieldMatrix<Dfp> xRef = createDfpMatrix(new int[][] {
130                 { 19, -71 }, { -6, 22 }, { -2, 9 }
131         });
132 
133         // using FieldMatrix
134         FieldMatrix<Dfp> x = solver.solve(b);
135         for (int i = 0; i < x.getRowDimension(); i++){
136             for (int j = 0; j < x.getColumnDimension(); j++){
137                 Assert.assertEquals("(" + i + ", " + j + ")",
138                                     xRef.getEntry(i, j), x.getEntry(i, j));
139             }
140         }
141 
142         // using ArrayFieldVector
143         for (int j = 0; j < b.getColumnDimension(); j++) {
144             final FieldVector<Dfp> xj = solver.solve(b.getColumnVector(j));
145             for (int i = 0; i < xj.getDimension(); i++){
146                 Assert.assertEquals("(" + i + ", " + j + ")",
147                                     xRef.getEntry(i, j), xj.getEntry(i));
148             }
149         }
150 
151         // using SparseFieldVector
152         for (int j = 0; j < b.getColumnDimension(); j++) {
153             final SparseFieldVector<Dfp> bj;
154             bj = new SparseFieldVector<>(Dfp25.getField(),
155                                                  b.getColumn(j));
156             final FieldVector<Dfp> xj = solver.solve(bj);
157             for (int i = 0; i < xj.getDimension(); i++) {
158                 Assert.assertEquals("(" + i + ", " + j + ")",
159                                     xRef.getEntry(i, j), xj.getEntry(i));
160             }
161         }
162     }
163 
164     /** test determinant */
165     @Test
166     public void testDeterminant() {
167         Assert.assertEquals( -1, getDeterminant(createDfpMatrix(testData)), 1E-15);
168         Assert.assertEquals(-10, getDeterminant(createDfpMatrix(luData)), 1E-14);
169         Assert.assertEquals(  0, getDeterminant(createDfpMatrix(singular)), 1E-15);
170         Assert.assertEquals(  0, getDeterminant(createDfpMatrix(bigSingular)), 1E-15);
171     }
172 
173     private double getDeterminant(final FieldMatrix<Dfp> m) {
174         return new FieldLUDecomposition<>(m).getDeterminant().toDouble();
175     }
176 }