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  package org.apache.commons.math4.legacy.linear;
18  
19  import org.junit.Test;
20  import org.junit.Assert;
21  import org.apache.commons.math4.legacy.TestUtils;
22  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
23  import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
24  import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
25  import org.apache.commons.math4.legacy.exception.NoDataException;
26  import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
27  import org.apache.commons.math4.legacy.exception.NullArgumentException;
28  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
29  import org.apache.commons.math4.legacy.exception.OutOfRangeException;
30  import org.apache.commons.math4.legacy.core.dfp.Dfp;
31  
32  /**
33   * Test cases for the {@link Array2DRowFieldMatrix} class.
34   *
35   */
36  
37  public final class FieldMatrixImplTest {
38  
39      // 3 x 3 identity matrix
40      protected Dfp[][] id = { {Dfp25.of(1),Dfp25.of(0),Dfp25.of(0)}, {Dfp25.of(0),Dfp25.of(1),Dfp25.of(0)}, {Dfp25.of(0),Dfp25.of(0),Dfp25.of(1)} };
41  
42      // Test data for group operations
43      protected Dfp[][] testData = { {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3)}, {Dfp25.of(2),Dfp25.of(5),Dfp25.of(3)}, {Dfp25.of(1),Dfp25.of(0),Dfp25.of(8)} };
44      protected Dfp[][] testDataLU = {{Dfp25.of(2), Dfp25.of(5), Dfp25.of(3)}, {Dfp25.of(1, 2), Dfp25.of(-5, 2), Dfp25.of(13, 2)}, {Dfp25.of(1, 2), Dfp25.of(1, 5), Dfp25.of(1, 5)}};
45      protected Dfp[][] testDataPlus2 = { {Dfp25.of(3),Dfp25.of(4),Dfp25.of(5)}, {Dfp25.of(4),Dfp25.of(7),Dfp25.of(5)}, {Dfp25.of(3),Dfp25.of(2),Dfp25.of(10)} };
46      protected Dfp[][] testDataMinus = { {Dfp25.of(-1),Dfp25.of(-2),Dfp25.of(-3)}, {Dfp25.of(-2),Dfp25.of(-5),Dfp25.of(-3)},
47         {Dfp25.of(-1),Dfp25.of(0),Dfp25.of(-8)} };
48      protected Dfp[] testDataRow1 = {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3)};
49      protected Dfp[] testDataCol3 = {Dfp25.of(3),Dfp25.of(3),Dfp25.of(8)};
50      protected Dfp[][] testDataInv =
51          { {Dfp25.of(-40),Dfp25.of(16),Dfp25.of(9)}, {Dfp25.of(13),Dfp25.of(-5),Dfp25.of(-3)}, {Dfp25.of(5),Dfp25.of(-2),Dfp25.of(-1)} };
52      protected Dfp[] preMultTest = {Dfp25.of(8),Dfp25.of(12),Dfp25.of(33)};
53      protected Dfp[][] testData2 ={ {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3)}, {Dfp25.of(2),Dfp25.of(5),Dfp25.of(3)}};
54      protected Dfp[][] testData2T = { {Dfp25.of(1),Dfp25.of(2)}, {Dfp25.of(2),Dfp25.of(5)}, {Dfp25.of(3),Dfp25.of(3)}};
55      protected Dfp[][] testDataPlusInv =
56          { {Dfp25.of(-39),Dfp25.of(18),Dfp25.of(12)}, {Dfp25.of(15),Dfp25.of(0),Dfp25.of(0)}, {Dfp25.of(6),Dfp25.of(-2),Dfp25.of(7)} };
57  
58      // lu decomposition tests
59      protected Dfp[][] luData = { {Dfp25.of(2),Dfp25.of(3),Dfp25.of(3)}, {Dfp25.of(0),Dfp25.of(5),Dfp25.of(7)}, {Dfp25.of(6),Dfp25.of(9),Dfp25.of(8)} };
60      protected Dfp[][] luDataLUDecomposition = { {Dfp25.of(6),Dfp25.of(9),Dfp25.of(8)}, {Dfp25.of(0),Dfp25.of(5),Dfp25.of(7)},
61              {Dfp25.of(1, 3),Dfp25.of(0),Dfp25.of(1, 3)} };
62  
63      // singular matrices
64      protected Dfp[][] singular = { {Dfp25.of(2),Dfp25.of(3)}, {Dfp25.of(2),Dfp25.of(3)} };
65      protected Dfp[][] bigSingular = {{Dfp25.of(1),Dfp25.of(2),Dfp25.of(3),Dfp25.of(4)}, {Dfp25.of(2),Dfp25.of(5),Dfp25.of(3),Dfp25.of(4)},
66          {Dfp25.of(7),Dfp25.of(3),Dfp25.of(256),Dfp25.of(1930)}, {Dfp25.of(3),Dfp25.of(7),Dfp25.of(6),Dfp25.of(8)}}; // 4th row = 1st + 2nd
67      protected Dfp[][] detData = { {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3)}, {Dfp25.of(4),Dfp25.of(5),Dfp25.of(6)}, {Dfp25.of(7),Dfp25.of(8),Dfp25.of(10)} };
68      protected Dfp[][] detData2 = { {Dfp25.of(1), Dfp25.of(3)}, {Dfp25.of(2), Dfp25.of(4)}};
69  
70      // vectors
71      protected Dfp[] testVector = {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3)};
72      protected Dfp[] testVector2 = {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3),Dfp25.of(4)};
73  
74      // submatrix accessor tests
75      protected Dfp[][] subTestData = {{Dfp25.of(1), Dfp25.of(2), Dfp25.of(3), Dfp25.of(4)}, {Dfp25.of(3, 2), Dfp25.of(5, 2), Dfp25.of(7, 2), Dfp25.of(9, 2)},
76              {Dfp25.of(2), Dfp25.of(4), Dfp25.of(6), Dfp25.of(8)}, {Dfp25.of(4), Dfp25.of(5), Dfp25.of(6), Dfp25.of(7)}};
77      // array selections
78      protected Dfp[][] subRows02Cols13 = { {Dfp25.of(2), Dfp25.of(4)}, {Dfp25.of(4), Dfp25.of(8)}};
79      protected Dfp[][] subRows03Cols12 = { {Dfp25.of(2), Dfp25.of(3)}, {Dfp25.of(5), Dfp25.of(6)}};
80      protected Dfp[][] subRows03Cols123 = { {Dfp25.of(2), Dfp25.of(3), Dfp25.of(4)} , {Dfp25.of(5), Dfp25.of(6), Dfp25.of(7)}};
81      // effective permutations
82      protected Dfp[][] subRows20Cols123 = { {Dfp25.of(4), Dfp25.of(6), Dfp25.of(8)} , {Dfp25.of(2), Dfp25.of(3), Dfp25.of(4)}};
83      protected Dfp[][] subRows31Cols31 = {{Dfp25.of(7), Dfp25.of(5)}, {Dfp25.of(9, 2), Dfp25.of(5, 2)}};
84      // contiguous ranges
85      protected Dfp[][] subRows01Cols23 = {{Dfp25.of(3),Dfp25.of(4)} , {Dfp25.of(7, 2), Dfp25.of(9, 2)}};
86      protected Dfp[][] subRows23Cols00 = {{Dfp25.of(2)} , {Dfp25.of(4)}};
87      protected Dfp[][] subRows00Cols33 = {{Dfp25.of(4)}};
88      // row matrices
89      protected Dfp[][] subRow0 = {{Dfp25.of(1),Dfp25.of(2),Dfp25.of(3),Dfp25.of(4)}};
90      protected Dfp[][] subRow3 = {{Dfp25.of(4),Dfp25.of(5),Dfp25.of(6),Dfp25.of(7)}};
91      // column matrices
92      protected Dfp[][] subColumn1 = {{Dfp25.of(2)}, {Dfp25.of(5, 2)}, {Dfp25.of(4)}, {Dfp25.of(5)}};
93      protected Dfp[][] subColumn3 = {{Dfp25.of(4)}, {Dfp25.of(9, 2)}, {Dfp25.of(8)}, {Dfp25.of(7)}};
94  
95      // tolerances
96      protected double entryTolerance = 10E-16;
97      protected double normTolerance = 10E-14;
98  
99      /** test dimensions */
100     @Test
101     public void testDimensions() {
102         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
103         Array2DRowFieldMatrix<Dfp> m2 = new Array2DRowFieldMatrix<>(testData2);
104         Assert.assertEquals("testData row dimension",3,m.getRowDimension());
105         Assert.assertEquals("testData column dimension",3,m.getColumnDimension());
106         Assert.assertTrue("testData is square",m.isSquare());
107         Assert.assertEquals("testData2 row dimension",m2.getRowDimension(),2);
108         Assert.assertEquals("testData2 column dimension",m2.getColumnDimension(),3);
109         Assert.assertFalse("testData2 is not square", m2.isSquare());
110     }
111 
112     /** test copy functions */
113     @Test
114     public void testCopyFunctions() {
115         Array2DRowFieldMatrix<Dfp> m1 = new Array2DRowFieldMatrix<>(testData);
116         Array2DRowFieldMatrix<Dfp> m2 = new Array2DRowFieldMatrix<>(m1.getData());
117         Assert.assertEquals(m2,m1);
118         Array2DRowFieldMatrix<Dfp> m3 = new Array2DRowFieldMatrix<>(testData);
119         Array2DRowFieldMatrix<Dfp> m4 = new Array2DRowFieldMatrix<>(m3.getData(), false);
120         Assert.assertEquals(m4,m3);
121     }
122 
123     /** test add */
124     @Test
125     public void testAdd() {
126         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
127         Array2DRowFieldMatrix<Dfp> mInv = new Array2DRowFieldMatrix<>(testDataInv);
128         FieldMatrix<Dfp> mPlusMInv = m.add(mInv);
129         Dfp[][] sumEntries = mPlusMInv.getData();
130         for (int row = 0; row < m.getRowDimension(); row++) {
131             for (int col = 0; col < m.getColumnDimension(); col++) {
132                 Assert.assertEquals(testDataPlusInv[row][col],sumEntries[row][col]);
133             }
134         }
135     }
136 
137     /** test add failure */
138     @Test
139     public void testAddFail() {
140         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
141         Array2DRowFieldMatrix<Dfp> m2 = new Array2DRowFieldMatrix<>(testData2);
142         try {
143             m.add(m2);
144             Assert.fail("MathIllegalArgumentException expected");
145         } catch (MathIllegalArgumentException ex) {
146             // ignored
147         }
148     }
149 
150      /** test m-n = m + -n */
151     @Test
152     public void testPlusMinus() {
153         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
154         Array2DRowFieldMatrix<Dfp> m2 = new Array2DRowFieldMatrix<>(testDataInv);
155         TestUtils.assertEquals(m.subtract(m2),m2.scalarMultiply(Dfp25.of(-1)).add(m));
156         try {
157             m.subtract(new Array2DRowFieldMatrix<>(testData2));
158             Assert.fail("Expecting illegalArgumentException");
159         } catch (MathIllegalArgumentException ex) {
160             // ignored
161         }
162     }
163 
164     /** test multiply */
165     @Test
166      public void testMultiply() {
167         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
168         Array2DRowFieldMatrix<Dfp> mInv = new Array2DRowFieldMatrix<>(testDataInv);
169         Array2DRowFieldMatrix<Dfp> identity = new Array2DRowFieldMatrix<>(id);
170         Array2DRowFieldMatrix<Dfp> m2 = new Array2DRowFieldMatrix<>(testData2);
171         TestUtils.assertEquals(m.multiply(mInv), identity);
172         TestUtils.assertEquals(mInv.multiply(m), identity);
173         TestUtils.assertEquals(m.multiply(identity), m);
174         TestUtils.assertEquals(identity.multiply(mInv), mInv);
175         TestUtils.assertEquals(m2.multiply(identity), m2);
176         try {
177             m.multiply(new Array2DRowFieldMatrix<>(bigSingular));
178             Assert.fail("Expecting illegalArgumentException");
179         } catch (MathIllegalArgumentException ex) {
180             // ignored
181         }
182     }
183 
184     //Additional Test for Array2DRowFieldMatrix<Dfp>Test.testMultiply
185 
186     private final Dfp[][] d3 = new Dfp[][] {{Dfp25.of(1),Dfp25.of(2),Dfp25.of(3),Dfp25.of(4)},{Dfp25.of(5),Dfp25.of(6),Dfp25.of(7),Dfp25.of(8)}};
187     private final Dfp[][] d4 = new Dfp[][] {{Dfp25.of(1)},{Dfp25.of(2)},{Dfp25.of(3)},{Dfp25.of(4)}};
188     private final Dfp[][] d5 = new Dfp[][] {{Dfp25.of(30)},{Dfp25.of(70)}};
189 
190     @Test
191     public void testMultiply2() {
192        FieldMatrix<Dfp> m3 = new Array2DRowFieldMatrix<>(d3);
193        FieldMatrix<Dfp> m4 = new Array2DRowFieldMatrix<>(d4);
194        FieldMatrix<Dfp> m5 = new Array2DRowFieldMatrix<>(d5);
195        TestUtils.assertEquals(m3.multiply(m4), m5);
196    }
197 
198     @Test
199     public void testPower() {
200         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
201         FieldMatrix<Dfp> mInv = new Array2DRowFieldMatrix<>(testDataInv);
202         FieldMatrix<Dfp> mPlusInv = new Array2DRowFieldMatrix<>(testDataPlusInv);
203         FieldMatrix<Dfp> identity = new Array2DRowFieldMatrix<>(id);
204 
205         TestUtils.assertEquals(m.power(0), identity);
206         TestUtils.assertEquals(mInv.power(0), identity);
207         TestUtils.assertEquals(mPlusInv.power(0), identity);
208 
209         TestUtils.assertEquals(m.power(1), m);
210         TestUtils.assertEquals(mInv.power(1), mInv);
211         TestUtils.assertEquals(mPlusInv.power(1), mPlusInv);
212 
213         FieldMatrix<Dfp> C1 = m.copy();
214         FieldMatrix<Dfp> C2 = mInv.copy();
215         FieldMatrix<Dfp> C3 = mPlusInv.copy();
216 
217         // stop at 5 to avoid overflow
218         for (int i = 2; i <= 5; ++i) {
219             C1 = C1.multiply(m);
220             C2 = C2.multiply(mInv);
221             C3 = C3.multiply(mPlusInv);
222 
223             TestUtils.assertEquals(m.power(i), C1);
224             TestUtils.assertEquals(mInv.power(i), C2);
225             TestUtils.assertEquals(mPlusInv.power(i), C3);
226         }
227 
228         try {
229             FieldMatrix<Dfp> mNotSquare = new Array2DRowFieldMatrix<>(testData2T);
230             mNotSquare.power(2);
231             Assert.fail("Expecting NonSquareMatrixException");
232         } catch (NonSquareMatrixException ex) {
233             // ignored
234         }
235 
236         try {
237             m.power(-1);
238             Assert.fail("Expecting MathIllegalArgumentException");
239         } catch (MathIllegalArgumentException ex) {
240             // ignored
241         }
242     }
243 
244     /** test trace */
245     @Test
246     public void testTrace() {
247         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(id);
248         Assert.assertEquals("identity trace",Dfp25.of(3),m.getTrace());
249         m = new Array2DRowFieldMatrix<>(testData2);
250         try {
251             m.getTrace();
252             Assert.fail("Expecting NonSquareMatrixException");
253         } catch (NonSquareMatrixException ex) {
254             // ignored
255         }
256     }
257 
258     /** test scalarAdd */
259     @Test
260     public void testScalarAdd() {
261         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
262         TestUtils.assertEquals(new Array2DRowFieldMatrix<>(testDataPlus2), m.scalarAdd(Dfp25.of(2)));
263     }
264 
265     /** test operate */
266     @Test
267     public void testOperate() {
268         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(id);
269         TestUtils.assertEquals(testVector, m.operate(testVector));
270         TestUtils.assertEquals(testVector, m.operate(new ArrayFieldVector<>(testVector)).toArray());
271         m = new Array2DRowFieldMatrix<>(bigSingular);
272         try {
273             m.operate(testVector);
274             Assert.fail("Expecting illegalArgumentException");
275         } catch (MathIllegalArgumentException ex) {
276             // ignored
277         }
278     }
279 
280     /** test issue MATH-209 */
281     @Test
282     public void testMath209() {
283         FieldMatrix<Dfp> a = new Array2DRowFieldMatrix<>(new Dfp[][] {
284                 { Dfp25.of(1), Dfp25.of(2) }, { Dfp25.of(3), Dfp25.of(4) }, { Dfp25.of(5), Dfp25.of(6) }
285         }, false);
286         Dfp[] b = a.operate(new Dfp[] { Dfp25.of(1), Dfp25.of(1) });
287         Assert.assertEquals(a.getRowDimension(), b.length);
288         Assert.assertEquals( Dfp25.of(3), b[0]);
289         Assert.assertEquals( Dfp25.of(7), b[1]);
290         Assert.assertEquals(Dfp25.of(11), b[2]);
291     }
292 
293     /** test transpose */
294     @Test
295     public void testTranspose() {
296         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
297         FieldMatrix<Dfp> mIT = new FieldLUDecomposition<>(m).getSolver().getInverse().transpose();
298         FieldMatrix<Dfp> mTI = new FieldLUDecomposition<>(m.transpose()).getSolver().getInverse();
299         TestUtils.assertEquals(mIT, mTI);
300         m = new Array2DRowFieldMatrix<>(testData2);
301         FieldMatrix<Dfp> mt = new Array2DRowFieldMatrix<>(testData2T);
302         TestUtils.assertEquals(mt, m.transpose());
303     }
304 
305     /** test preMultiply by vector */
306     @Test
307     public void testPremultiplyVector() {
308         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
309         TestUtils.assertEquals(m.preMultiply(testVector), preMultTest);
310         TestUtils.assertEquals(m.preMultiply(new ArrayFieldVector<>(testVector).toArray()),
311                                preMultTest);
312         m = new Array2DRowFieldMatrix<>(bigSingular);
313         try {
314             m.preMultiply(testVector);
315             Assert.fail("expecting MathIllegalArgumentException");
316         } catch (MathIllegalArgumentException ex) {
317             // ignored
318         }
319     }
320 
321     @Test
322     public void testPremultiply() {
323         FieldMatrix<Dfp> m3 = new Array2DRowFieldMatrix<>(d3);
324         FieldMatrix<Dfp> m4 = new Array2DRowFieldMatrix<>(d4);
325         FieldMatrix<Dfp> m5 = new Array2DRowFieldMatrix<>(d5);
326         TestUtils.assertEquals(m4.preMultiply(m3), m5);
327 
328         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
329         Array2DRowFieldMatrix<Dfp> mInv = new Array2DRowFieldMatrix<>(testDataInv);
330         Array2DRowFieldMatrix<Dfp> identity = new Array2DRowFieldMatrix<>(id);
331         TestUtils.assertEquals(m.preMultiply(mInv), identity);
332         TestUtils.assertEquals(mInv.preMultiply(m), identity);
333         TestUtils.assertEquals(m.preMultiply(identity), m);
334         TestUtils.assertEquals(identity.preMultiply(mInv), mInv);
335         try {
336             m.preMultiply(new Array2DRowFieldMatrix<>(bigSingular));
337             Assert.fail("Expecting illegalArgumentException");
338         } catch (MathIllegalArgumentException ex) {
339             // ignored
340         }
341     }
342 
343     @Test
344     public void testGetVectors() {
345         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
346         TestUtils.assertEquals(m.getRow(0), testDataRow1);
347         TestUtils.assertEquals(m.getColumn(2), testDataCol3);
348         try {
349             m.getRow(10);
350             Assert.fail("expecting OutOfRangeException");
351         } catch (OutOfRangeException ex) {
352             // ignored
353         }
354         try {
355             m.getColumn(-1);
356             Assert.fail("expecting OutOfRangeException");
357         } catch (OutOfRangeException ex) {
358             // ignored
359         }
360     }
361 
362     @Test
363     public void testGetEntry() {
364         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
365         Assert.assertEquals("get entry", m.getEntry(0,1), Dfp25.of(2));
366         try {
367             m.getEntry(10, 4);
368             Assert.fail ("Expecting OutOfRangeException");
369         } catch (OutOfRangeException ex) {
370             // expected
371         }
372     }
373 
374     /** test examples in user guide */
375     @Test
376     public void testExamples() {
377         // Create a real matrix with two rows and three columns
378         Dfp[][] matrixData = {
379                 {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3)},
380                 {Dfp25.of(2),Dfp25.of(5),Dfp25.of(3)}
381         };
382         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(matrixData);
383         // One more with three rows, two columns
384         Dfp[][] matrixData2 = {
385                 {Dfp25.of(1),Dfp25.of(2)},
386                 {Dfp25.of(2),Dfp25.of(5)},
387                 {Dfp25.of(1), Dfp25.of(7)}
388         };
389         FieldMatrix<Dfp> n = new Array2DRowFieldMatrix<>(matrixData2);
390         // Now multiply m by n
391         FieldMatrix<Dfp> p = m.multiply(n);
392         Assert.assertEquals(2, p.getRowDimension());
393         Assert.assertEquals(2, p.getColumnDimension());
394         // Invert p
395         FieldMatrix<Dfp> pInverse = new FieldLUDecomposition<>(p).getSolver().getInverse();
396         Assert.assertEquals(2, pInverse.getRowDimension());
397         Assert.assertEquals(2, pInverse.getColumnDimension());
398 
399         // Solve example
400         Dfp[][] coefficientsData = {
401                 {Dfp25.of(2), Dfp25.of(3), Dfp25.of(-2)},
402                 {Dfp25.of(-1), Dfp25.of(7), Dfp25.of(6)},
403                 {Dfp25.of(4), Dfp25.of(-3), Dfp25.of(-5)}
404         };
405         FieldMatrix<Dfp> coefficients = new Array2DRowFieldMatrix<>(coefficientsData);
406         Dfp[] constants = {
407             Dfp25.of(1), Dfp25.of(-2), Dfp25.of(1)
408         };
409         Dfp[] solution;
410         solution = new FieldLUDecomposition<>(coefficients)
411             .getSolver()
412             .solve(new ArrayFieldVector<>(constants, false)).toArray();
413         Assert.assertEquals(Dfp25.of(2).multiply(solution[0]).
414                             add(Dfp25.of(3).multiply(solution[1])).
415                             subtract(Dfp25.of(2).multiply(solution[2])).toDouble(),
416                             constants[0].toDouble(),
417                             0d);
418         Assert.assertEquals(Dfp25.of(-1).multiply(solution[0]).
419                             add(Dfp25.of(7).multiply(solution[1])).
420                             add(Dfp25.of(6).multiply(solution[2])).toDouble(),
421                             constants[1].toDouble(),
422                             0d);
423         Assert.assertEquals(Dfp25.of(4).multiply(solution[0]).
424                             subtract(Dfp25.of(3).multiply(solution[1])).
425                             subtract(Dfp25.of(5).multiply(solution[2])).toDouble(),
426                             constants[2].toDouble(),
427                             0d);
428     }
429 
430     // test submatrix accessors
431     @Test
432     public void testGetSubMatrix() {
433         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
434         checkGetSubMatrix(m, subRows23Cols00,  2 , 3 , 0, 0);
435         checkGetSubMatrix(m, subRows00Cols33,  0 , 0 , 3, 3);
436         checkGetSubMatrix(m, subRows01Cols23,  0 , 1 , 2, 3);
437         checkGetSubMatrix(m, subRows02Cols13,  new int[] { 0, 2 }, new int[] { 1, 3 });
438         checkGetSubMatrix(m, subRows03Cols12,  new int[] { 0, 3 }, new int[] { 1, 2 });
439         checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 });
440         checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 });
441         checkGetSubMatrix(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 });
442         checkGetSubMatrix(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 });
443         checkGetSubMatrix(m, null,  1, 0, 2, 4);
444         checkGetSubMatrix(m, null, -1, 1, 2, 2);
445         checkGetSubMatrix(m, null,  1, 0, 2, 2);
446         checkGetSubMatrix(m, null,  1, 0, 2, 4);
447         checkGetSubMatrix(m, null, new int[] {},    new int[] { 0 });
448         checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 });
449     }
450 
451     private void checkGetSubMatrix(FieldMatrix<Dfp> m, Dfp[][] reference,
452                                    int startRow, int endRow, int startColumn, int endColumn) {
453         try {
454             FieldMatrix<Dfp> sub = m.getSubMatrix(startRow, endRow, startColumn, endColumn);
455             if (reference != null) {
456                 Assert.assertEquals(new Array2DRowFieldMatrix<>(reference), sub);
457             } else {
458                 Assert.fail("Expecting OutOfRangeException or NotStrictlyPositiveException"
459                      + " or NumberIsTooSmallException or NoDataException");
460             }
461         } catch (OutOfRangeException e) {
462             if (reference != null) {
463                 throw e;
464             }
465         } catch (NotStrictlyPositiveException e) {
466             if (reference != null) {
467                 throw e;
468             }
469         } catch (NumberIsTooSmallException e) {
470             if (reference != null) {
471                 throw e;
472             }
473         } catch (NoDataException e) {
474             if (reference != null) {
475                 throw e;
476             }
477         }
478     }
479 
480     private void checkGetSubMatrix(FieldMatrix<Dfp> m, Dfp[][] reference,
481                                    int[] selectedRows, int[] selectedColumns) {
482         try {
483             FieldMatrix<Dfp> sub = m.getSubMatrix(selectedRows, selectedColumns);
484             if (reference != null) {
485                 Assert.assertEquals(new Array2DRowFieldMatrix<>(reference), sub);
486             } else {
487                 Assert.fail("Expecting OutOfRangeException or NotStrictlyPositiveException"
488                      + " or NumberIsTooSmallException or NoDataException");
489             }
490         } catch (OutOfRangeException e) {
491             if (reference != null) {
492                 throw e;
493             }
494         } catch (NotStrictlyPositiveException e) {
495             if (reference != null) {
496                 throw e;
497             }
498         } catch (NumberIsTooSmallException e) {
499             if (reference != null) {
500                 throw e;
501             }
502         } catch (NoDataException e) {
503             if (reference != null) {
504                 throw e;
505             }
506         }
507     }
508 
509     @Test
510     public void testCopySubMatrix() {
511         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
512         checkCopy(m, subRows23Cols00,  2 , 3 , 0, 0);
513         checkCopy(m, subRows00Cols33,  0 , 0 , 3, 3);
514         checkCopy(m, subRows01Cols23,  0 , 1 , 2, 3);
515         checkCopy(m, subRows02Cols13,  new int[] { 0, 2 }, new int[] { 1, 3 });
516         checkCopy(m, subRows03Cols12,  new int[] { 0, 3 }, new int[] { 1, 2 });
517         checkCopy(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 });
518         checkCopy(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 });
519         checkCopy(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 });
520         checkCopy(m, subRows31Cols31,  new int[] { 3, 1 }, new int[] { 3, 1 });
521 
522         checkCopy(m, null,  1, 0, 2, 4);
523         checkCopy(m, null, -1, 1, 2, 2);
524         checkCopy(m, null,  1, 0, 2, 2);
525         checkCopy(m, null,  1, 0, 2, 4);
526         checkCopy(m, null, new int[] {},    new int[] { 0 });
527         checkCopy(m, null, new int[] { 0 }, new int[] { 4 });
528     }
529 
530     private void checkCopy(FieldMatrix<Dfp> m, Dfp[][] reference,
531                            int startRow, int endRow, int startColumn, int endColumn) {
532         try {
533             Dfp[][] sub = (reference == null) ?
534                              new Dfp[1][1] :
535                              new Dfp[reference.length][reference[0].length];
536             m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub);
537             if (reference != null) {
538                 Assert.assertEquals(new Array2DRowFieldMatrix<>(reference), new Array2DRowFieldMatrix<>(sub));
539             } else {
540                 Assert.fail("Expecting OutOfRangeException or NumberIsTooSmallException or NoDataException");
541             }
542         } catch (OutOfRangeException e) {
543             if (reference != null) {
544                 throw e;
545             }
546         } catch (NumberIsTooSmallException e) {
547             if (reference != null) {
548                 throw e;
549             }
550         } catch (NoDataException e) {
551             if (reference != null) {
552                 throw e;
553             }
554         }
555     }
556 
557     private void checkCopy(FieldMatrix<Dfp> m, Dfp[][] reference,
558                            int[] selectedRows, int[] selectedColumns) {
559         try {
560             Dfp[][] sub = (reference == null) ?
561                     new Dfp[1][1] :
562                     new Dfp[reference.length][reference[0].length];
563             m.copySubMatrix(selectedRows, selectedColumns, sub);
564             if (reference != null) {
565                 Assert.assertEquals(new Array2DRowFieldMatrix<>(reference), new Array2DRowFieldMatrix<>(sub));
566             } else {
567                 Assert.fail("Expecting OutOfRangeException or NumberIsTooSmallException or NoDataException");
568             }
569         } catch (OutOfRangeException e) {
570             if (reference != null) {
571                 throw e;
572             }
573         } catch (NumberIsTooSmallException e) {
574             if (reference != null) {
575                 throw e;
576             }
577         } catch (NoDataException e) {
578             if (reference != null) {
579                 throw e;
580             }
581         }
582     }
583 
584     @Test
585     public void testGetRowMatrix() {
586         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
587         FieldMatrix<Dfp> mRow0 = new Array2DRowFieldMatrix<>(subRow0);
588         FieldMatrix<Dfp> mRow3 = new Array2DRowFieldMatrix<>(subRow3);
589         Assert.assertEquals("Row0", mRow0,
590                 m.getRowMatrix(0));
591         Assert.assertEquals("Row3", mRow3,
592                 m.getRowMatrix(3));
593         try {
594             m.getRowMatrix(-1);
595             Assert.fail("Expecting OutOfRangeException");
596         } catch (OutOfRangeException ex) {
597             // expected
598         }
599         try {
600             m.getRowMatrix(4);
601             Assert.fail("Expecting OutOfRangeException");
602         } catch (OutOfRangeException ex) {
603             // expected
604         }
605     }
606 
607     @Test
608     public void testSetRowMatrix() {
609         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
610         FieldMatrix<Dfp> mRow3 = new Array2DRowFieldMatrix<>(subRow3);
611         Assert.assertNotSame(mRow3, m.getRowMatrix(0));
612         m.setRowMatrix(0, mRow3);
613         Assert.assertEquals(mRow3, m.getRowMatrix(0));
614         try {
615             m.setRowMatrix(-1, mRow3);
616             Assert.fail("Expecting OutOfRangeException");
617         } catch (OutOfRangeException ex) {
618             // expected
619         }
620         try {
621             m.setRowMatrix(0, m);
622             Assert.fail("Expecting MatrixDimensionMismatchException");
623         } catch (MatrixDimensionMismatchException ex) {
624             // expected
625         }
626     }
627 
628     @Test
629     public void testGetColumnMatrix() {
630         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
631         FieldMatrix<Dfp> mColumn1 = new Array2DRowFieldMatrix<>(subColumn1);
632         FieldMatrix<Dfp> mColumn3 = new Array2DRowFieldMatrix<>(subColumn3);
633         Assert.assertEquals("Column1", mColumn1,
634                 m.getColumnMatrix(1));
635         Assert.assertEquals("Column3", mColumn3,
636                 m.getColumnMatrix(3));
637         try {
638             m.getColumnMatrix(-1);
639             Assert.fail("Expecting OutOfRangeException");
640         } catch (OutOfRangeException ex) {
641             // expected
642         }
643         try {
644             m.getColumnMatrix(4);
645             Assert.fail("Expecting OutOfRangeException");
646         } catch (OutOfRangeException ex) {
647             // expected
648         }
649     }
650 
651     @Test
652     public void testSetColumnMatrix() {
653         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
654         FieldMatrix<Dfp> mColumn3 = new Array2DRowFieldMatrix<>(subColumn3);
655         Assert.assertNotSame(mColumn3, m.getColumnMatrix(1));
656         m.setColumnMatrix(1, mColumn3);
657         Assert.assertEquals(mColumn3, m.getColumnMatrix(1));
658         try {
659             m.setColumnMatrix(-1, mColumn3);
660             Assert.fail("Expecting OutOfRangeException");
661         } catch (OutOfRangeException ex) {
662             // expected
663         }
664         try {
665             m.setColumnMatrix(0, m);
666             Assert.fail("Expecting MatrixDimensionMismatchException");
667         } catch (MatrixDimensionMismatchException ex) {
668             // expected
669         }
670     }
671 
672     @Test
673     public void testGetRowVector() {
674         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
675         FieldVector<Dfp> mRow0 = new ArrayFieldVector<>(subRow0[0]);
676         FieldVector<Dfp> mRow3 = new ArrayFieldVector<>(subRow3[0]);
677         Assert.assertEquals("Row0", mRow0, m.getRowVector(0));
678         Assert.assertEquals("Row3", mRow3, m.getRowVector(3));
679         try {
680             m.getRowVector(-1);
681             Assert.fail("Expecting OutOfRangeException");
682         } catch (OutOfRangeException ex) {
683             // expected
684         }
685         try {
686             m.getRowVector(4);
687             Assert.fail("Expecting OutOfRangeException");
688         } catch (OutOfRangeException ex) {
689             // expected
690         }
691     }
692 
693     @Test
694     public void testSetRowVector() {
695         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
696         FieldVector<Dfp> mRow3 = new ArrayFieldVector<>(subRow3[0]);
697         Assert.assertNotSame(mRow3, m.getRowMatrix(0));
698         m.setRowVector(0, mRow3);
699         Assert.assertEquals(mRow3, m.getRowVector(0));
700         try {
701             m.setRowVector(-1, mRow3);
702             Assert.fail("Expecting OutOfRangeException");
703         } catch (OutOfRangeException ex) {
704             // expected
705         }
706         try {
707             m.setRowVector(0, new ArrayFieldVector<>(Dfp25.getField(), 5));
708             Assert.fail("Expecting MatrixDimensionMismatchException");
709         } catch (MatrixDimensionMismatchException ex) {
710             // expected
711         }
712     }
713 
714     @Test
715     public void testGetColumnVector() {
716         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
717         FieldVector<Dfp> mColumn1 = columnToVector(subColumn1);
718         FieldVector<Dfp> mColumn3 = columnToVector(subColumn3);
719         Assert.assertEquals("Column1", mColumn1, m.getColumnVector(1));
720         Assert.assertEquals("Column3", mColumn3, m.getColumnVector(3));
721         try {
722             m.getColumnVector(-1);
723             Assert.fail("Expecting OutOfRangeException");
724         } catch (OutOfRangeException ex) {
725             // expected
726         }
727         try {
728             m.getColumnVector(4);
729             Assert.fail("Expecting OutOfRangeException");
730         } catch (OutOfRangeException ex) {
731             // expected
732         }
733     }
734 
735     @Test
736     public void testSetColumnVector() {
737         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
738         FieldVector<Dfp> mColumn3 = columnToVector(subColumn3);
739         Assert.assertNotSame(mColumn3, m.getColumnVector(1));
740         m.setColumnVector(1, mColumn3);
741         Assert.assertEquals(mColumn3, m.getColumnVector(1));
742         try {
743             m.setColumnVector(-1, mColumn3);
744             Assert.fail("Expecting OutOfRangeException");
745         } catch (OutOfRangeException ex) {
746             // expected
747         }
748         try {
749             m.setColumnVector(0, new ArrayFieldVector<>(Dfp25.getField(), 5));
750             Assert.fail("Expecting MatrixDimensionMismatchException");
751         } catch (MatrixDimensionMismatchException ex) {
752             // expected
753         }
754     }
755 
756     private FieldVector<Dfp> columnToVector(Dfp[][] column) {
757         Dfp[] data = new Dfp[column.length];
758         for (int i = 0; i < data.length; ++i) {
759             data[i] = column[i][0];
760         }
761         return new ArrayFieldVector<>(data, false);
762     }
763 
764     @Test
765     public void testGetRow() {
766         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
767         checkArrays(subRow0[0], m.getRow(0));
768         checkArrays(subRow3[0], m.getRow(3));
769         try {
770             m.getRow(-1);
771             Assert.fail("Expecting OutOfRangeException");
772         } catch (OutOfRangeException ex) {
773             // expected
774         }
775         try {
776             m.getRow(4);
777             Assert.fail("Expecting OutOfRangeException");
778         } catch (OutOfRangeException ex) {
779             // expected
780         }
781     }
782 
783     @Test
784     public void testSetRow() {
785         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
786         Assert.assertNotSame(subRow3[0][0], m.getRow(0)[0]);
787         m.setRow(0, subRow3[0]);
788         checkArrays(subRow3[0], m.getRow(0));
789         try {
790             m.setRow(-1, subRow3[0]);
791             Assert.fail("Expecting OutOfRangeException");
792         } catch (OutOfRangeException ex) {
793             // expected
794         }
795         try {
796             m.setRow(0, new Dfp[5]);
797             Assert.fail("Expecting MatrixDimensionMismatchException");
798         } catch (MatrixDimensionMismatchException ex) {
799             // expected
800         }
801     }
802 
803     @Test
804     public void testGetColumn() {
805         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
806         Dfp[] mColumn1 = columnToArray(subColumn1);
807         Dfp[] mColumn3 = columnToArray(subColumn3);
808         checkArrays(mColumn1, m.getColumn(1));
809         checkArrays(mColumn3, m.getColumn(3));
810         try {
811             m.getColumn(-1);
812             Assert.fail("Expecting OutOfRangeException");
813         } catch (OutOfRangeException ex) {
814             // expected
815         }
816         try {
817             m.getColumn(4);
818             Assert.fail("Expecting OutOfRangeException");
819         } catch (OutOfRangeException ex) {
820             // expected
821         }
822     }
823 
824     @Test
825     public void testSetColumn() {
826         FieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(subTestData);
827         Dfp[] mColumn3 = columnToArray(subColumn3);
828         Assert.assertNotSame(mColumn3[0], m.getColumn(1)[0]);
829         m.setColumn(1, mColumn3);
830         checkArrays(mColumn3, m.getColumn(1));
831         try {
832             m.setColumn(-1, mColumn3);
833             Assert.fail("Expecting OutOfRangeException");
834         } catch (OutOfRangeException ex) {
835             // expected
836         }
837         try {
838             m.setColumn(0, new Dfp[5]);
839             Assert.fail("Expecting MatrixDimensionMismatchException");
840         } catch (MatrixDimensionMismatchException ex) {
841             // expected
842         }
843     }
844 
845     private Dfp[] columnToArray(Dfp[][] column) {
846         Dfp[] data = new Dfp[column.length];
847         for (int i = 0; i < data.length; ++i) {
848             data[i] = column[i][0];
849         }
850         return data;
851     }
852 
853     private void checkArrays(Dfp[] expected, Dfp[] actual) {
854         Assert.assertEquals(expected.length, actual.length);
855         for (int i = 0; i < expected.length; ++i) {
856             Assert.assertEquals(expected[i], actual[i]);
857         }
858     }
859 
860     @Test
861     public void testEqualsAndHashCode() {
862         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
863         Array2DRowFieldMatrix<Dfp> m1 = (Array2DRowFieldMatrix<Dfp>) m.copy();
864         Array2DRowFieldMatrix<Dfp> mt = (Array2DRowFieldMatrix<Dfp>) m.transpose();
865         Assert.assertTrue(m.hashCode() != mt.hashCode());
866         Assert.assertEquals(m.hashCode(), m1.hashCode());
867         Assert.assertEquals(m, m);
868         Assert.assertEquals(m, m1);
869         Assert.assertNotEquals(m, null);
870         Assert.assertNotEquals(m, mt);
871         Assert.assertNotEquals(m, new Array2DRowFieldMatrix<>(bigSingular));
872     }
873 
874     @Test
875     public void testToString() {
876         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
877         Assert.assertEquals("Array2DRowFieldMatrix{{1.,2.,3.},{2.,5.,3.},{1.,0.,8.}}", m.toString());
878         m = new Array2DRowFieldMatrix<>(Dfp25.getField());
879         Assert.assertEquals("Array2DRowFieldMatrix{}", m.toString());
880     }
881 
882     @Test
883     public void testSetSubMatrix() {
884         Array2DRowFieldMatrix<Dfp> m = new Array2DRowFieldMatrix<>(testData);
885         m.setSubMatrix(detData2,1,1);
886         FieldMatrix<Dfp> expected = new Array2DRowFieldMatrix<>
887             (new Dfp[][] {
888                     {Dfp25.of(1),Dfp25.of(2),Dfp25.of(3)},
889                     {Dfp25.of(2),Dfp25.of(1),Dfp25.of(3)},
890                     {Dfp25.of(1),Dfp25.of(2),Dfp25.of(4)}
891              });
892         Assert.assertEquals(expected, m);
893 
894         m.setSubMatrix(detData2,0,0);
895         expected = new Array2DRowFieldMatrix<>
896             (new Dfp[][] {
897                     {Dfp25.of(1),Dfp25.of(3),Dfp25.of(3)},
898                     {Dfp25.of(2),Dfp25.of(4),Dfp25.of(3)},
899                     {Dfp25.of(1),Dfp25.of(2),Dfp25.of(4)}
900              });
901         Assert.assertEquals(expected, m);
902 
903         m.setSubMatrix(testDataPlus2,0,0);
904         expected = new Array2DRowFieldMatrix<>
905             (new Dfp[][] {
906                     {Dfp25.of(3),Dfp25.of(4),Dfp25.of(5)},
907                     {Dfp25.of(4),Dfp25.of(7),Dfp25.of(5)},
908                     {Dfp25.of(3),Dfp25.of(2),Dfp25.of(10)}
909              });
910         Assert.assertEquals(expected, m);
911 
912         // dimension overflow
913         try {
914             m.setSubMatrix(testData,1,1);
915             Assert.fail("expecting OutOfRangeException");
916         } catch (OutOfRangeException e) {
917             // expected
918         }
919         // dimension underflow
920         try {
921             m.setSubMatrix(testData,-1,1);
922             Assert.fail("expecting OutOfRangeException");
923         } catch (OutOfRangeException e) {
924             // expected
925         }
926         try {
927             m.setSubMatrix(testData,1,-1);
928             Assert.fail("expecting OutOfRangeException");
929         } catch (OutOfRangeException e) {
930             // expected
931         }
932 
933         // null
934         try {
935             m.setSubMatrix(null, 1, 1);
936             Assert.fail("expecting NullArgumentException");
937         } catch (NullArgumentException e) {
938             // expected
939         }
940         Array2DRowFieldMatrix<Dfp> m2 = new Array2DRowFieldMatrix<>(Dfp25.getField());
941         try {
942             m2.setSubMatrix(testData,0,1);
943             Assert.fail("expecting MathIllegalStateException");
944         } catch (MathIllegalStateException e) {
945             // expected
946         }
947         try {
948             m2.setSubMatrix(testData,1,0);
949             Assert.fail("expecting MathIllegalStateException");
950         } catch (MathIllegalStateException e) {
951             // expected
952         }
953 
954         // ragged
955         try {
956             m.setSubMatrix(new Dfp[][] {{Dfp25.of(1)}, {Dfp25.of(2), Dfp25.of(3)}}, 0, 0);
957             Assert.fail("expecting MathIllegalArgumentException");
958         } catch (MathIllegalArgumentException e) {
959             // expected
960         }
961 
962         // empty
963         try {
964             m.setSubMatrix(new Dfp[][] {{}}, 0, 0);
965             Assert.fail("expecting MathIllegalArgumentException");
966         } catch (MathIllegalArgumentException e) {
967             // expected
968         }
969     }
970 
971     @Test
972     public void testWalk() {
973         int rows    = 150;
974         int columns = 75;
975 
976         FieldMatrix<Dfp> m =
977             new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
978         m.walkInRowOrder(new SetVisitor());
979         GetVisitor getVisitor = new GetVisitor();
980         m.walkInOptimizedOrder(getVisitor);
981         Assert.assertEquals(rows * columns, getVisitor.getCount());
982 
983         m = new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
984         m.walkInRowOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
985         getVisitor = new GetVisitor();
986         m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2);
987         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
988         for (int i = 0; i < rows; ++i) {
989             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, 0));
990             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, columns - 1));
991         }
992         for (int j = 0; j < columns; ++j) {
993             Assert.assertEquals(Dfp25.of(0), m.getEntry(0, j));
994             Assert.assertEquals(Dfp25.of(0), m.getEntry(rows - 1, j));
995         }
996 
997         m = new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
998         m.walkInColumnOrder(new SetVisitor());
999         getVisitor = new GetVisitor();
1000         m.walkInOptimizedOrder(getVisitor);
1001         Assert.assertEquals(rows * columns, getVisitor.getCount());
1002 
1003         m = new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
1004         m.walkInColumnOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
1005         getVisitor = new GetVisitor();
1006         m.walkInOptimizedOrder(getVisitor, 1, rows - 2, 1, columns - 2);
1007         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
1008         for (int i = 0; i < rows; ++i) {
1009             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, 0));
1010             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, columns - 1));
1011         }
1012         for (int j = 0; j < columns; ++j) {
1013             Assert.assertEquals(Dfp25.of(0), m.getEntry(0, j));
1014             Assert.assertEquals(Dfp25.of(0), m.getEntry(rows - 1, j));
1015         }
1016 
1017         m = new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
1018         m.walkInOptimizedOrder(new SetVisitor());
1019         getVisitor = new GetVisitor();
1020         m.walkInRowOrder(getVisitor);
1021         Assert.assertEquals(rows * columns, getVisitor.getCount());
1022 
1023         m = new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
1024         m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
1025         getVisitor = new GetVisitor();
1026         m.walkInRowOrder(getVisitor, 1, rows - 2, 1, columns - 2);
1027         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
1028         for (int i = 0; i < rows; ++i) {
1029             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, 0));
1030             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, columns - 1));
1031         }
1032         for (int j = 0; j < columns; ++j) {
1033             Assert.assertEquals(Dfp25.of(0), m.getEntry(0, j));
1034             Assert.assertEquals(Dfp25.of(0), m.getEntry(rows - 1, j));
1035         }
1036 
1037         m = new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
1038         m.walkInOptimizedOrder(new SetVisitor());
1039         getVisitor = new GetVisitor();
1040         m.walkInColumnOrder(getVisitor);
1041         Assert.assertEquals(rows * columns, getVisitor.getCount());
1042 
1043         m = new Array2DRowFieldMatrix<>(Dfp25.getField(), rows, columns);
1044         m.walkInOptimizedOrder(new SetVisitor(), 1, rows - 2, 1, columns - 2);
1045         getVisitor = new GetVisitor();
1046         m.walkInColumnOrder(getVisitor, 1, rows - 2, 1, columns - 2);
1047         Assert.assertEquals((rows - 2) * (columns - 2), getVisitor.getCount());
1048         for (int i = 0; i < rows; ++i) {
1049             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, 0));
1050             Assert.assertEquals(Dfp25.of(0), m.getEntry(i, columns - 1));
1051         }
1052         for (int j = 0; j < columns; ++j) {
1053             Assert.assertEquals(Dfp25.of(0), m.getEntry(0, j));
1054             Assert.assertEquals(Dfp25.of(0), m.getEntry(rows - 1, j));
1055         }
1056     }
1057 
1058     @Test
1059     public void testSerial()  {
1060         final int r = 2;
1061         final int c = 3;
1062         Array2DRowFieldMatrix<BigReal> m = new Array2DRowFieldMatrix<>(BigRealField.getInstance(), r, c);
1063         for (int i = 0; i < r; i++) {
1064             for (int j = 0; j < c; j++) {
1065                 m.setEntry(i, j, new BigReal(Math.random()));
1066             }
1067         }
1068         Assert.assertEquals(m,TestUtils.serializeAndRecover(m));
1069     }
1070 
1071     private static final class SetVisitor extends DefaultFieldMatrixChangingVisitor<Dfp> {
1072         SetVisitor() {
1073             super(Dfp25.ZERO);
1074         }
1075         @Override
1076         public Dfp visit(int i, int j, Dfp value) {
1077             return Dfp25.of(i * 1024 + j, 1024);
1078         }
1079     }
1080 
1081     private static final class GetVisitor extends DefaultFieldMatrixPreservingVisitor<Dfp> {
1082         private int count;
1083         GetVisitor() {
1084             super(Dfp25.ZERO);
1085             count = 0;
1086         }
1087         @Override
1088         public void visit(int i, int j, Dfp value) {
1089             ++count;
1090             Assert.assertEquals(Dfp25.of(i * 1024 + j, 1024), value);
1091         }
1092         public int getCount() {
1093             return count;
1094         }
1095     }
1096 
1097     //--------------- -----------------Protected methods
1098 
1099     /** extracts the l  and u matrices from compact lu representation */
1100     protected void splitLU(FieldMatrix<Dfp> lu,
1101                            Dfp[][] lowerData,
1102                            Dfp[][] upperData) {
1103         if (!lu.isSquare()) {
1104             throw new NonSquareMatrixException(lu.getRowDimension(), lu.getColumnDimension());
1105         }
1106         if (lowerData.length != lowerData[0].length) {
1107             throw new DimensionMismatchException(lowerData.length, lowerData[0].length);
1108         }
1109         if (upperData.length != upperData[0].length) {
1110             throw new DimensionMismatchException(upperData.length, upperData[0].length);
1111         }
1112         if (lowerData.length != upperData.length) {
1113             throw new DimensionMismatchException(lowerData.length, upperData.length);
1114         }
1115         if (lowerData.length != lu.getRowDimension()) {
1116             throw new DimensionMismatchException(lowerData.length, lu.getRowDimension());
1117         }
1118         int n = lu.getRowDimension();
1119         for (int i = 0; i < n; i++) {
1120             for (int j = 0; j < n; j++) {
1121                 if (j < i) {
1122                     lowerData[i][j] = lu.getEntry(i, j);
1123                     upperData[i][j] = Dfp25.ZERO;
1124                 } else if (i == j) {
1125                     lowerData[i][j] = Dfp25.ONE;
1126                     upperData[i][j] = lu.getEntry(i, j);
1127                 } else {
1128                     lowerData[i][j] = Dfp25.ZERO;
1129                     upperData[i][j] = lu.getEntry(i, j);
1130                 }
1131             }
1132         }
1133     }
1134 
1135     /** Returns the result of applying the given row permutation to the matrix */
1136     protected FieldMatrix<Dfp> permuteRows(FieldMatrix<Dfp> matrix, int[] permutation) {
1137         if (!matrix.isSquare()) {
1138             throw new NonSquareMatrixException(matrix.getRowDimension(),
1139                                                matrix.getColumnDimension());
1140         }
1141         if (matrix.getRowDimension() != permutation.length) {
1142             throw new DimensionMismatchException(matrix.getRowDimension(), permutation.length);
1143         }
1144         int n = matrix.getRowDimension();
1145         int m = matrix.getColumnDimension();
1146         Dfp out[][] = new Dfp[m][n];
1147         for (int i = 0; i < n; i++) {
1148             for (int j = 0; j < m; j++) {
1149                 out[i][j] = matrix.getEntry(permutation[i], j);
1150             }
1151         }
1152         return new Array2DRowFieldMatrix<>(out);
1153     }
1154 }