sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1529972 - 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 Mon, 07 Oct 2013 15:25:29 GMT
Author: desruisseaux
Date: Mon Oct  7 15:25:28 2013
New Revision: 1529972

URL: http://svn.apache.org/r1529972
Log:
Support for NonSquareMatrix.solve(Matrix), and preserve DoubleDouble.error terms in NonSquareMatrix.inverse().
Added documentation and a few more tests.

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/Matrices.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/NonSquareMatrix.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/MatricesTest.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/NonSquareMatrixTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.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=1529972&r1=1529971&r2=1529972&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] Mon Oct  7 15:25:28 2013
@@ -169,7 +169,7 @@ class GeneralMatrix extends MatrixSIS {
      * intend was to specify the {@link Math#PI} value, in which case this method will infer
that we would
      * need to add 1.2246467991473532E-16 in order to get a value closer to π.
      */
-    private static void inferErrors(final double[] elements) {
+    static void inferErrors(final double[] elements) {
         final int length = elements.length / 2;
         for (int i=length; i<elements.length; i++) {
             elements[i] = DoubleDouble.errorForWellKnownValue(elements[i - length]);

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1529972&r1=1529971&r2=1529972&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
[UTF-8] Mon Oct  7 15:25:28 2013
@@ -903,6 +903,7 @@ public final class Matrices extends Stat
                         // NaN or Infinity.
                         element = element.replace("Infinity", "∞");
                         width = spacing + element.length();
+                        widthBeforeFraction[i] = Math.max(widthBeforeFraction[i], width);
                     }
                 }
                 columnWidth[i] = Math.max(columnWidth[i], width);

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=1529972&r1=1529971&r2=1529972&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
Mon Oct  7 15:25:28 2013
@@ -250,7 +250,7 @@ public abstract class MatrixSIS implemen
      * @see java.awt.geom.AffineTransform#createInverse()
      */
     public MatrixSIS inverse() throws NoninvertibleMatrixException {
-        return Solver.inverse(this);
+        return Solver.inverse(this, true);
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java?rev=1529972&r1=1529971&r2=1529972&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
[UTF-8] Mon Oct  7 15:25:28 2013
@@ -106,16 +106,56 @@ final class NonSquareMatrix extends Gene
     /**
      * {@inheritDoc}
      *
-     * <p>This method performs a special check for non-square matrix in an attempt
to invert them anyway.
-     * This is possible only if some columns or rows contain contain only 0 elements.</p>
+     * <p>This method delegates the work to {@code inverse().multiply(matrix)} in order
to leverage
+     * the special handling done by {@code inverse()} for non-square matrices.</p>
+     */
+    @Override
+    public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException
{
+        MatrixSIS result = inverse();
+        if (!matrix.isIdentity()) {
+            result = result.multiply(matrix);
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This method performs a special check for non-square matrices in an attempt
to invert them anyway.
+     * If this matrix has more columns than rows, then this method can invert that matrix
if and only if
+     * some columns contain only 0 elements. In such case, the dimensions corresponding to
those columns are
+     * considered independent of all other dimensions. This happen typically with the dimension
of <var>z</var>
+     * and <var>t</var> ordinate values.</p>
+     *
+     * <p><b>Example:</b> in a conversion from (x₁,y₁,z,t) to (x₂,y₂),
if the (x,y) dimensions are independent
+     * of z and t dimensions, then we do not need those (z,t) dimensions for calculating
the inverse of (x₁,y₁)
+     * to (x₂,y₂). We can omit the (z,t) dimensions in order to have a square matrix,
perform the inversion,
+     * then insert NaN in place of the omitted dimensions. In the matrix below, we can see
that (x,y) are
+     * independent of (z,t) because the 3th and 4th columns contains only 0 elements:</p>
+     *
+     * {@preformat math
+     *   ┌               ┐ -1        ┌                  ┐
+     *   │ 2  0  0  0  8 │           │ 0.5  0     -4.00 │
+     *   │ 0  4  0  0  5 │     =     │ 0    0.25  -1.25 │
+     *   │ 0  0  0  0  1 │           │ 0    0       NaN │
+     *   └               ┘           │ 0    0       NaN │
+     *                               │ 0    0      1    │
+     *                               └                  ┘
+     * }
+     *
+     * There is an issue about whether the full row shall contains NaN, or only the last
element (the translation
+     * term) as in the above example.  The current implementation inserts a NaN value in
the translation term and
+     * sets all other values to 0 on the assumption that if (x₂,y₂) do not depend on
(z,t), then conversely (z,t)
+     * do not depend on (x₂,y₂) neither.
      */
     @Override
     public MatrixSIS inverse() throws NoninvertibleMatrixException {
         final int numRow = this.numRow; // Protection against accidental changes.
         final int numCol = this.numCol;
         if (numRow < numCol) {
+            final int length = numRow * numCol;
             /*
-             * Target points have fewer ordinates than source point. If a column contains
only zero values,
+             * Target points have fewer ordinates than source points. If a column contains
only zero values,
              * then this means that the ordinate at the corresponding column is simply deleted.
We can omit
              * that column. We check the last columns before the first columns on the assumption
that last
              * dimensions are more likely to be independant dimensions like time.
@@ -123,60 +163,91 @@ final class NonSquareMatrix extends Gene
             int oi = numCol - numRow;
             final int[] omitted = new int[oi];
 skipColumn: for (int i=numCol; --i>=0;) {
-                for (int j=numRow; --j>=0;) {
-                    if (getElement(j, i) != 0) {
+                for (int j=length + i; (j -= numCol) >= 0;) {
+                    if (elements[j] != 0) {
                         continue skipColumn;
                     }
                 }
-                // Found a column which contains only 0 elements.
-                omitted[--oi] = i;
+                omitted[--oi] = i; // Found a column which contains only 0 elements.
                 if (oi == 0) {
-                    break; // Found enough columns to skip.
-                }
-            }
-            if (oi == 0) {
-                /*
-                 * Create a square matrix omitting some or all columns containing only 0
elements, and invert
-                 * that matrix. Finally, create a new matrix with new rows added for the
omitted ordinates.
-                 */
-                MatrixSIS squareMatrix = new GeneralMatrix(numRow, numRow, false, 2);
-                for (int k=0,i=0; i<numCol; i++) {
-                    if (oi != omitted.length && i == omitted[oi]) {
-                        oi++;
-                    } else {
-                        for (int j=numRow; --j>=0;) {
-                            squareMatrix.setElement(j, k, getElement(j, i));
-                        }
-                        k++;
+                    /*
+                     * Found enough columns containing only zero elements. Create a square
matrix omitting those
+                     * columns, and invert that matrix. Note that we also need to either
copy the error terms,
+                     * or to infer them.
+                     */
+                    GeneralMatrix squareMatrix = new GeneralMatrix(numRow, numRow, false,
2);
+                    int j=0;
+                    for (i=0; i<numCol; i++) {
+                        if (oi != omitted.length && i == omitted[oi]) oi++;
+                        else copyColumnTo(i, squareMatrix, j++); // Copy only if not skipped.
                     }
-                }
-                squareMatrix = squareMatrix.inverse();
-                /*
-                 * From this point, the meaning of 'numCol' and 'numRow' are interchanged.
-                 */
-                final MatrixSIS inverse = new NonSquareMatrix(numCol, numRow, false, 2);
-                oi = 0;
-                for (int k=0,j=0; j<numCol; j++) {
-                    if (oi != omitted.length && j == omitted[oi]) {
-                        if (j < numRow) {
-                            inverse.setElement(j, j, 0);
-                        }
-                        inverse.setElement(j, numRow-1, Double.NaN);
-                        oi++;
-                    } else {
-                        for (int i=numRow; --i>=0;) {
-                            inverse.setElement(j, i, squareMatrix.getElement(k, i));
+                    // If the source matrix does not use double-double arithmetic, infer
the error terms.
+                    if (indexOfErrors(numRow, numCol, elements) == 0) {
+                        inferErrors(squareMatrix.elements);
+                    }
+                    squareMatrix = (GeneralMatrix) Solver.inverse(squareMatrix, false);
+                    /*
+                     * Create a new matrix with new rows added for the omitted ordinates.
+                     * From this point, the meaning of 'numCol' and 'numRow' are interchanged.
+                     */
+                    final NonSquareMatrix inverse = new NonSquareMatrix(numCol, numRow, false,
2);
+                    for (oi=0, j=0, i=0; i<numCol; i++) {
+                        if (oi != omitted.length && i == omitted[oi]) {
+                            inverse.setElement(i, numRow-1, Double.NaN);
+                            oi++;
+                        } else {
+                            inverse.copyRowFrom(squareMatrix, j++, i);
                         }
-                        k++;
                     }
+                    return inverse;
                 }
-                return inverse;
             }
         }
+        /*
+         * If we reach this point, we have not been able to replace the non-square matrix
by a square one.
+         * Delegate to the super-class method as a matter of principle, but that method is
expected to fail.
+         */
         return super.inverse();
     }
 
     /**
+     * Copies a column from this matrix to the given matrix, including the double-double
arithmetic error terms
+     * if any. The given matrix must have the same number of rows than this matrix, and must
have enough room for
+     * error terms (this is not verified).
+     *
+     * @param srcIndex  Index of the column to copy from this matrix.
+     * @param target    The matrix where to copy the column.
+     * @param dstIndex  Index of the column where to copy in the target matrix.
+     */
+    private void copyColumnTo(int srcIndex, final GeneralMatrix target, int dstIndex) {
+        assert target.numRow == numRow;
+        while (srcIndex < elements.length) {
+            target.elements[dstIndex] = elements[srcIndex];
+            srcIndex += this.numCol;
+            dstIndex += target.numCol;
+        }
+    }
+
+    /**
+     * Copies a row from the given matrix to this matrix, including the double-double arithmetic
error terms.
+     * The two matrix must have the same number of columns, and both of them must have room
for the error terms
+     * (this is not verified).
+     *
+     * @param source   The matrix from which to copy a row.
+     * @param srcIndex Index of the row to copy from the source matrix.
+     * @param dstIndex Index of the row where to copy in this matrix.
+     */
+    private void copyRowFrom(final GeneralMatrix source, int srcIndex, int dstIndex) {
+        final int numCol = this.numCol;
+        assert numCol == source.numCol;
+        srcIndex *= numCol;
+        dstIndex *= numCol;
+        System.arraycopy(source.elements, srcIndex, elements, dstIndex, numCol);  // Copy
main values
+        System.arraycopy(source.elements, srcIndex + numCol * source.numRow,      // Copy
error terms
+                                elements, dstIndex + numCol * numRow, numCol);
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override

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=1529972&r1=1529971&r2=1529972&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] Mon Oct  7 15:25:28 2013
@@ -108,15 +108,17 @@ final class Solver implements Matrix {
     /**
      * Computes the inverse of the given matrix. This method shall be invoked only for square
matrices.
      *
+     * @param  X        The matrix to invert, which must be square.
+     * @param  noChange If {@code true}, do not allow modifications to the {@code X} matrix.
      * @throws NoninvertibleMatrixException If the {@code X} matrix is not square or singular.
      */
-    static MatrixSIS inverse(final MatrixSIS X) throws NoninvertibleMatrixException {
+    static MatrixSIS inverse(final MatrixSIS X, final boolean noChange) throws NoninvertibleMatrixException
{
         final int size = X.getNumRow();
         final int numCol = X.getNumCol();
         if (numCol != size) {
             throw new NoninvertibleMatrixException(Errors.format(Errors.Keys.NonInvertibleMatrix_2,
size, numCol));
         }
-        return solve(X, IDENTITY, null, size, size);
+        return solve(X, IDENTITY, null, size, size, noChange);
     }
 
     /**
@@ -142,7 +144,7 @@ final class Solver implements Matrix {
                 eltY = null; // Matrix does not contains error terms.
             }
         }
-        return solve(X, Y, eltY, size, innerSize);
+        return solve(X, Y, eltY, size, innerSize, true);
     }
 
     /**
@@ -166,19 +168,20 @@ final class Solver implements Matrix {
      *     }
      * }
      *
-     * @param  X         The matrix to invert.
+     * @param  X         The matrix to invert, which must be square.
      * @param  Y         The desired result of {@code X} × <var>U</var>.
      * @param  eltY      Elements and error terms of the {@code Y} matrix, or {@code null}
if not available.
      * @param  size      The value of {@code X.getNumRow()}, {@code X.getNumCol()} and {@code
Y.getNumRow()}.
      * @param  innerSize The value of {@code Y.getNumCol()}.
+     * @param  noChange  If {@code true}, do not allow modifications to the {@code X} matrix.
      * @throws NoninvertibleMatrixException If the {@code X} matrix is not square or singular.
      */
     private static MatrixSIS solve(final MatrixSIS X, final Matrix Y, final double[] eltY,
-            final int size, final int innerSize) throws NoninvertibleMatrixException
+            final int size, final int innerSize, final boolean noChange) throws NoninvertibleMatrixException
     {
         assert (X.getNumRow() == size && X.getNumCol() == size) : size;
         assert (Y.getNumRow() == size && Y.getNumCol() == innerSize) || (Y instanceof
Solver);
-        final double[] LU = GeneralMatrix.getExtendedElements(X, size, size, true);
+        final double[] LU = GeneralMatrix.getExtendedElements(X, size, size, noChange);
         final int lastRowOrColumn = size - 1;
         /*
          * indexOfNaN array will be created only if at least one NaN value is found, and
those NaN meet

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java?rev=1529972&r1=1529971&r2=1529972&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
[UTF-8] Mon Oct  7 15:25:28 2013
@@ -27,6 +27,7 @@ import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
+import static java.lang.Double.NaN;
 import static org.apache.sis.test.Assert.*;
 import static org.opengis.referencing.cs.AxisDirection.*;
 
@@ -338,14 +339,21 @@ public final strictfp class MatricesTest
                 "│ 0  0  1  0 │\n" +
                 "│ 0  0  0  1 │\n" +
                 "└            ┘\n", new Matrix4().toString());
+
+        assertMultilinesEquals(
+                "┌               ┐\n" +
+                "│   1    0    0 │\n" +
+                "│ NaN  NaN  NaN │\n" +
+                "│   0    0    1 │\n" +
+                "└               ┘\n", new Matrix3(1, 0, 0, NaN, NaN, NaN, 0, 0, 1).toString());
         /*
          * Mix of values with different precision, ±0, ±1, NaN and infinities.
          */
         final MatrixSIS matrix = Matrices.create(4, 5, new double[] {
-            39.5193682106975150,  -68.5200,     -1.0,  1,  98,
-           -66.0358637477182200,   Double.NaN,  43.0,  0,  Double.NEGATIVE_INFINITY,
-             2.0741018968776337,   83.7260,     -0.0,  1,  -3,
-            91.8796187759200600,  -18.2674,     24.5,  0,  36.5
+            39.5193682106975150,  -68.5200,  -1.0,  1,  98,
+           -66.0358637477182200,       NaN,  43.0,  0,  Double.NEGATIVE_INFINITY,
+             2.0741018968776337,   83.7260,  -0.0,  1,  -3,
+            91.8796187759200600,  -18.2674,  24.5,  0,  36.5
         });
         assertMultilinesEquals(
                 "┌                                               ┐\n" +

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=1529972&r1=1529971&r2=1529972&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] Mon Oct  7 15:25:28 2013
@@ -71,4 +71,33 @@ public final strictfp class Matrix3Test 
         validate(matrix);
         assertArrayEquals(elements, matrix.getElements(), STRICT);
     }
+
+    /**
+     * Verifies our claim that {@code A.solve(B)} is equivalent to {@code A.inverse().multiply(B)}.
+     * This claim is documented in {@link MatrixSIS#solve(Matrix)} javadoc.
+     *
+     * @throws NoninvertibleMatrixException Should not happen.
+     */
+    @Test
+    public void testSolveEquivalence() throws NoninvertibleMatrixException {
+        final Matrix3 A = new Matrix3(
+                0.5,  0,    0,
+                0,    0.5,  0,
+                0,    0,    1);
+
+        final Matrix3 B = new Matrix3(
+                0,  3,  0,
+                3,  0,  0,
+                0,  0,  1);
+
+        // Verify the result of A.inverse().multiply(B) as a matter of principle.
+        final double[] expected = A.inverse().multiply(B).getElements();
+        assertArrayEquals(new double[] {
+                0,  6,  0,
+                6,  0,  0,
+                0,  0,  1}, expected, TOLERANCE);
+
+        // Now the actual test.
+        assertMatrixEquals(expected, SIZE, SIZE, A.solve(B), TOLERANCE);
+    }
 }

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=1529972&r1=1529971&r2=1529972&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] Mon Oct  7 15:25:28 2013
@@ -93,10 +93,10 @@ public final strictfp class Matrix4Test 
          * 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);
+                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.

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=1529972&r1=1529971&r2=1529972&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] Mon Oct  7 15:25:28 2013
@@ -74,35 +74,54 @@ public final strictfp class NonSquareMat
     }
 
     /**
-     * Tests {@link #inverse()} with a non-square matrix.
+     * Tests {@link NonSquareMatrix#inverse()} with a non-square matrix.
      */
     @Override
     public void testInverse() throws NoninvertibleMatrixException {
+        testDimensionReduction(null, 1, 0);
+    }
+
+    /**
+     * Tests {@link NonSquareMatrix#solve(Matrix)} with a non-square matrix.
+     */
+    @Override
+    public void testSolve() throws NoninvertibleMatrixException {
+        final Matrix3 Y = new Matrix3(
+                2, 0, 0,
+                0, 2, 0,
+                0, 0, 1);
+        testDimensionReduction(Y, 2, NaN);
+    }
+
+    /**
+     * Tests {@link NonSquareMatrix#inverse()} or {@link NonSquareMatrix#solve(Matrix)} with
a conversion
+     * matrix having more source dimensions (columns) than target dimensions (rows).
+     *
+     * @param  Y    The matrix to give to {@code solve(Y)}, {@code null} for testing {@code
inverse()}.
+     * @param  sf   The scale factor by which to multiply all expected scale elements.
+     * @param  uks  Value of unknown scales (O for {@code inverse()}, or NaN for {@code solve(Y)}).
+     * @throws NoninvertibleMatrixException Should never happen.
+     */
+    private static void testDimensionReduction(final MatrixSIS Y, final double sf, final
double uks)
+            throws NoninvertibleMatrixException
+    {
         final MatrixSIS matrix = Matrices.create(3, 5, new double[] {
             2, 0, 0, 0, 8,
             0, 0, 4, 0, 5,
             0, 0, 0, 0, 1
         });
         final double[] expected = {
-            0.5, 0,    -4,
-            0,   0,     NaN,
-            0,   0.25, -1.25,
-            0,   0,     NaN,
-            0,   0,     1
+            0.5*sf, 0,          -4,
+            uks,    uks,       NaN,
+            0,      0.25*sf, -1.25,
+            uks,    uks,       NaN,
+            0,      0,           1
         };
-        final MatrixSIS inverse = matrix.inverse();
+        final MatrixSIS inverse = (Y != null) ? matrix.solve(Y) : matrix.inverse();
         assertMatrixEquals(expected, 5, 3, inverse, SolverTest.TOLERANCE);
     }
 
     /**
-     * TODO: inverse transform not yet implemented for non-square matrix.
-     */
-    @Override
-    @org.junit.Ignore
-    public void testSolve() 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}.
      */

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=1529972&r1=1529971&r2=1529972&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] Mon Oct  7 15:25:28 2013
@@ -143,7 +143,7 @@ public final strictfp class SolverTest e
             0,     0,  0.5,    0,  -10,
             0,     0,  0,      0,    1
         };
-        MatrixSIS inverse = Solver.inverse(matrix);
+        MatrixSIS inverse = Solver.inverse(matrix, false);
         assertMatrixEquals(expected, 5, 5, inverse, TOLERANCE);
         /*
          * Set a scale factor to NaN. The translation term for the corresponding
@@ -163,7 +163,7 @@ public final strictfp class SolverTest e
             0,     0,  NaN,    0,  NaN,
             0,     0,  0,      0,    1
         };
-        inverse = Solver.inverse(matrix);
+        inverse = Solver.inverse(matrix, false);
         assertMatrixEquals(expected, 5, 5, inverse, TOLERANCE);
         /*
          * Set a scale factor to NaN with translation equals to 0.
@@ -184,7 +184,7 @@ public final strictfp class SolverTest e
             0,     0,  NaN,    0,    0,
             0,     0,  0,      0,    1
         };
-        inverse = Solver.inverse(matrix);
+        inverse = Solver.inverse(matrix, false);
         assertMatrixEquals(expected, 5, 5, inverse, TOLERANCE);
         /*
          * Set a translation term to NaN. The translation should be NaN in
@@ -204,7 +204,7 @@ public final strictfp class SolverTest e
             0,     0,  0.5,    0,  NaN,
             0,     0,  0,      0,    1
         };
-        inverse = Solver.inverse(matrix);
+        inverse = Solver.inverse(matrix, false);
         assertMatrixEquals(expected, 5, 5, inverse, TOLERANCE);
     }
 }



Mime
View raw message