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