sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1528611 - 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-utility/src/main/java/org/apache/sis/internal/u...
Date Wed, 02 Oct 2013 20:10:31 GMT
Author: desruisseaux
Date: Wed Oct  2 20:10:31 2013
New Revision: 1528611

URL: http://svn.apache.org/r1528611
Log:
Added a STRICTFP static final flag for verification purpose only.
First piece of double-double arithmetic in matrix inversion.

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/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/main/java/org/apache/sis/referencing/operation/matrix/Solver.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/SolverTest.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.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=1528611&r1=1528610&r2=1528611&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] Wed Oct  2 20:10:31 2013
@@ -400,22 +400,6 @@ class GeneralMatrix extends MatrixSIS {
     }
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS inverse() throws NoninvertibleMatrixException {
-        return Solver.inverse(this);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException
{
-        throw new UnsupportedOperationException(); // TODO
-    }
-
-    /**
      * Sets this matrix to the product of the given matrices: {@code this = A × B}.
      * The matrix sizes much match - this is not verified unless assertions are enabled.
      */

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=1528611&r1=1528610&r2=1528611&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] Wed Oct  2 20:10:31 2013
@@ -265,27 +265,6 @@ public final class Matrix2 extends Matri
     }
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS inverse() throws NoninvertibleMatrixException {
-        final double det = m00*m11 - m01*m10;
-        if (det == 0) {
-            throw new NoninvertibleMatrixException();
-        }
-        return new Matrix2(m11 / det, -m01 / det,
-                          -m10 / det,  m00 / det);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException
{
-        throw new UnsupportedOperationException(); // TODO
-    }
-
-    /**
      * Returns {@code true} if the specified object is of type {@code Matrix2} and
      * all of the data members are equal to the corresponding data members in this matrix.
      *

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=1528611&r1=1528610&r2=1528611&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] Wed Oct  2 20:10:31 2013
@@ -307,22 +307,6 @@ public final class Matrix3 extends Matri
     }
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS inverse() throws NoninvertibleMatrixException {
-        return Solver.inverse(this);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException
{
-        throw new UnsupportedOperationException(); // TODO
-    }
-
-    /**
      * Returns {@code true} if the specified object is of type {@code Matrix3} and
      * all of the data members are equal to the corresponding data members in this matrix.
      *

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=1528611&r1=1528610&r2=1528611&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] Wed Oct  2 20:10:31 2013
@@ -358,22 +358,6 @@ public final class Matrix4 extends Matri
     }
 
     /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS inverse() throws NoninvertibleMatrixException {
-        return Solver.inverse(this);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException
{
-        throw new UnsupportedOperationException(); // TODO
-    }
-
-    /**
      * Returns {@code true} if the specified object is of type {@code Matrix4} and
      * all of the data members are equal to the corresponding data members in this matrix.
      *

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=1528611&r1=1528610&r2=1528611&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
Wed Oct  2 20:10:31 2013
@@ -230,7 +230,9 @@ public abstract class MatrixSIS implemen
      *         to the number of columns in this matrix.
      * @throws NoninvertibleMatrixException if this matrix is not invertible.
      */
-    public abstract MatrixSIS solve(Matrix matrix) throws MismatchedMatrixSizeException,
NoninvertibleMatrixException;
+    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException
{
+        throw new UnsupportedOperationException(); // TODO
+    }
 
     /**
      * Returns the inverse of this matrix.
@@ -240,7 +242,9 @@ public abstract class MatrixSIS implemen
      *
      * @see java.awt.geom.AffineTransform#createInverse()
      */
-    public abstract MatrixSIS inverse() throws NoninvertibleMatrixException;
+    public MatrixSIS inverse() throws NoninvertibleMatrixException {
+        return Solver.inverse(this);
+    }
 
     /**
      * Compares the given matrices for equality, using the given absolute tolerance threshold.

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Solver.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Solver.java?rev=1528611&r1=1528610&r2=1528611&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Solver.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Solver.java
[UTF-8] Wed Oct  2 20:10:31 2013
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.operation.matrix;
 
 import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.util.ArraysExt;
 
 
@@ -100,7 +101,8 @@ final class Solver implements Matrix {
      * (this is <strong>not</strong> verified by this method).
      */
     static MatrixSIS inverse(final MatrixSIS X) throws NoninvertibleMatrixException {
-        return solve(X, IDENTITY, X.getNumRow());
+        final int size = X.getNumRow();
+        return solve(X, IDENTITY, size, size);
     }
 
     /**
@@ -121,28 +123,34 @@ final class Solver implements Matrix {
      * }
      *
      * @param  X The matrix to invert.
+     * @param  size The value of {@code X.getNumRow()}, {@code X.getNumCol()} and {@code
Y.getNumRow()}.
      * @param  innerSize The value of {@code Y.getNumCol()}.
      * @throws NoninvertibleMatrixException If the {@code X} matrix is singular.
      */
-    static MatrixSIS solve(final MatrixSIS X, final Matrix Y, final int innerSize)
+    static MatrixSIS solve(final MatrixSIS X, final Matrix Y, final int size, final int innerSize)
             throws NoninvertibleMatrixException
     {
-        final int size = X.getNumRow();
         /*
          * Use a "left-looking", dot-product, Crout/Doolittle algorithm.
          */
-        final double[] LU = X.getElements();
+        final int errorLU = size * size;
+        final double[] LU = GeneralMatrix.getExtendedElements(X, size, size);
+        assert errorLU == GeneralMatrix.indexOfErrors(size, size, LU);
         final int[] pivot = new int[size];
         for (int j=0; j<size; j++) {
            pivot[j] = j;
         }
-        final double[] column = new double[size];
+        final double[]  column = new double[size * 2];
+        final DoubleDouble dot = new DoubleDouble();
+        final DoubleDouble sum = new DoubleDouble();
         for (int i=0; i<size; i++) {
             /*
              * Make a copy of the i-th column.
              */
             for (int j=0; j<size; j++) {
-                column[j] = LU[j*size + i];
+                final int k = j*size + i;
+                column[j] = LU[k];
+                column[j + size] = LU[k + errorLU];
             }
             /*
              * Apply previous transformations.
@@ -150,11 +158,16 @@ final class Solver implements Matrix {
             for (int j=0; j<size; j++) {
                 final int rowOffset = j*size;
                 final int kmax = Math.min(j,i);
-                double s = 0.0;
+                sum.clear();
                 for (int k=0; k<kmax; k++) {
-                   s += LU[rowOffset + k] * column[k];
-                }
-                LU[rowOffset + i] = (column[j] -= s);
+                    dot.value = LU[rowOffset + k];
+                    dot.error = LU[rowOffset + k + errorLU];
+                    dot.multiply(column[k], column[k + size]);
+                    sum.add(dot);
+                }
+                sum.add(-column[j], -column[j + size]);
+                LU[rowOffset + i]           = column[j]        = -sum.value;
+                LU[rowOffset + i + errorLU] = column[j + size] = -sum.error;
             }
             /*
              * Find pivot and exchange if necessary.

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=1528611&r1=1528610&r2=1528611&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] Wed Oct  2 20:10:31 2013
@@ -18,6 +18,7 @@ package org.apache.sis.referencing.opera
 
 import java.util.Random;
 import Jama.Matrix;
+import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.DependsOnMethod;
@@ -58,7 +59,7 @@ public abstract strictfp class MatrixTes
      * The matrix elements used in this class varies between 0 and 100,
      * and the {@code Math.ulp(100.0)} value is approximatively 1.4E-14.
      */
-    static final double TOLERANCE = 1E-10;
+    static final double TOLERANCE = DoubleDouble.STRICTFP ? STRICT : 1E-8;
 
     /**
      * Number of random matrices to try in arithmetic operation tests.
@@ -104,9 +105,10 @@ public abstract strictfp class MatrixTes
         final int numCol = actual.getNumCol();
         assertEquals("numRow", expected.getRowDimension(),    numRow);
         assertEquals("numCol", expected.getColumnDimension(), numCol);
+        final String name = actual.getClass().getSimpleName();
         for (int j=0; j<numRow; j++) {
             for (int i=0; i<numCol; i++) {
-                assertEquals(expected.get(j,i), actual.getElement(j,i), tolerance);
+                assertEquals(name, expected.get(j,i), actual.getElement(j,i), tolerance);
             }
         }
     }
@@ -273,7 +275,7 @@ public abstract strictfp class MatrixTes
                 m += e*e;
             }
             m = StrictMath.sqrt(m);
-            assertEquals(1, m, TOLERANCE);
+            assertEquals(1, m, 1E-12);
         }
     }
 

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=1528611&r1=1528610&r2=1528611&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] Wed Oct  2 20:10:31 2013
@@ -80,7 +80,7 @@ public final strictfp class SolverTest e
                 out.println(e); // "Matrix is singular."
                 continue;
             }
-            final MatrixSIS U = Solver.solve(matrix, matrixArg, matrixArg.getNumCol());
+            final MatrixSIS U = Solver.solve(matrix, matrixArg, matrixArg.getNumRow(), matrixArg.getNumCol());
             MatrixTestCase.assertMatrixEquals(jama, U, MatrixTestCase.TOLERANCE);
         }
     }

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1528611&r1=1528610&r2=1528611&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
[UTF-8] Wed Oct  2 20:10:31 2013
@@ -62,6 +62,23 @@ import org.apache.sis.math.MathFunctions
  */
 public final class DoubleDouble extends Number {
     /**
+     * {@code true} for disabling the extended precision. This variable should always be
{@code false},
+     * except for testing purpose. If set to {@code true}, then all double-double arithmetic
operations
+     * are immediately followed by a clearing of {@link DoubleDouble#error}.  The result
should then be
+     * identical to computation performed using the normal {@code double} arithmetic.
+     *
+     * <p>Since this flag is static final, all expressions of the form {@code if (STRICTFP)}
should be
+     * omitted by the compiler from the class files in normal operations.</p>
+     *
+     * <p>Setting this flag to {@code true} causes some JUnit tests to fail. This is
normal. The main
+     * purpose of this flag is to allow {@link org.apache.sis.referencing.operation.matrix.MatrixTestCase}
+     * to perform strict comparisons of matrix operation results with JAMA, which is taken
as the reference
+     * implementation. Since JAMA uses {@code double} arithmetic, SIS needs to disable {@code
double-double}
+     * arithmetic if the results are to be compared for strict equality.</p>
+     */
+    public static final boolean STRICTFP = false;
+
+    /**
      * For cross-version compatibility.
      */
     private static final long serialVersionUID = -7602414219228638550L;
@@ -201,6 +218,7 @@ public final class DoubleDouble extends 
      *         the given value is assumed to be the most accurate available representation.
      */
     public static double errorForWellKnownValue(final double value) {
+        if (STRICTFP) return 0;
         final int i = Arrays.binarySearch(VALUES, Math.abs(value));
         return (i >= 0) ? MathFunctions.xorSign(ERRORS[i], value) : 0;
     }
@@ -219,6 +237,7 @@ public final class DoubleDouble extends 
      */
     final void normalize() {
         error += (value - (value += error));
+        if (STRICTFP) error = 0;
     }
 
     /**
@@ -233,6 +252,7 @@ public final class DoubleDouble extends 
     public void setToQuickSum(final double a, final double b) {
         value = a + b;
         error = b - (value - a);
+        if (STRICTFP) error = 0;
     }
 
     /**
@@ -247,6 +267,7 @@ public final class DoubleDouble extends 
         value = a + b;
         final double v = value - a;
         error = (a - (value - v)) + (b - v);
+        if (STRICTFP) error = 0;
     }
 
     /**
@@ -267,6 +288,7 @@ public final class DoubleDouble extends 
         final double bhi = t - (t - b);
         final double blo = b - bhi;
         error = ((ahi*bhi - value) + ahi*blo + alo*bhi) + alo*blo;
+        if (STRICTFP) error = 0;
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java?rev=1528611&r1=1528610&r2=1528611&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
[UTF-8] Wed Oct  2 20:10:31 2013
@@ -33,6 +33,7 @@ import static java.lang.StrictMath.*;
 
 /**
  * Tests {@link DoubleDouble} using {@link BigDecimal} as the references.
+ * Those tests need {@link DoubleDouble#STRICTFP} to be set to {@code false}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4



Mime
View raw message