Author: desruisseaux
Date: Fri Mar 20 11:52:25 2015
New Revision: 1667988

URL: http://svn.apache.org/r1667988
Log:
Matrix: added a test case for MatrixSIS.concatenate(...), and documentation 
fixes.

Modified:
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
    
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
    
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
    
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java
    
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -133,7 +133,7 @@ public final class Matrix1 extends Matri
     /**
      * Returns the number of rows in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumRow() {
@@ -143,7 +143,7 @@ public final class Matrix1 extends Matri
     /**
      * Returns the number of columns in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumCol() {
@@ -191,6 +191,8 @@ public final class Matrix1 extends Matri
     /**
      * Returns all matrix elements in a flat, row-major (column indices vary 
fastest) array.
      * The array length is 1.
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final double[] getElements() {
@@ -220,6 +222,8 @@ public final class Matrix1 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isAffine() {
@@ -228,6 +232,8 @@ public final class Matrix1 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isIdentity() {
@@ -269,6 +275,8 @@ public final class Matrix1 extends Matri
 
     /**
      * Returns a hash code value based on the data values in this object.
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public int hashCode() {

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -143,7 +143,7 @@ public final class Matrix2 extends Matri
     /**
      * Returns the number of rows in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumRow() {
@@ -153,7 +153,7 @@ public final class Matrix2 extends Matri
     /**
      * Returns the number of columns in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumCol() {
@@ -209,6 +209,8 @@ public final class Matrix2 extends Matri
     /**
      * Returns all matrix elements in a flat, row-major (column indices vary 
fastest) array.
      * The array length is 4.
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final double[] getElements() {
@@ -240,6 +242,8 @@ public final class Matrix2 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isAffine() {
@@ -248,6 +252,8 @@ public final class Matrix2 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isIdentity() {
@@ -296,6 +302,8 @@ public final class Matrix2 extends Matri
 
     /**
      * Returns a hash code value based on the data values in this object.
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public int hashCode() {

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -155,7 +155,7 @@ public final class Matrix3 extends Matri
     /**
      * Returns the number of rows in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumRow() {
@@ -165,7 +165,7 @@ public final class Matrix3 extends Matri
     /**
      * Returns the number of columns in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumCol() {
@@ -231,6 +231,8 @@ public final class Matrix3 extends Matri
     /**
      * Returns all matrix elements in a flat, row-major (column indices vary 
fastest) array.
      * The array length is 9.
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final double[] getElements() {
@@ -264,6 +266,8 @@ public final class Matrix3 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isAffine() {
@@ -272,6 +276,8 @@ public final class Matrix3 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isIdentity() {

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -173,7 +173,7 @@ public final class Matrix4 extends Matri
     /**
      * Returns the number of rows in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumRow() {
@@ -183,7 +183,7 @@ public final class Matrix4 extends Matri
     /**
      * Returns the number of columns in this matrix, which is always {@value 
#SIZE} in this implementation.
      *
-     * @return Always {@value SIZE}.
+     * @return Always {@value #SIZE}.
      */
     @Override
     public final int getNumCol() {
@@ -263,6 +263,8 @@ public final class Matrix4 extends Matri
     /**
      * Returns all matrix elements in a flat, row-major (column indices vary 
fastest) array.
      * The array length is 16.
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final double[] getElements() {
@@ -298,6 +300,8 @@ public final class Matrix4 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isAffine() {
@@ -306,6 +310,8 @@ public final class Matrix4 extends Matri
 
     /**
      * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
      */
     @Override
     public final boolean isIdentity() {

Modified: 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -38,7 +38,7 @@ import org.apache.sis.util.resources.Err
  *   <li>basic operations needed for <cite>referencing by coordinates</cite>:
  *       {@link #transpose()}, {@link #inverse()}, {@link 
#multiply(Matrix)};</li>
  *   <li>some operations more specific to referencing by coordinates:
- *       {@link #isAffine()}, {@link #normalizeColumns()}.</li>
+ *       {@link #isAffine()}, {@link #normalizeColumns()}, {@link 
#concatenate(int, Number, Number)}.</li>
  * </ul>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
@@ -292,17 +292,36 @@ public abstract class MatrixSIS implemen
     /**
      * Assuming that this matrix represents an affine transform, applies a 
scale and a translation
      * on the given dimension.
-     *
-     * <p>If:</p>
+     * If:
      * <ul>
      *   <li>{@code original} is this matrix before this method call</li>
      *   <li>{@code modified} is this matrix after this method call</li>
      * </ul>
      *
-     * Then transforming a coordinate by {@code modified} is equivalent to 
first replacing the ordinate
+     * then transforming a coordinate by {@code modified} is equivalent to 
first replacing the ordinate
      * value at dimension {@code srcDim} by ({@code scale} × 
<var>ordinate</var> + {@code offset}),
      * then apply the {@code original} transform.
      *
+     * {@section Comparison with Java2D}
+     * If this matrix was an instance of Java2D {@link AffineTransform}, then 
invoking this method would
+     * be equivalent to invoke the following {@code AffineTransform} methods 
in the order shown below:
+     *
+     * <table class="sis">
+     *   <caption>Equivalence between this method and {@code AffineTransform} 
({@code at}) methods</caption>
+     *   <tr>
+     *     <th>{@code concatenate(0, scale, offset)}</th>
+     *     <th>{@code concatenate(1, scale, offset)}</th>
+     *   </tr>
+     *   <tr>
+     *     <td><code>at.{@linkplain AffineTransform#translate(double, double) 
translate}(offset, 0)</code></td>
+     *     <td><code>at.{@linkplain AffineTransform#translate(double, double) 
translate}(0, offset)</code></td>
+     *   </tr>
+     *   <tr>
+     *     <td><code>at.{@linkplain AffineTransform#scale(double, double) 
scale}(scale, 1)</code></td>
+     *     <td><code>at.{@linkplain AffineTransform#scale(double, double) 
scale}(1, scale)</code></td>
+     *   </tr>
+     * </table>
+     *
      * @param srcDim The dimension of the ordinate to rescale in the source 
coordinates.
      * @param scale  The amount by which to multiply the source ordinate value 
before to apply the transform, or {@code null} if none.
      * @param offset The amount by which to translate the source ordinate 
value before to apply the transform, or {@code null} if none.
@@ -311,21 +330,21 @@ public abstract class MatrixSIS implemen
      *
      * @since 0.6
      */
-    public void concatenateAffine(final int srcDim, final Number scale, final 
Number offset) {
+    public void concatenate(final int srcDim, final Number scale, final Number 
offset) {
         final int lastCol = getNumCol() - 1;
         ArgumentChecks.ensureValidIndex(lastCol, srcDim);
         final DoubleDouble s = new DoubleDouble();
         final DoubleDouble t = new DoubleDouble();
-        for (int j = getNumRow() - 1; --j >= 0;) {
+        for (int j = getNumRow(); --j >= 0;) {
             if (offset != null) {
-                get(j, srcDim,  s); // Scale factor
-                get(j, lastCol, t); // Translation factor
+                get(j, srcDim,  s);     // Scale factor
+                get(j, lastCol, t);     // Translation factor
                 s.multiply(offset);
                 t.add(s);
                 set(j, lastCol, t);
             }
             if (scale != null) {
-                get(j, srcDim, s);  // Scale factor
+                get(j, srcDim, s);      // Scale factor
                 s.multiply(scale);
                 set(j, srcDim, s);
             }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -28,7 +28,7 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 public final strictfp class GeneralMatrixTest extends MatrixTestCase {
@@ -93,4 +93,16 @@ public final strictfp class GeneralMatri
                 -2.2204460492503132E-17,
                 -2.5483615218035994E-18}, elements, STRICT);
     }
+
+    /**
+     * Tests {@link MatrixSIS#concatenate(int, Number, Number)} using {@link 
AffineTranform}
+     * as a reference implementation.
+     *
+     * @since 0.6
+     */
+    @Test
+    public void testConcatenate() {
+        testConcatenate(new GeneralMatrix(3, 3, true, 1), true);    // Double 
precision
+        testConcatenate(new GeneralMatrix(3, 3, true, 2), true);    // 
Double-double precision
+    }
 }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -29,7 +29,7 @@ import static org.apache.sis.referencing
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 @DependsOn(SolverTest.class)
@@ -100,4 +100,15 @@ public final strictfp class Matrix3Test
         // Now the actual test.
         assertEqualsElements(expected, SIZE, SIZE, A.solve(B), TOLERANCE);
     }
+
+    /**
+     * Tests {@link MatrixSIS#concatenate(int, Number, Number)} using {@link 
AffineTranform}
+     * as a reference implementation.
+     *
+     * @since 0.6
+     */
+    @Test
+    public void testConcatenate() {
+        testConcatenate(new Matrix3(), true);
+    }
 }

Modified: 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java?rev=1667988&r1=1667987&r2=1667988&view=diff
==============================================================================
--- 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
 [UTF-8] (original)
+++ 
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
 [UTF-8] Fri Mar 20 11:52:25 2015
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.operation.matrix;
 
 import java.util.Random;
+import java.awt.geom.AffineTransform;
 import Jama.Matrix;
 import org.apache.sis.math.Statistics;
 import org.apache.sis.internal.util.DoubleDouble;
@@ -45,7 +46,7 @@ import static org.apache.sis.test.Assert
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.6
  * @module
  */
 public abstract strictfp class MatrixTestCase extends TestCase {
@@ -195,6 +196,29 @@ public abstract strictfp class MatrixTes
     }
 
     /**
+     * Asserts that an element from the given matrix is equals to the expected 
value, using a relative threshold.
+     */
+    private static void assertEqualsRelative(final String message, final 
double expected,
+            final MatrixSIS matrix, final int row, final int column)
+    {
+        assertEquals(message, expected, matrix.getElement(row, column), 
StrictMath.abs(expected) * 1E-12);
+    }
+
+    /**
+     * Returns the next random number as a value between approximatively -100 
and 100
+     * with the guarantee to be different than zero. The values returned by 
this method
+     * are suitable for testing scale factors.
+     */
+    private double nextNonZeroRandom() {
+        double value = random.nextDouble() * 200 - 100;
+        value += StrictMath.copySign(0.001, value);
+        if (random.nextBoolean()) {
+            value = 1 / value;
+        }
+        return value;
+    }
+
+    /**
      * Creates an array of the given length filled with random values. All 
random values are between 0 inclusive
      * and 100 exclusive. This method never write negative values. 
Consequently, any strictly negative value set
      * by the test method is guaranteed to be different than all original 
values in the returned array.
@@ -372,6 +396,71 @@ public abstract strictfp class MatrixTes
         }
     }
 
+    /**
+     * Tests {@link MatrixSIS#concatenate(int, Number, Number)} using {@link 
AffineTranform}
+     * as a reference implementation. This test can be run only with matrices 
of size 3×3.
+     * Consequently it is sub-classes responsibility to add a {@code 
testConcatenate()} method
+     * which invoke this method.
+     *
+     * @param matrix The matrix of size 3×3 to test.
+     * @param withShear {@code true} for including shear in the matrix to test.
+     *        This value can be set to {@code false} if the subclass want to 
test a simpler case.
+     *
+     * @since 0.6
+     */
+    final void testConcatenate(final MatrixSIS matrix, final boolean 
withShear) {
+        initialize(4599164481916500056L);
+        final AffineTransform at = new AffineTransform();
+        if (withShear) {
+            at.shear(nextNonZeroRandom(), nextNonZeroRandom());
+            matrix.setElement(0, 1, at.getShearX());
+            matrix.setElement(1, 0, at.getShearY());
+        }
+        for (int i=0; i<100; i++) {
+            /*
+             * 1) For the first  30 iterations, test the result of applying 
only a scale.
+             * 2) For the next   30 iterations, test the result of applying 
only a translation.
+             * 3) For all remaining iterations, test combination of scale and 
translation.
+             */
+            final Number scale  = (i >= 60 || i < 30) ? nextNonZeroRandom() : 
null;
+            final Number offset = (i >= 30)           ? nextNonZeroRandom() : 
null;
+            /*
+             * Apply the scale and offset on the affine transform, which we 
use as the reference
+             * implementation. The scale and offset must be applied in the 
exact same order than
+             * the order documented in MatrixSIS.concatenate(…) javadoc.
+             */
+            final int srcDim = (i & 1);
+            if (offset != null) {
+                switch (srcDim) {
+                    case 0: at.translate(offset.doubleValue(), 0); break;
+                    case 1: at.translate(0, offset.doubleValue()); break;
+                }
+            }
+            if (scale != null) {
+                switch (srcDim) {
+                    case 0: at.scale(scale.doubleValue(), 1); break;
+                    case 1: at.scale(1, scale.doubleValue()); break;
+                }
+            }
+            /*
+             * Apply the operation and compare with our reference 
implementation.
+             */
+            matrix.concatenate(srcDim, scale, offset);
+            final String message = (offset == null) ? "After scale" :
+                                   (scale  == null) ? "After translate" : 
"After scale and translate";
+            assertEqualsRelative(message, 0,                  matrix, 2, 0);
+            assertEqualsRelative(message, 0,                  matrix, 2, 1);
+            assertEqualsRelative(message, 1,                  matrix, 2, 2);
+            assertEqualsRelative(message, at.getTranslateX(), matrix, 0, 2);
+            assertEqualsRelative(message, at.getTranslateY(), matrix, 1, 2);
+            assertEqualsRelative(message, at.getScaleX(),     matrix, 0, 0);
+            assertEqualsRelative(message, at.getScaleY(),     matrix, 1, 1);
+            assertEqualsRelative(message, at.getShearX(),     matrix, 0, 1);
+            assertEqualsRelative(message, at.getShearY(),     matrix, 1, 0);
+            assertTrue("isAffine", matrix.isAffine());
+        }
+    }
+
     /**
      * Tests {@link MatrixSIS#multiply(Matrix)}.
      */


Reply via email to