You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2013/10/03 23:11:11 UTC
svn commit: r1529004 - in /sis/branches/JDK7/core:
sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/
sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/
sis-referencing/src/test/java/org/apache/sis/test/s...
Author: desruisseaux
Date: Thu Oct 3 21:11:10 2013
New Revision: 1529004
URL: http://svn.apache.org/r1529004
Log:
Fix the seed of random number generators for ensuring stable builds.
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix1Test.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix2Test.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix4Test.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -98,11 +98,10 @@ class GeneralMatrix extends MatrixSIS {
*/
GeneralMatrix(final int numRow, final int numCol, final double[] elements) {
ensureValidSize(numRow, numCol);
- final int length = numRow * numCol;
- ensureLengthMatch(length, elements);
+ ensureLengthMatch(numRow * numCol, elements);
this.numRow = (short) numRow;
this.numCol = (short) numCol;
- this.elements = Arrays.copyOf(elements, length);
+ this.elements = elements.clone();
}
/**
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -241,17 +241,6 @@ public final class Matrix1 extends Matri
* {@inheritDoc}
*/
@Override
- public MatrixSIS inverse() throws NoninvertibleMatrixException {
- if (m00 == 0) {
- throw new NoninvertibleMatrixException();
- }
- return new Matrix1(1 / m00);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException {
final int nc = matrix.getNumCol();
ensureNumRowMatch(SIZE, matrix, nc);
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -16,7 +16,8 @@
*/
package org.apache.sis.referencing.operation.matrix;
-import org.apache.sis.test.DependsOn;
+import java.util.Random;
+import org.junit.Test;
import static org.junit.Assert.*;
@@ -30,17 +31,19 @@ import static org.junit.Assert.*;
* @version 0.4
* @module
*/
-@DependsOn(SolverTest.class)
public final strictfp class GeneralMatrixTest extends MatrixTestCase {
/**
* Number of rows and columns.
*/
- private final int size;
+ private int size;
/**
- * Creates a test with a random size for the square matrix.
+ * Computes a random size for the next matrix to create.
+ *
+ * @param random The random number generator to use.
*/
- public GeneralMatrixTest() {
+ @Override
+ void prepareNewMatrixSize(final Random random) {
size = 5 + random.nextInt(8); // Matrix sizes from 5 to 12 inclusive.
}
@@ -55,4 +58,39 @@ public final strictfp class GeneralMatri
super.validate(matrix);
assertEquals(GeneralMatrix.class, matrix.getClass());
}
+
+ /**
+ * Tests {@link GeneralMatrix#getExtendedElements(Matrix, int, int, boolean)}.
+ * This test verifies that {@code getExtendedElements} can infer default error
+ * terms for some well known values.
+ *
+ * @see Matrix2Test#testGetExtendedElements()
+ */
+ @Test
+ public void testGetExtendedElements() {
+ testGetExtendedElements(new GeneralMatrix(2, 2, new double[] {
+ StrictMath.PI / 180, // Degrees to radians
+ 180 / StrictMath.PI, // Radians to degrees
+ 0.9, // Gradians to degrees
+ 0.1234567})); // Random value with no special meaning.
+ }
+
+ /**
+ * Implementation of {@link #testGetExtendedElements()} shared by {@link Matrix2Test}.
+ */
+ static void testGetExtendedElements(final MatrixSIS matrix) {
+ final double[] elements = GeneralMatrix.getExtendedElements(matrix, Matrix2.SIZE, Matrix2.SIZE, false);
+ assertArrayEquals(new double[] {
+ // Same values than in the above matrix.
+ StrictMath.PI / 180,
+ 180 / StrictMath.PI,
+ 0.9,
+ 0.1234567,
+
+ // Values below this point are error terms copied from DoubleDouble.ERRORS.
+ 2.9486522708701687E-19,
+ -1.9878495670576283E-15,
+ -2.2204460492503132E-17,
+ 0}, elements, STRICT);
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix1Test.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix1Test.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix1Test.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix1Test.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -55,6 +55,7 @@ public final strictfp class Matrix1Test
*/
@Test
public void testConstructor() {
+ initialize(415870088589607716L);
final double[] elements = createRandomPositiveValues(SIZE * SIZE);
final Matrix1 matrix = new Matrix1(
elements[0]);
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix2Test.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix2Test.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix2Test.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix2Test.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -55,6 +55,7 @@ public final strictfp class Matrix2Test
*/
@Test
public void testConstructor() {
+ initialize(-8453835559080304420L);
final double[] elements = createRandomPositiveValues(SIZE * SIZE);
final Matrix2 matrix = new Matrix2(
elements[0],
@@ -64,4 +65,18 @@ public final strictfp class Matrix2Test
validate(matrix);
assertArrayEquals(elements, matrix.getElements(), STRICT);
}
+
+ /**
+ * Tests {@link GeneralMatrix#getExtendedElements(Matrix, int, int, boolean)}.
+ * This test is a copy of {@link GeneralMatrixTest#testGetExtendedElements()},
+ * but on a {@link Matrix2} instance instead of {@link GeneralMatrix}.
+ */
+ @Test
+ public void testGetExtendedElements() {
+ GeneralMatrixTest.testGetExtendedElements(new Matrix2(
+ StrictMath.PI / 180, // Degrees to radians
+ 180 / StrictMath.PI, // Radians to degrees
+ 0.9, // Gradians to degrees
+ 0.1234567)); // Random value with no special meaning.
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -56,6 +56,7 @@ public final strictfp class Matrix3Test
*/
@Test
public void testConstructor() {
+ initialize(-2078758443421995879L);
final double[] elements = createRandomPositiveValues(SIZE * SIZE);
final Matrix3 matrix = new Matrix3(
elements[0],
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix4Test.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix4Test.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix4Test.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix4Test.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -56,6 +56,7 @@ public final strictfp class Matrix4Test
*/
@Test
public void testConstructor() {
+ initialize(-7053945420932915425L);
final double[] elements = createRandomPositiveValues(SIZE * SIZE);
final Matrix4 matrix = new Matrix4(
elements[ 0],
@@ -77,4 +78,49 @@ public final strictfp class Matrix4Test
validate(matrix);
assertArrayEquals(elements, matrix.getElements(), STRICT);
}
+
+ /**
+ * Tests the accuracy of a chain of matrix operations.
+ *
+ * @throws NoninvertibleMatrixException Should never happen.
+ */
+ @Test
+ public void testAccuracy() throws NoninvertibleMatrixException {
+ final double parisMeridian = 2 + (20 + 13.82/60)/60; // Paris meridian: 2°20'13.82"
+ final double toRadians = StrictMath.PI / 180;
+ /*
+ * Gradians to degrees with a Prime Meridian shift
+ * and a random conversion factor for z values.
+ */
+ final Matrix4 step1 = new Matrix4(
+ 0.9, 0, 0, parisMeridian,
+ 0, 0.9, 0, 0,
+ 0, 0, 0.8, 0, // Random conversion factor for z values.
+ 0, 0, 0, 1);
+ /*
+ * Degrees to radians with swapping of (longitude, latitude) axes
+ * and a conversion factor of z values from feet to metres.
+ */
+ final Matrix4 step2 = new Matrix4(
+ 0, toRadians, 0, 0,
+ toRadians, 0, 0, 0,
+ 0, 0, 0.3048, 0,
+ 0, 0, 0, 1);
+ /*
+ * Converse of the above operations.
+ */
+ final MatrixSIS step3 = step2.multiply(step1).inverse();
+ /*
+ * Concatenate everything, which should go back to the identity transform.
+ * We have a slight residu in the longitude translation term because of the
+ * prime meridian shift - we will set this residu to zero for this test.
+ *
+ * Note that the 'isIdentity(0)' test fail if the double-double arithmetic is
+ * disabled, because some scale factors will be 0.9999999999999999 instead of 1.
+ */
+ final MatrixSIS result = step3.multiply(step2).multiply(step1);
+ assertEquals("translateX", 0, result.getElement(0,3), 1E-32);
+ result.setElement(0,3, 0);
+ assertTrue("isIdentity(0)", Matrices.isIdentity(result, 0));
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -18,6 +18,7 @@ package org.apache.sis.referencing.opera
import java.util.Random;
import Jama.Matrix;
+import org.apache.sis.math.Statistics;
import org.apache.sis.internal.util.DoubleDouble;
import org.apache.sis.test.TestCase;
import org.apache.sis.test.TestUtilities;
@@ -49,22 +50,47 @@ import static org.apache.sis.test.Assert
*/
public abstract strictfp class MatrixTestCase extends TestCase {
/**
+ * {@code true} for reusing the same sequences of random numbers in every execution of test cases, or
+ * {@code false} for "truly" random sequences of random numbers. This flag can be set to {@code false}
+ * for testing purpose, but should be set to {@code true} otherwise for avoiding random test failure.
+ * This is needed because we want to set {@link #TOLERANCE} to a small value, but it is very difficult
+ * to guaranteed that a random sequence of numbers will not cause a larger discrepancy.
+ *
+ * <p>Note that this flag is set to {@code false} if double-double arithmetic is disabled because in such
+ * case, the results should be identical to the JAMA results (i.e. equal using a {@link #TOLERANCE} of zero)
+ * for any sequence of numbers.</p>
+ */
+ protected static final boolean DETERMINIST = !DoubleDouble.DISABLED;
+
+ /**
* A constant for any test in this class or a subclass which expect
* a floating point value to be strictly equals to an other value.
*/
static final double STRICT = 0;
/**
- * Tolerance factor for comparisons of floating point numbers.
- * The matrix elements used in this class varies between 0 and 100,
+ * Tolerance factor for comparisons of floating point numbers between SIS and JAMA implementation,
+ * which is {@value}. Note that the matrix element values used in this class vary between 0 and 100,
* and the {@code Math.ulp(100.0)} value is approximatively 1.4E-14.
+ *
+ * {@section How this value is determined}
+ * Experience (by looking at {@link #statistics}) shows that the differences are usually smaller than 1E-12.
+ * However when using non-determinist sequence of random values ({@link #DETERMINIST} sets to {@code false}),
+ * we do have from time-to-time a difference around 1E-9.
+ *
+ * Those differences exist because SIS uses double-double arithmetic, while JAMA uses ordinary double.
+ * To remove that ambiguity, one can temporarily set {@link DoubleDouble#DISABLED} to {@code true},
+ * in which case the SIS results should be strictly identical to the JAMA ones.
+ *
+ * @see SolverTest#TOLERANCE
+ * @see NonSquareMatrixTest#printStatistics()
*/
- static final double TOLERANCE = DoubleDouble.DISABLED ? STRICT : 1E-8;
+ protected static final double TOLERANCE = DoubleDouble.DISABLED ? STRICT : 1E-12;
/**
* Number of random matrices to try in arithmetic operation tests.
*/
- static final int NUMBER_OF_REPETITIONS = 10;
+ static final int NUMBER_OF_REPETITIONS = 100;
/**
* The threshold in matrix determinant for attempting to compute the inverse.
@@ -73,15 +99,45 @@ public abstract strictfp class MatrixTes
private static final double DETERMINANT_THRESHOLD = 0.001;
/**
- * Random number generator, created by {@link #initialize(String, boolean)} when first needed.
+ * Statistics about the different between the JAMA and SIS matrix elements, or {@code null}
+ * if those statistics do not need to be collected. This is used during the test development
+ * phase for tuning the tolerance threshold.
+ *
+ * @see NonSquareMatrixTest#printStatistics()
*/
- final Random random;
+ static final Statistics statistics = verbose ? new Statistics("|SIS - JAMA|") : null;
+
+ /**
+ * Random number generator, created by {@link #initialize(long)} as the first operation of
+ * any test method which will use random numbers. This random number generator will use a
+ * fixed seed if {@link #DETERMINIST} is {@code true}, which is the normal case.
+ */
+ private Random random;
/**
* For subclasses only.
*/
MatrixTestCase() {
- random = TestUtilities.createRandomNumberGenerator();
+ }
+
+ /**
+ * Initializes the random number generator to the given seed. If {@link #DETERMINIST} is {@code false}
+ * (which happen only when performing some more extensive tests), then the given seed will be replaced
+ * by a random one.
+ *
+ * @param seed The initial seed.
+ */
+ final void initialize(final long seed) {
+ random = DETERMINIST ? new Random(seed) : TestUtilities.createRandomNumberGenerator();
+ }
+
+ /**
+ * Computes a random size for the next matrix to create. This method is overridden
+ * only by subclasses that test matrix implementations supporting arbitrary sizes.
+ *
+ * @param random The random number generator to use for computing a random matrix size.
+ */
+ void prepareNewMatrixSize(final Random random) {
}
/** Returns the number of rows of the matrix being tested. */ abstract int getNumRow();
@@ -99,6 +155,10 @@ public abstract strictfp class MatrixTes
/**
* Verifies that the SIS matrix is equals to the JAMA one, up to the given tolerance value.
+ *
+ * @param expected The JAMA matrix used as a reference implementation.
+ * @param actual The SIS matrix to compare to JAMA.
+ * @param tolerance The tolerance threshold, usually either {@link #STRICT} or {@link #TOLERANCE}.
*/
static void assertMatrixEquals(final Matrix expected, final MatrixSIS actual, final double tolerance) {
final int numRow = actual.getNumRow();
@@ -108,7 +168,14 @@ public abstract strictfp class MatrixTes
final String name = actual.getClass().getSimpleName();
for (int j=0; j<numRow; j++) {
for (int i=0; i<numCol; i++) {
- assertEquals(name, expected.get(j,i), actual.getElement(j,i), tolerance);
+ final double e = expected.get(j,i);
+ final double a = actual.getElement(j,i);
+ assertEquals(name, e, a, tolerance);
+ if (tolerance != STRICT && statistics != null) {
+ synchronized (statistics) {
+ statistics.accept(StrictMath.abs(e - a));
+ }
+ }
}
}
}
@@ -136,6 +203,8 @@ public abstract strictfp class MatrixTes
*/
@Test
public void testGetElements() {
+ initialize(3812872376135347328L);
+ prepareNewMatrixSize(random);
final int numRow = getNumRow();
final int numCol = getNumCol();
final double[] elements = createRandomPositiveValues(numRow * numCol);
@@ -157,6 +226,8 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testGetElements")
public void testSetElement() {
+ initialize(-8079924100564483073L);
+ prepareNewMatrixSize(random);
final int numRow = getNumRow();
final int numCol = getNumCol();
final MatrixSIS matrix = Matrices.createZero(numRow, numCol);
@@ -186,6 +257,8 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testSetElement")
public void testIsIdentity() {
+ initialize(6173145457052452823L);
+ prepareNewMatrixSize(random);
final int numRow = getNumRow();
final int numCol = getNumCol();
final MatrixSIS matrix = Matrices.createDiagonal(numRow, numCol);
@@ -215,6 +288,8 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testSetElement")
public void testCloneEquals() {
+ initialize(-4572234104840706847L);
+ prepareNewMatrixSize(random);
final int numRow = getNumRow();
final int numCol = getNumCol();
final double[] elements = createRandomPositiveValues(numRow * numCol);
@@ -243,6 +318,8 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testGetElements")
public void testTranspose() {
+ initialize(585037875560696050L);
+ prepareNewMatrixSize(random);
final int numRow = getNumRow();
final int numCol = getNumCol();
final double[] elements = createRandomPositiveValues(numRow * numCol);
@@ -262,6 +339,8 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testGetElements")
public void testNormalizeColumns() {
+ initialize(1549772118153010333L);
+ prepareNewMatrixSize(random);
final int numRow = getNumRow();
final int numCol = getNumCol();
final double[] elements = createRandomPositiveValues(numRow * numCol);
@@ -285,9 +364,11 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testGetElements")
public void testMultiply() {
- final int numRow = getNumRow();
- final int numCol = getNumCol();
+ initialize(2478887638739725150L);
for (int n=0; n<NUMBER_OF_REPETITIONS; n++) {
+ prepareNewMatrixSize(random);
+ final int numRow = getNumRow();
+ final int numCol = getNumCol();
double[] elements = createRandomPositiveValues(numRow * numCol);
final MatrixSIS matrix = Matrices.create(numRow, numCol, elements);
final Matrix reference = new Matrix(elements, numCol).transpose();
@@ -320,12 +401,14 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testMultiply")
public void testSolve() throws NoninvertibleMatrixException {
- final int numRow = getNumRow();
- final int numCol = getNumCol();
+ initialize(2108474073121762244L);
+ for (int n=0; n<NUMBER_OF_REPETITIONS; n++) {
+ prepareNewMatrixSize(random);
+ final int numRow = getNumRow();
+ final int numCol = getNumCol();
- if (numRow != 1 || numCol != 1) return; // Temporary limitation.
+ if (numRow != 1 || numCol != 1) return; // Temporary limitation.
- for (int n=0; n<NUMBER_OF_REPETITIONS; n++) {
double[] elements = createRandomPositiveValues(numRow * numCol);
final Matrix reference = new Matrix(elements, numCol).transpose();
if (!(reference.det() >= DETERMINANT_THRESHOLD)) {
@@ -362,9 +445,11 @@ public abstract strictfp class MatrixTes
@Test
@DependsOnMethod("testSolve")
public void testInverse() throws NoninvertibleMatrixException {
- final int numRow = getNumRow();
- final int numCol = getNumCol();
+ initialize(-9063921123024549789L);
for (int n=0; n<NUMBER_OF_REPETITIONS; n++) {
+ prepareNewMatrixSize(random);
+ final int numRow = getNumRow();
+ final int numCol = getNumCol();
final double[] elements = createRandomPositiveValues(numRow * numCol);
final Matrix reference = new Matrix(elements, numCol).transpose();
if (!(reference.det() >= DETERMINANT_THRESHOLD)) {
@@ -380,6 +465,8 @@ public abstract strictfp class MatrixTes
*/
@Test
public void testSerialization() {
+ initialize(-3232759118744327281L);
+ prepareNewMatrixSize(random);
final int numRow = getNumRow();
final int numCol = getNumCol();
final MatrixSIS matrix = Matrices.create(numRow, numCol, createRandomPositiveValues(numRow * numCol));
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -16,7 +16,10 @@
*/
package org.apache.sis.referencing.operation.matrix;
+import java.util.Random;
import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestUtilities;
+import org.junit.AfterClass;
import static org.junit.Assert.*;
@@ -25,22 +28,31 @@ import static org.junit.Assert.*;
* Tests the {@link NonSquareMatrix} implementation.
* This class inherits all tests defined in {@link MatrixTestCase}.
*
+ * <p>This class is expected to be the last {@code MatrixTestCase} subclass to be executed,
+ * because it sends the {@link #statistics} to {@link #out}. This condition is ensured if
+ * the tests are executed by {@link org.apache.sis.test.suite.ReferencingTestSuite}.
+ * However it is not a big deal if this condition is broken, as the only consequence
+ * is that reported statistics will be incomplete.</p>
+ *
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
* @version 0.4
* @module
*/
-@DependsOn(GeneralMatrixTest.class)
+@DependsOn(SolverTest.class)
public final strictfp class NonSquareMatrixTest extends MatrixTestCase {
/**
* Number of rows and columns, initialized by {@link #initialize(String, boolean)}.
*/
- private final int numRow, numCol;
+ private int numRow, numCol;
/**
- * Creates a test with a random size for the matrix and ensure that the matrix is not square.
+ * Computes a random size for the next matrix to create.
+ *
+ * @param random The random number generator to use.
*/
- public NonSquareMatrixTest() {
+ @Override
+ void prepareNewMatrixSize(final Random random) {
numRow = 5 + random.nextInt(8); // Matrix sizes from 5 to 12 inclusive.
int n;
do n = 5 + random.nextInt(8);
@@ -67,4 +79,19 @@ public final strictfp class NonSquareMat
@org.junit.Ignore
public void testInverse() throws NoninvertibleMatrixException {
}
+
+ /**
+ * Prints the statistics about the differences between JAMA and SIS matrix elements.
+ * Those statistics will be visible only if {@link #verbose} is {@code true}.
+ */
+ @AfterClass
+ public static void printStatistics() {
+ if (statistics != null) {
+ TestUtilities.printSeparator("Overall statistics on agreement of matrix arithmetic");
+ synchronized (statistics) {
+ out.println(statistics);
+ }
+ TestUtilities.forceFlushOutput();
+ }
+ }
}
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -18,6 +18,7 @@ package org.apache.sis.referencing.opera
import java.util.Random;
import Jama.Matrix;
+import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestUtilities;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -27,13 +28,36 @@ import org.junit.Test;
* Tests the {@link Solver} class using <a href="http://math.nist.gov/javanumerics/jama">JAMA</a>
* as the reference implementation.
*
+ * {@section Cyclic dependency}
+ * There is a cyclic test dependency since {@link GeneralMatrix} needs {@link Solver} for some operations,
+ * and conversely. To be more specific the dependency order is:
+ *
+ * <ol>
+ * <li>Simple {@link GeneralMatrix} methods (construction, get/set elements)</li>
+ * <li>{@link Solver}</li>
+ * <li>More complex {@code GeneralMatrix} methods (matrix inversion, solve)</li>
+ * </ol>
+ *
+ * We test {@code GeneralMatrix} before {@code Solver} since nothing could be done without
+ * the above-cited simple operations anyway.
+ *
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
* @version 0.4
* @module
*/
+@DependsOn(GeneralMatrixTest.class) // See class javadoc
public final strictfp class SolverTest extends TestCase {
/**
+ * The tolerance threshold for this test case, which is {@value}. This value needs to be higher then the
+ * {@link MatrixTestCase#TOLERANCE} one because of the increased complexity of {@link Solver} operations.
+ *
+ * @see MatrixTestCase#TOLERANCE
+ * @see NonSquareMatrixTest#printStatistics()
+ */
+ protected static final double TOLERANCE = 100 * MatrixTestCase.TOLERANCE;
+
+ /**
* The matrix to test.
*/
private MatrixSIS matrix;
@@ -66,7 +90,12 @@ public final strictfp class SolverTest e
*/
@Test
public void testSolve() throws NoninvertibleMatrixException {
- final Random random = TestUtilities.createRandomNumberGenerator();
+ final Random random;
+ if (MatrixTestCase.DETERMINIST) {
+ random = new Random(7671901444622173417L);
+ } else {
+ random = TestUtilities.createRandomNumberGenerator();
+ }
for (int k=0; k<MatrixTestCase.NUMBER_OF_REPETITIONS; k++) {
final int size = random.nextInt(16) + 1;
createMatrices(size, random.nextInt(16) + 1, random);
@@ -81,7 +110,7 @@ public final strictfp class SolverTest e
continue;
}
final MatrixSIS U = Solver.solve(matrix, matrixArg, matrixArg.getNumRow(), matrixArg.getNumCol());
- MatrixTestCase.assertMatrixEquals(jama, U, MatrixTestCase.TOLERANCE);
+ MatrixTestCase.assertMatrixEquals(jama, U, TOLERANCE);
}
}
}
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -31,13 +31,13 @@ import org.junit.BeforeClass;
*/
@Suite.SuiteClasses({
// Test matrix first because they may be used in about every SIS corners.
+ org.apache.sis.referencing.operation.matrix.GeneralMatrixTest.class,
org.apache.sis.referencing.operation.matrix.SolverTest.class,
org.apache.sis.referencing.operation.matrix.Matrix1Test.class,
org.apache.sis.referencing.operation.matrix.Matrix2Test.class,
org.apache.sis.referencing.operation.matrix.Matrix3Test.class,
org.apache.sis.referencing.operation.matrix.Matrix4Test.class,
- org.apache.sis.referencing.operation.matrix.GeneralMatrixTest.class,
- org.apache.sis.referencing.operation.matrix.NonSquareMatrixTest.class,
+ org.apache.sis.referencing.operation.matrix.NonSquareMatrixTest.class, // Expected to be last MatrixTestCase - see javadoc.
org.apache.sis.referencing.operation.matrix.MatricesTest.class,
org.apache.sis.referencing.operation.matrix.AffineTransforms2DTest.class,
Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java?rev=1529004&r1=1529003&r2=1529004&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java [UTF-8] Thu Oct 3 21:11:10 2013
@@ -44,7 +44,7 @@ import static org.junit.Assert.*;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-3.16)
- * @version 0.3
+ * @version 0.4
* @module
*/
public final strictfp class TestUtilities extends Static {
@@ -90,6 +90,17 @@ public final strictfp class TestUtilitie
}
/**
+ * Prints and clear the current content of {@link TestCase#out}, regardless of whether
+ * {@link TestCase#verbose} is {@code true} or {@code false}. This method should rarely
+ * be needed.
+ *
+ * @since 0.4
+ */
+ public static void forceFlushOutput() {
+ TestCase.flushOutput();
+ }
+
+ /**
* If verbose output are enabled, prints the given title to {@link TestCase#out} in a box.
* This method is invoked for writing a clear visual separator between the verbose output
* of different test cases. This method does nothing if verbose output is not enabled,