sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1523008 - in /sis/branches/JDK7/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/matrix/ test/java/org/apache/sis/referencing/operation/matrix/
Date Fri, 13 Sep 2013 16:55:37 GMT
Author: desruisseaux
Date: Fri Sep 13 16:55:36 2013
New Revision: 1523008

URL: http://svn.apache.org/r1523008
Log:
Added a 'solve' abstract method (not yet implemented) and test cases.
Also modified the test case for running the arithmetic tests more than once with different
random matrices.

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/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.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=1523008&r1=1523007&r2=1523008&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] Fri Sep 13 16:55:36 2013
@@ -285,6 +285,14 @@ class GeneralMatrix extends MatrixSIS {
      * {@inheritDoc}
      */
     @Override
+    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, SingularMatrixException
{
+        throw new UnsupportedOperationException(); // TODO
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public final MatrixSIS multiply(final Matrix matrix) {
         final int numRow = this.numRow; // Protection against accidental changes.
         final int numCol = this.numCol;

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=1523008&r1=1523007&r2=1523008&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] Fri Sep 13 16:55:36 2013
@@ -236,8 +236,32 @@ public final class Matrix1 extends Matri
      * {@inheritDoc}
      */
     @Override
+    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, SingularMatrixException
{
+        final int nc = matrix.getNumCol();
+        ensureNumRowMatch(SIZE, matrix, nc);
+        if (m00 == 0) {
+            throw new SingularMatrixException();
+        }
+        if (nc != SIZE) {
+            final NonSquareMatrix m = new NonSquareMatrix(SIZE, nc, false);
+            for (int i=0; i<nc; i++) {
+                m.elements[i] = matrix.getElement(0, i) / m00;
+            }
+            return m;
+        }
+        return new Matrix1(matrix.getElement(0,0) / m00);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public MatrixSIS multiply(final Matrix matrix) {
-        ensureSizeMatch(SIZE, matrix);
+        final int nc = matrix.getNumCol();
+        ensureNumRowMatch(SIZE, matrix, nc);
+        if (nc != SIZE) {
+            return new NonSquareMatrix(this, matrix);
+        }
         return new Matrix1(m00 * matrix.getElement(0,0));
     }
 

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java?rev=1523008&r1=1523007&r2=1523008&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
[UTF-8] Fri Sep 13 16:55:36 2013
@@ -265,6 +265,14 @@ public final class Matrix2 extends Matri
      * {@inheritDoc}
      */
     @Override
+    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, SingularMatrixException
{
+        throw new UnsupportedOperationException(); // TODO
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public MatrixSIS multiply(final Matrix matrix) {
         final int nc = matrix.getNumCol();
         ensureNumRowMatch(SIZE, matrix, nc);

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java?rev=1523008&r1=1523007&r2=1523008&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
[UTF-8] Fri Sep 13 16:55:36 2013
@@ -303,6 +303,14 @@ public final class Matrix3 extends Matri
      * {@inheritDoc}
      */
     @Override
+    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, SingularMatrixException
{
+        throw new UnsupportedOperationException(); // TODO
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public MatrixSIS multiply(final Matrix matrix) {
         final int nc = matrix.getNumCol();
         ensureNumRowMatch(SIZE, matrix, nc);

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java?rev=1523008&r1=1523007&r2=1523008&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
[UTF-8] Fri Sep 13 16:55:36 2013
@@ -354,6 +354,14 @@ public final class Matrix4 extends Matri
      * {@inheritDoc}
      */
     @Override
+    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, SingularMatrixException
{
+        throw new UnsupportedOperationException(); // TODO
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public MatrixSIS multiply(final Matrix matrix) {
         final int nc = matrix.getNumCol();
         ensureNumRowMatch(SIZE, matrix, nc);

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1523008&r1=1523007&r2=1523008&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
(original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
Fri Sep 13 16:55:36 2013
@@ -189,6 +189,19 @@ public abstract class MatrixSIS implemen
     public abstract MatrixSIS multiply(Matrix matrix) throws MismatchedMatrixSizeException;
 
     /**
+     * Returns the value of <var>U</var> which solves {@code this} × <var>U</var>
= {@code matrix}.
+     * This is equivalent to first computing the inverse of {@code this}, then multiplying
the result
+     * by the given matrix.
+     *
+     * @param  matrix The matrix to solve.
+     * @return The <var>U</var> matrix that satisfies {@code this} × <var>U</var>
= {@code matrix}.
+     * @throws MismatchedMatrixSizeException if the number of rows in the given matrix is
not equals
+     *         to the number of columns in this matrix.
+     * @throws SingularMatrixException if this matrix is not invertible.
+     */
+    public abstract MatrixSIS solve(Matrix matrix) throws MismatchedMatrixSizeException,
SingularMatrixException;
+
+    /**
      * Returns the inverse of this matrix.
      *
      * @return The inverse of this matrix.

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=1523008&r1=1523007&r2=1523008&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] Fri Sep 13 16:55:36 2013
@@ -61,6 +61,17 @@ public abstract strictfp class MatrixTes
     static final double TOLERANCE = 1E-10;
 
     /**
+     * Number of random matrices to try in arithmetic operation tests.
+     */
+    private static final int NUM_TRIES = 10;
+
+    /**
+     * The threshold in matrix determinant for attempting to compute the inverse.
+     * Matrix with a determinant of 0 are not invertible, but we keep a margin for safety.
+     */
+    private static final double DETERMINANT_THRESHOLD = 0.001;
+
+    /**
      * Random number generator, created by {@link #initialize(String, boolean)} when first
needed.
      */
     final Random random;
@@ -267,62 +278,101 @@ public abstract strictfp class MatrixTes
     }
 
     /**
-     * Tests {@link MatrixSIS#multiply(Matrix)} with a matrix argument of size {@code numCol}
× {@code numRow}
-     * (i.e. the shape of a transposed matrix).
+     * Tests {@link MatrixSIS#multiply(Matrix)}.
      */
     @Test
     @DependsOnMethod("testGetElements")
-    public void testMultiplyByMatrix() {
+    public void testMultiply() {
         final int numRow = getNumRow();
         final int numCol = getNumCol();
-        final double[] elements = createRandomPositiveValues(numRow * numCol);
-        final MatrixSIS matrix = Matrices.create(numRow, numCol, elements);
-        final Matrix reference = new Matrix(elements, numCol).transpose();
-        /*
-         * Computes new random value for the argument. We mix positive and negative values,
-         * but with more positive values than negative ones in order to reduce the chances
-         * to have a product of zero for an element.
-         */
-        for (int k=0; k<elements.length; k++) {
-            elements[k] = 8 - random.nextDouble() * 10;
+        for (int n=0; n<NUM_TRIES; n++) {
+            double[] elements = createRandomPositiveValues(numRow * numCol);
+            final MatrixSIS matrix = Matrices.create(numRow, numCol, elements);
+            final Matrix reference = new Matrix(elements, numCol).transpose();
+            /*
+             * Computes new random value for the argument. We mix positive and negative values,
+             * but with more positive values than negative ones in order to reduce the chances
+             * to have a product of zero for an element.
+             */
+            final int nx = random.nextInt(8) + 1;
+            elements = new double[numCol * nx];
+            for (int k=0; k<elements.length; k++) {
+                elements[k] = 8 - random.nextDouble() * 10;
+            }
+            final Matrix referenceArg = new Matrix(elements, nx).transpose();
+            final MatrixSIS matrixArg = Matrices.create(numCol, nx, elements);
+            /*
+             * Performs the multiplication and compare.
+             */
+            final Matrix referenceResult = reference.times(referenceArg);
+            final MatrixSIS matrixResult = matrix.multiply(matrixArg);
+            assertMatrixEquals(referenceResult, matrixResult, TOLERANCE);
         }
-        final MatrixSIS matrixArg = Matrices.create(numCol, numRow, elements);
-        final Matrix referenceArg = new Matrix(elements, numRow).transpose();
-        /*
-         * Performs the multiplication and compare.
-         */
-        final MatrixSIS matrixResult = matrix.multiply(matrixArg);
-        final Matrix referenceResult = reference.times(referenceArg);
-        assertMatrixEquals(referenceResult, matrixResult, TOLERANCE);
     }
 
     /**
-     * Tests {@link MatrixSIS#multiply(Matrix)} with a matrix argument of size {@code numCol}
× 1.
+     * Tests {@link MatrixSIS#solve(Matrix)}.
+     *
+     * @throws SingularMatrixException Should never happen.
      */
     @Test
-    @DependsOnMethod("testMultiplyByMatrix")
-    public void testMultiplyByVector() {
+    @DependsOnMethod("testMultiply")
+    public void testSolve() throws SingularMatrixException {
         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();
-        /*
-         * Computes new random value for the argument. We mix positive and negative values,
-         * but with more positive values than negative ones in order to reduce the chances
-         * to have a product of zero for an element.
-         */
-        elements = new double[numCol];
-        for (int k=0; k<numCol; k++) {
-            elements[k] = 8 - random.nextDouble() * 10;
+
+        org.junit.Assume.assumeTrue(numRow == 1 && numCol == 1); // Temporary limitation.
+
+        for (int n=0; n<NUM_TRIES; n++) {
+            double[] elements = createRandomPositiveValues(numRow * numCol);
+            final Matrix reference = new Matrix(elements, numCol).transpose();
+            if (!(reference.det() >= DETERMINANT_THRESHOLD)) {
+                continue; // To close to a singular matrix - search an other one.
+            }
+            final MatrixSIS matrix = Matrices.create(numRow, numCol, elements);
+            /*
+             * Computes new random value for the argument. We mix positive and negative values,
+             * but with more positive values than negative ones in order to reduce the chances
+             * to have a product of zero for an element.
+             */
+            final int nx = random.nextInt(8) + 1;
+            elements = new double[numCol * nx];
+            for (int k=0; k<elements.length; k++) {
+                elements[k] = 8 - random.nextDouble() * 10;
+            }
+            final Matrix referenceArg = new Matrix(elements, nx).transpose();
+            final MatrixSIS matrixArg = Matrices.create(numCol, nx, elements);
+            /*
+             * Performs the operation and compare.
+             */
+            final Matrix referenceResult = reference.solve(referenceArg);
+            final MatrixSIS matrixResult = matrix.solve(matrixArg);
+            assertMatrixEquals(referenceResult, matrixResult, TOLERANCE);
+        }
+    }
+
+    /**
+     * Tests {@link MatrixSIS#inverse()}.
+     * SIS implements the {@code inverse} operation as a special case of the {@code solve}
operation.
+     *
+     * @throws SingularMatrixException Should never happen.
+     */
+    @Test
+    @DependsOnMethod("testSolve")
+    public void testInverse() throws SingularMatrixException {
+        final int numRow = getNumRow();
+        final int numCol = getNumCol();
+
+        org.junit.Assume.assumeTrue(numRow == 1 && numCol == 1); // Temporary limitation.
+
+        for (int n=0; n<NUM_TRIES; n++) {
+            final double[] elements = createRandomPositiveValues(numRow * numCol);
+            final Matrix reference = new Matrix(elements, numCol).transpose();
+            if (!(reference.det() >= DETERMINANT_THRESHOLD)) {
+                continue; // To close to a singular matrix - search an other one.
+            }
+            final MatrixSIS matrix = Matrices.create(numRow, numCol, elements);
+            assertMatrixEquals(reference.inverse(), matrix.inverse(), TOLERANCE);
         }
-        final MatrixSIS matrixArg = Matrices.create(numCol, 1, elements);
-        final Matrix referenceArg = new Matrix(elements, numCol);
-        /*
-         * Performs the multiplication and compare.
-         */
-        final MatrixSIS matrixResult = matrix.multiply(matrixArg);
-        final Matrix referenceResult = reference.times(referenceArg);
-        assertMatrixEquals(referenceResult, matrixResult, TOLERANCE);
     }
 }



Mime
View raw message