001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.math.linear; 018 019 import org.apache.commons.math.Field; 020 import org.apache.commons.math.fraction.Fraction; 021 import org.apache.commons.math.fraction.FractionConversionException; 022 import org.apache.commons.math.fraction.FractionField; 023 024 import junit.framework.Test; 025 import junit.framework.TestCase; 026 import junit.framework.TestSuite; 027 028 /** 029 * Test cases for the {@link SparseFieldMatrix} class. 030 * 031 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ 032 */ 033 public class SparseFieldMatrixTest extends TestCase { 034 // 3 x 3 identity matrix 035 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) } }; 036 // Test data for group operations 037 protected Fraction[][] testData = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(5), new Fraction(3) }, 038 { new Fraction(1), new Fraction(0), new Fraction(8) } }; 039 protected Fraction[][] testDataLU = null; 040 protected Fraction[][] testDataPlus2 = { { new Fraction(3), new Fraction(4), new Fraction(5) }, { new Fraction(4), new Fraction(7), new Fraction(5) }, 041 { new Fraction(3), new Fraction(2), new Fraction(10) } }; 042 protected Fraction[][] testDataMinus = { { new Fraction(-1), new Fraction(-2), new Fraction(-3) }, 043 { new Fraction(-2), new Fraction(-5), new Fraction(-3) }, { new Fraction(-1), new Fraction(0), new Fraction(-8) } }; 044 protected Fraction[] testDataRow1 = { new Fraction(1), new Fraction(2), new Fraction(3) }; 045 protected Fraction[] testDataCol3 = { new Fraction(3), new Fraction(3), new Fraction(8) }; 046 protected Fraction[][] testDataInv = { { new Fraction(-40), new Fraction(16), new Fraction(9) }, { new Fraction(13), new Fraction(-5), new Fraction(-3) }, 047 { new Fraction(5), new Fraction(-2), new Fraction(-1) } }; 048 protected Fraction[] preMultTest = { new Fraction(8), new Fraction(12), new Fraction(33) }; 049 protected Fraction[][] testData2 = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(5), new Fraction(3) } }; 050 protected Fraction[][] testData2T = { { new Fraction(1), new Fraction(2) }, { new Fraction(2), new Fraction(5) }, { new Fraction(3), new Fraction(3) } }; 051 protected Fraction[][] testDataPlusInv = { { new Fraction(-39), new Fraction(18), new Fraction(12) }, 052 { new Fraction(15), new Fraction(0), new Fraction(0) }, { new Fraction(6), new Fraction(-2), new Fraction(7) } }; 053 054 // lu decomposition tests 055 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) } }; 056 protected Fraction[][] luDataLUDecomposition = null; 057 058 // singular matrices 059 protected Fraction[][] singular = { { new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(3) } }; 060 protected Fraction[][] bigSingular = { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, 061 { new Fraction(2), new Fraction(5), new Fraction(3), new Fraction(4) }, { 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 062 063 // row 064 // = 065 // 1st 066 // + 067 // 2nd 068 protected Fraction[][] detData = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(4), new Fraction(5), new Fraction(6) }, 069 { new Fraction(7), new Fraction(8), new Fraction(10) } }; 070 protected Fraction[][] detData2 = { { new Fraction(1), new Fraction(3) }, { new Fraction(2), new Fraction(4) } }; 071 072 // vectors 073 protected Fraction[] testVector = { new Fraction(1), new Fraction(2), new Fraction(3) }; 074 protected Fraction[] testVector2 = { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }; 075 076 // submatrix accessor tests 077 protected Fraction[][] subTestData = null; 078 079 // array selections 080 protected Fraction[][] subRows02Cols13 = { {new Fraction(2), new Fraction(4) }, { new Fraction(4), new Fraction(8) } }; 081 protected Fraction[][] subRows03Cols12 = { { new Fraction(2), new Fraction(3) }, { new Fraction(5), new Fraction(6) } }; 082 protected Fraction[][] subRows03Cols123 = { { new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6), new Fraction(7) } }; 083 084 // effective permutations 085 protected Fraction[][] subRows20Cols123 = { { new Fraction(4), new Fraction(6), new Fraction(8) }, { new Fraction(2), new Fraction(3), new Fraction(4) } }; 086 protected Fraction[][] subRows31Cols31 = null; 087 088 // contiguous ranges 089 protected Fraction[][] subRows01Cols23 = null; 090 protected Fraction[][] subRows23Cols00 = { { new Fraction(2) }, { new Fraction(4) } }; 091 protected Fraction[][] subRows00Cols33 = { { new Fraction(4) } }; 092 093 // row matrices 094 protected Fraction[][] subRow0 = { { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) } }; 095 protected Fraction[][] subRow3 = { { new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7) } }; 096 097 // column matrices 098 protected Fraction[][] subColumn1 = null; 099 protected Fraction[][] subColumn3 = null; 100 101 // tolerances 102 protected double entryTolerance = 10E-16; 103 protected double normTolerance = 10E-14; 104 protected Field<Fraction> field = FractionField.getInstance(); 105 106 public SparseFieldMatrixTest(String name) { 107 super(name); 108 setupFractionArrays(); 109 } 110 111 private void setupFractionArrays() { 112 try { 113 testDataLU = new Fraction[][]{ { new Fraction(2), new Fraction(5), new Fraction(3) }, { new Fraction(.5d), new Fraction(-2.5d), new Fraction(6.5d) }, 114 { new Fraction(0.5d), new Fraction(0.2d), new Fraction(.2d) } }; 115 luDataLUDecomposition = new Fraction[][]{ { new Fraction(6), new Fraction(9), new Fraction(8) }, 116 { new Fraction(0), new Fraction(5), new Fraction(7) }, { new Fraction(0.33333333333333), new Fraction(0), new Fraction(0.33333333333333) } }; 117 subTestData = new Fraction [][]{ { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, 118 { new Fraction(1.5), new Fraction(2.5), new Fraction(3.5), new Fraction(4.5) }, { new Fraction(2), new Fraction(4), new Fraction(6), new Fraction(8) }, { new Fraction(4), new Fraction(5), new Fraction(6), new Fraction(7) } }; 119 subRows31Cols31 = new Fraction[][]{ { new Fraction(7), new Fraction(5) }, { new Fraction(4.5), new Fraction(2.5) } }; 120 subRows01Cols23 = new Fraction[][]{ { new Fraction(3), new Fraction(4) }, { new Fraction(3.5), new Fraction(4.5) } }; 121 subColumn1 = new Fraction [][]{ { new Fraction(2) }, { new Fraction(2.5) }, { new Fraction(4) }, { new Fraction(5) } }; 122 subColumn3 = new Fraction[][]{ { new Fraction(4) }, { new Fraction(4.5) }, { new Fraction(8) }, { new Fraction(7) } }; 123 } catch (FractionConversionException e) { 124 // ignore, can't happen 125 } 126 127 128 } 129 130 public static Test suite() { 131 TestSuite suite = new TestSuite(SparseFieldMatrixTest.class); 132 suite.setName("SparseFieldMatrix<Fraction> Tests"); 133 return suite; 134 } 135 136 /** test dimensions */ 137 public void testDimensions() { 138 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 139 SparseFieldMatrix<Fraction> m2 = createSparseMatrix(testData2); 140 assertEquals("testData row dimension", 3, m.getRowDimension()); 141 assertEquals("testData column dimension", 3, m.getColumnDimension()); 142 assertTrue("testData is square", m.isSquare()); 143 assertEquals("testData2 row dimension", m2.getRowDimension(), 2); 144 assertEquals("testData2 column dimension", m2.getColumnDimension(), 3); 145 assertTrue("testData2 is not square", !m2.isSquare()); 146 } 147 148 /** test copy functions */ 149 public void testCopyFunctions() { 150 SparseFieldMatrix<Fraction> m1 = createSparseMatrix(testData); 151 FieldMatrix<Fraction> m2 = m1.copy(); 152 assertEquals(m1.getClass(), m2.getClass()); 153 assertEquals((m2), m1); 154 SparseFieldMatrix<Fraction> m3 = createSparseMatrix(testData); 155 FieldMatrix<Fraction> m4 = m3.copy(); 156 assertEquals(m3.getClass(), m4.getClass()); 157 assertEquals((m4), m3); 158 } 159 160 /** test add */ 161 public void testAdd() { 162 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 163 SparseFieldMatrix<Fraction> mInv = createSparseMatrix(testDataInv); 164 SparseFieldMatrix<Fraction> mDataPlusInv = createSparseMatrix(testDataPlusInv); 165 FieldMatrix<Fraction> mPlusMInv = m.add(mInv); 166 for (int row = 0; row < m.getRowDimension(); row++) { 167 for (int col = 0; col < m.getColumnDimension(); col++) { 168 assertEquals("sum entry entry", 169 mDataPlusInv.getEntry(row, col).doubleValue(), mPlusMInv.getEntry(row, col).doubleValue(), 170 entryTolerance); 171 } 172 } 173 } 174 175 /** test add failure */ 176 public void testAddFail() { 177 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 178 SparseFieldMatrix<Fraction> m2 = createSparseMatrix(testData2); 179 try { 180 m.add(m2); 181 fail("IllegalArgumentException expected"); 182 } catch (IllegalArgumentException ex) { 183 // ignored 184 } 185 } 186 187 188 /** test m-n = m + -n */ 189 public void testPlusMinus() { 190 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 191 SparseFieldMatrix<Fraction> n = createSparseMatrix(testDataInv); 192 assertClose("m-n = m + -n", m.subtract(n), 193 n.scalarMultiply(new Fraction(-1)).add(m), entryTolerance); 194 try { 195 m.subtract(createSparseMatrix(testData2)); 196 fail("Expecting illegalArgumentException"); 197 } catch (IllegalArgumentException ex) { 198 // ignored 199 } 200 } 201 202 /** test multiply */ 203 public void testMultiply() { 204 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 205 SparseFieldMatrix<Fraction> mInv = createSparseMatrix(testDataInv); 206 SparseFieldMatrix<Fraction> identity = createSparseMatrix(id); 207 SparseFieldMatrix<Fraction> m2 = createSparseMatrix(testData2); 208 assertClose("inverse multiply", m.multiply(mInv), identity, 209 entryTolerance); 210 assertClose("inverse multiply", m.multiply(new Array2DRowFieldMatrix<Fraction>(testDataInv)), identity, 211 entryTolerance); 212 assertClose("inverse multiply", mInv.multiply(m), identity, 213 entryTolerance); 214 assertClose("identity multiply", m.multiply(identity), m, 215 entryTolerance); 216 assertClose("identity multiply", identity.multiply(mInv), mInv, 217 entryTolerance); 218 assertClose("identity multiply", m2.multiply(identity), m2, 219 entryTolerance); 220 try { 221 m.multiply(createSparseMatrix(bigSingular)); 222 fail("Expecting illegalArgumentException"); 223 } catch (IllegalArgumentException ex) { 224 // ignored 225 } 226 } 227 228 // Additional Test for Array2DRowRealMatrixTest.testMultiply 229 230 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) } }; 231 private Fraction[][] d4 = new Fraction[][] { { new Fraction(1) }, { new Fraction(2) }, { new Fraction(3) }, { new Fraction(4) } }; 232 private Fraction[][] d5 = new Fraction[][] { { new Fraction(30) }, { new Fraction(70) } }; 233 234 public void testMultiply2() { 235 FieldMatrix<Fraction> m3 = createSparseMatrix(d3); 236 FieldMatrix<Fraction> m4 = createSparseMatrix(d4); 237 FieldMatrix<Fraction> m5 = createSparseMatrix(d5); 238 assertClose("m3*m4=m5", m3.multiply(m4), m5, entryTolerance); 239 } 240 241 /** test trace */ 242 public void testTrace() { 243 FieldMatrix<Fraction> m = createSparseMatrix(id); 244 assertEquals("identity trace", 3d, m.getTrace().doubleValue(), entryTolerance); 245 m = createSparseMatrix(testData2); 246 try { 247 m.getTrace(); 248 fail("Expecting NonSquareMatrixException"); 249 } catch (NonSquareMatrixException ex) { 250 // ignored 251 } 252 } 253 254 /** test sclarAdd */ 255 public void testScalarAdd() { 256 FieldMatrix<Fraction> m = createSparseMatrix(testData); 257 assertClose("scalar add", createSparseMatrix(testDataPlus2), 258 m.scalarAdd(new Fraction(2)), entryTolerance); 259 } 260 261 /** test operate */ 262 public void testOperate() { 263 FieldMatrix<Fraction> m = createSparseMatrix(id); 264 assertClose("identity operate", testVector, m.operate(testVector), 265 entryTolerance); 266 assertClose("identity operate", testVector, m.operate( 267 new ArrayFieldVector<Fraction>(testVector)).getData(), entryTolerance); 268 m = createSparseMatrix(bigSingular); 269 try { 270 m.operate(testVector); 271 fail("Expecting illegalArgumentException"); 272 } catch (IllegalArgumentException ex) { 273 // ignored 274 } 275 } 276 277 /** test issue MATH-209 */ 278 public void testMath209() { 279 FieldMatrix<Fraction> a = createSparseMatrix(new Fraction[][] { 280 { new Fraction(1), new Fraction(2) }, { new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6) } }); 281 Fraction[] b = a.operate(new Fraction[] { new Fraction(1), new Fraction(1) }); 282 assertEquals(a.getRowDimension(), b.length); 283 assertEquals(3.0, b[0].doubleValue(), 1.0e-12); 284 assertEquals(7.0, b[1].doubleValue(), 1.0e-12); 285 assertEquals(11.0, b[2].doubleValue(), 1.0e-12); 286 } 287 288 /** test transpose */ 289 public void testTranspose() { 290 291 FieldMatrix<Fraction> m = createSparseMatrix(testData); 292 FieldMatrix<Fraction> mIT = new FieldLUDecompositionImpl<Fraction>(m).getSolver().getInverse().transpose(); 293 FieldMatrix<Fraction> mTI = new FieldLUDecompositionImpl<Fraction>(m.transpose()).getSolver().getInverse(); 294 assertClose("inverse-transpose", mIT, mTI, normTolerance); 295 m = createSparseMatrix(testData2); 296 FieldMatrix<Fraction> mt = createSparseMatrix(testData2T); 297 assertClose("transpose",mt,m.transpose(),normTolerance); 298 } 299 300 /** test preMultiply by vector */ 301 public void testPremultiplyVector() { 302 FieldMatrix<Fraction> m = createSparseMatrix(testData); 303 assertClose("premultiply", m.preMultiply(testVector), preMultTest, 304 normTolerance); 305 assertClose("premultiply", m.preMultiply( 306 new ArrayFieldVector<Fraction>(testVector).getData()), preMultTest, normTolerance); 307 m = createSparseMatrix(bigSingular); 308 try { 309 m.preMultiply(testVector); 310 fail("expecting IllegalArgumentException"); 311 } catch (IllegalArgumentException ex) { 312 // ignored 313 } 314 } 315 316 public void testPremultiply() { 317 FieldMatrix<Fraction> m3 = createSparseMatrix(d3); 318 FieldMatrix<Fraction> m4 = createSparseMatrix(d4); 319 FieldMatrix<Fraction> m5 = createSparseMatrix(d5); 320 assertClose("m3*m4=m5", m4.preMultiply(m3), m5, entryTolerance); 321 322 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 323 SparseFieldMatrix<Fraction> mInv = createSparseMatrix(testDataInv); 324 SparseFieldMatrix<Fraction> identity = createSparseMatrix(id); 325 assertClose("inverse multiply", m.preMultiply(mInv), identity, 326 entryTolerance); 327 assertClose("inverse multiply", mInv.preMultiply(m), identity, 328 entryTolerance); 329 assertClose("identity multiply", m.preMultiply(identity), m, 330 entryTolerance); 331 assertClose("identity multiply", identity.preMultiply(mInv), mInv, 332 entryTolerance); 333 try { 334 m.preMultiply(createSparseMatrix(bigSingular)); 335 fail("Expecting illegalArgumentException"); 336 } catch (IllegalArgumentException ex) { 337 // ignored 338 } 339 } 340 341 public void testGetVectors() { 342 FieldMatrix<Fraction> m = createSparseMatrix(testData); 343 assertClose("get row", m.getRow(0), testDataRow1, entryTolerance); 344 assertClose("get col", m.getColumn(2), testDataCol3, entryTolerance); 345 try { 346 m.getRow(10); 347 fail("expecting MatrixIndexException"); 348 } catch (MatrixIndexException ex) { 349 // ignored 350 } 351 try { 352 m.getColumn(-1); 353 fail("expecting MatrixIndexException"); 354 } catch (MatrixIndexException ex) { 355 // ignored 356 } 357 } 358 359 public void testGetEntry() { 360 FieldMatrix<Fraction> m = createSparseMatrix(testData); 361 assertEquals("get entry", m.getEntry(0, 1).doubleValue(), 2d, entryTolerance); 362 try { 363 m.getEntry(10, 4); 364 fail("Expecting MatrixIndexException"); 365 } catch (MatrixIndexException ex) { 366 // expected 367 } 368 } 369 370 /** test examples in user guide */ 371 public void testExamples() { 372 // Create a real matrix with two rows and three columns 373 Fraction[][] matrixData = { { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(5), new Fraction(3) } }; 374 FieldMatrix<Fraction> m = createSparseMatrix(matrixData); 375 // One more with three rows, two columns 376 Fraction[][] matrixData2 = { { new Fraction(1), new Fraction(2) }, { new Fraction(2), new Fraction(5) }, { new Fraction(1), new Fraction(7) } }; 377 FieldMatrix<Fraction> n = createSparseMatrix(matrixData2); 378 // Now multiply m by n 379 FieldMatrix<Fraction> p = m.multiply(n); 380 assertEquals(2, p.getRowDimension()); 381 assertEquals(2, p.getColumnDimension()); 382 // Invert p 383 FieldMatrix<Fraction> pInverse = new FieldLUDecompositionImpl<Fraction>(p).getSolver().getInverse(); 384 assertEquals(2, pInverse.getRowDimension()); 385 assertEquals(2, pInverse.getColumnDimension()); 386 387 // Solve example 388 Fraction[][] coefficientsData = { { new Fraction(2), new Fraction(3), new Fraction(-2) }, { new Fraction(-1), new Fraction(7), new Fraction(6) }, 389 { new Fraction(4), new Fraction(-3), new Fraction(-5) } }; 390 FieldMatrix<Fraction> coefficients = createSparseMatrix(coefficientsData); 391 Fraction[] constants = { new Fraction(1), new Fraction(-2), new Fraction(1) }; 392 Fraction[] solution = new FieldLUDecompositionImpl<Fraction>(coefficients).getSolver().solve(constants); 393 assertEquals((new Fraction(2).multiply((solution[0])).add(new Fraction(3).multiply(solution[1])).subtract(new Fraction(2).multiply(solution[2]))).doubleValue(), 394 constants[0].doubleValue(), 1E-12); 395 assertEquals(((new Fraction(-1).multiply(solution[0])).add(new Fraction(7).multiply(solution[1])).add(new Fraction(6).multiply(solution[2]))).doubleValue(), 396 constants[1].doubleValue(), 1E-12); 397 assertEquals(((new Fraction(4).multiply(solution[0])).subtract(new Fraction(3).multiply( solution[1])).subtract(new Fraction(5).multiply(solution[2]))).doubleValue(), 398 constants[2].doubleValue(), 1E-12); 399 400 } 401 402 // test submatrix accessors 403 public void testSubMatrix() { 404 FieldMatrix<Fraction> m = createSparseMatrix(subTestData); 405 FieldMatrix<Fraction> mRows23Cols00 = createSparseMatrix(subRows23Cols00); 406 FieldMatrix<Fraction> mRows00Cols33 = createSparseMatrix(subRows00Cols33); 407 FieldMatrix<Fraction> mRows01Cols23 = createSparseMatrix(subRows01Cols23); 408 FieldMatrix<Fraction> mRows02Cols13 = createSparseMatrix(subRows02Cols13); 409 FieldMatrix<Fraction> mRows03Cols12 = createSparseMatrix(subRows03Cols12); 410 FieldMatrix<Fraction> mRows03Cols123 = createSparseMatrix(subRows03Cols123); 411 FieldMatrix<Fraction> mRows20Cols123 = createSparseMatrix(subRows20Cols123); 412 FieldMatrix<Fraction> mRows31Cols31 = createSparseMatrix(subRows31Cols31); 413 assertEquals("Rows23Cols00", mRows23Cols00, m.getSubMatrix(2, 3, 0, 0)); 414 assertEquals("Rows00Cols33", mRows00Cols33, m.getSubMatrix(0, 0, 3, 3)); 415 assertEquals("Rows01Cols23", mRows01Cols23, m.getSubMatrix(0, 1, 2, 3)); 416 assertEquals("Rows02Cols13", mRows02Cols13, 417 m.getSubMatrix(new int[] { 0, 2 }, new int[] { 1, 3 })); 418 assertEquals("Rows03Cols12", mRows03Cols12, 419 m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2 })); 420 assertEquals("Rows03Cols123", mRows03Cols123, 421 m.getSubMatrix(new int[] { 0, 3 }, new int[] { 1, 2, 3 })); 422 assertEquals("Rows20Cols123", mRows20Cols123, 423 m.getSubMatrix(new int[] { 2, 0 }, new int[] { 1, 2, 3 })); 424 assertEquals("Rows31Cols31", mRows31Cols31, 425 m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 })); 426 assertEquals("Rows31Cols31", mRows31Cols31, 427 m.getSubMatrix(new int[] { 3, 1 }, new int[] { 3, 1 })); 428 429 try { 430 m.getSubMatrix(1, 0, 2, 4); 431 fail("Expecting MatrixIndexException"); 432 } catch (MatrixIndexException ex) { 433 // expected 434 } 435 try { 436 m.getSubMatrix(-1, 1, 2, 2); 437 fail("Expecting MatrixIndexException"); 438 } catch (MatrixIndexException ex) { 439 // expected 440 } 441 try { 442 m.getSubMatrix(1, 0, 2, 2); 443 fail("Expecting MatrixIndexException"); 444 } catch (MatrixIndexException ex) { 445 // expected 446 } 447 try { 448 m.getSubMatrix(1, 0, 2, 4); 449 fail("Expecting MatrixIndexException"); 450 } catch (MatrixIndexException ex) { 451 // expected 452 } 453 try { 454 m.getSubMatrix(new int[] {}, new int[] { 0 }); 455 fail("Expecting MatrixIndexException"); 456 } catch (MatrixIndexException ex) { 457 // expected 458 } 459 try { 460 m.getSubMatrix(new int[] { 0 }, new int[] { 4 }); 461 fail("Expecting MatrixIndexException"); 462 } catch (MatrixIndexException ex) { 463 // expected 464 } 465 } 466 467 public void testGetRowMatrix() { 468 FieldMatrix<Fraction> m = createSparseMatrix(subTestData); 469 FieldMatrix<Fraction> mRow0 = createSparseMatrix(subRow0); 470 FieldMatrix<Fraction> mRow3 = createSparseMatrix(subRow3); 471 assertEquals("Row0", mRow0, m.getRowMatrix(0)); 472 assertEquals("Row3", mRow3, m.getRowMatrix(3)); 473 try { 474 m.getRowMatrix(-1); 475 fail("Expecting MatrixIndexException"); 476 } catch (MatrixIndexException ex) { 477 // expected 478 } 479 try { 480 m.getRowMatrix(4); 481 fail("Expecting MatrixIndexException"); 482 } catch (MatrixIndexException ex) { 483 // expected 484 } 485 } 486 487 public void testGetColumnMatrix() { 488 FieldMatrix<Fraction> m = createSparseMatrix(subTestData); 489 FieldMatrix<Fraction> mColumn1 = createSparseMatrix(subColumn1); 490 FieldMatrix<Fraction> mColumn3 = createSparseMatrix(subColumn3); 491 assertEquals("Column1", mColumn1, m.getColumnMatrix(1)); 492 assertEquals("Column3", mColumn3, m.getColumnMatrix(3)); 493 try { 494 m.getColumnMatrix(-1); 495 fail("Expecting MatrixIndexException"); 496 } catch (MatrixIndexException ex) { 497 // expected 498 } 499 try { 500 m.getColumnMatrix(4); 501 fail("Expecting MatrixIndexException"); 502 } catch (MatrixIndexException ex) { 503 // expected 504 } 505 } 506 507 public void testGetRowVector() { 508 FieldMatrix<Fraction> m = createSparseMatrix(subTestData); 509 FieldVector<Fraction> mRow0 = new ArrayFieldVector<Fraction>(subRow0[0]); 510 FieldVector<Fraction> mRow3 = new ArrayFieldVector<Fraction>(subRow3[0]); 511 assertEquals("Row0", mRow0, m.getRowVector(0)); 512 assertEquals("Row3", mRow3, m.getRowVector(3)); 513 try { 514 m.getRowVector(-1); 515 fail("Expecting MatrixIndexException"); 516 } catch (MatrixIndexException ex) { 517 // expected 518 } 519 try { 520 m.getRowVector(4); 521 fail("Expecting MatrixIndexException"); 522 } catch (MatrixIndexException ex) { 523 // expected 524 } 525 } 526 527 public void testGetColumnVector() { 528 FieldMatrix<Fraction> m = createSparseMatrix(subTestData); 529 FieldVector<Fraction> mColumn1 = columnToVector(subColumn1); 530 FieldVector<Fraction> mColumn3 = columnToVector(subColumn3); 531 assertEquals("Column1", mColumn1, m.getColumnVector(1)); 532 assertEquals("Column3", mColumn3, m.getColumnVector(3)); 533 try { 534 m.getColumnVector(-1); 535 fail("Expecting MatrixIndexException"); 536 } catch (MatrixIndexException ex) { 537 // expected 538 } 539 try { 540 m.getColumnVector(4); 541 fail("Expecting MatrixIndexException"); 542 } catch (MatrixIndexException ex) { 543 // expected 544 } 545 } 546 547 private FieldVector<Fraction> columnToVector(Fraction[][] column) { 548 Fraction[] data = new Fraction[column.length]; 549 for (int i = 0; i < data.length; ++i) { 550 data[i] = column[i][0]; 551 } 552 return new ArrayFieldVector<Fraction>(data, false); 553 } 554 555 public void testEqualsAndHashCode() { 556 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 557 SparseFieldMatrix<Fraction> m1 = (SparseFieldMatrix<Fraction>) m.copy(); 558 SparseFieldMatrix<Fraction> mt = (SparseFieldMatrix<Fraction>) m.transpose(); 559 assertTrue(m.hashCode() != mt.hashCode()); 560 assertEquals(m.hashCode(), m1.hashCode()); 561 assertEquals(m, m); 562 assertEquals(m, m1); 563 assertFalse(m.equals(null)); 564 assertFalse(m.equals(mt)); 565 assertFalse(m.equals(createSparseMatrix(bigSingular))); 566 } 567 568 /* Disable for now 569 public void testToString() { 570 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 571 assertEquals("SparseFieldMatrix<Fraction>{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}", 572 m.toString()); 573 m = new SparseFieldMatrix<Fraction>(field, 1, 1); 574 assertEquals("SparseFieldMatrix<Fraction>{{0.0}}", m.toString()); 575 } 576 */ 577 578 public void testSetSubMatrix() throws Exception { 579 SparseFieldMatrix<Fraction> m = createSparseMatrix(testData); 580 m.setSubMatrix(detData2, 1, 1); 581 FieldMatrix<Fraction> expected = createSparseMatrix(new Fraction[][] { 582 { new Fraction(1), new Fraction(2), new Fraction(3) }, { new Fraction(2), new Fraction(1), new Fraction(3) }, { new Fraction(1), new Fraction(2), new Fraction(4) } }); 583 assertEquals(expected, m); 584 585 m.setSubMatrix(detData2, 0, 0); 586 expected = createSparseMatrix(new Fraction[][] { 587 { new Fraction(1), new Fraction(3), new Fraction(3) }, { new Fraction(2), new Fraction(4), new Fraction(3) }, { new Fraction(1), new Fraction(2), new Fraction(4) } }); 588 assertEquals(expected, m); 589 590 m.setSubMatrix(testDataPlus2, 0, 0); 591 expected = createSparseMatrix(new Fraction[][] { 592 { 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) } }); 593 assertEquals(expected, m); 594 595 // javadoc example 596 SparseFieldMatrix<Fraction> matrix = 597 createSparseMatrix(new Fraction[][] { 598 { 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(9), new Fraction(0), new Fraction(1), new Fraction(2) } }); 599 matrix.setSubMatrix(new Fraction[][] { { new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(6) } }, 1, 1); 600 expected = createSparseMatrix(new Fraction[][] { 601 { new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) }, { new Fraction(5), new Fraction(3), new Fraction(4), new Fraction(8) }, { new Fraction(9), new Fraction(5), new Fraction(6), new Fraction(2) } }); 602 assertEquals(expected, matrix); 603 604 // dimension overflow 605 try { 606 m.setSubMatrix(testData, 1, 1); 607 fail("expecting MatrixIndexException"); 608 } catch (MatrixIndexException e) { 609 // expected 610 } 611 // dimension underflow 612 try { 613 m.setSubMatrix(testData, -1, 1); 614 fail("expecting MatrixIndexException"); 615 } catch (MatrixIndexException e) { 616 // expected 617 } 618 try { 619 m.setSubMatrix(testData, 1, -1); 620 fail("expecting MatrixIndexException"); 621 } catch (MatrixIndexException e) { 622 // expected 623 } 624 625 // null 626 try { 627 m.setSubMatrix(null, 1, 1); 628 fail("expecting NullPointerException"); 629 } catch (NullPointerException e) { 630 // expected 631 } 632 try { 633 new SparseFieldMatrix<Fraction>(field, 0, 0); 634 fail("expecting IllegalArgumentException"); 635 } catch (IllegalArgumentException e) { 636 // expected 637 } 638 639 // ragged 640 try { 641 m.setSubMatrix(new Fraction[][] { { new Fraction(1) }, { new Fraction(2), new Fraction(3) } }, 0, 0); 642 fail("expecting IllegalArgumentException"); 643 } catch (IllegalArgumentException e) { 644 // expected 645 } 646 647 // empty 648 try { 649 m.setSubMatrix(new Fraction[][] { {} }, 0, 0); 650 fail("expecting IllegalArgumentException"); 651 } catch (IllegalArgumentException e) { 652 // expected 653 } 654 655 } 656 657 // --------------- -----------------Protected methods 658 659 /** verifies that two matrices are close (1-norm) */ 660 protected void assertClose(String msg, FieldMatrix<Fraction> m, FieldMatrix<Fraction> n, 661 double tolerance) { 662 for(int i=0; i < m.getRowDimension(); i++){ 663 for(int j=0; j < m.getColumnDimension(); j++){ 664 assertEquals(msg, m.getEntry(i,j).doubleValue(), n.getEntry(i,j).doubleValue(), tolerance); 665 } 666 667 } 668 } 669 670 /** verifies that two vectors are close (sup norm) */ 671 protected void assertClose(String msg, Fraction[] m, Fraction[] n, 672 double tolerance) { 673 if (m.length != n.length) { 674 fail("vectors not same length"); 675 } 676 for (int i = 0; i < m.length; i++) { 677 assertEquals(msg + " " + i + " elements differ", m[i].doubleValue(), n[i].doubleValue(), 678 tolerance); 679 } 680 } 681 682 private SparseFieldMatrix<Fraction> createSparseMatrix(Fraction[][] data) { 683 SparseFieldMatrix<Fraction> matrix = new SparseFieldMatrix<Fraction>(field, data.length, data[0].length); 684 for (int row = 0; row < data.length; row++) { 685 for (int col = 0; col < data[row].length; col++) { 686 matrix.setEntry(row, col, data[row][col]); 687 } 688 } 689 return matrix; 690 } 691 692 }