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