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)}.
*/