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