Return-Path: X-Original-To: apmail-sis-commits-archive@www.apache.org Delivered-To: apmail-sis-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4931410BB0 for ; Wed, 18 Sep 2013 16:57:15 +0000 (UTC) Received: (qmail 37832 invoked by uid 500); 18 Sep 2013 16:57:07 -0000 Delivered-To: apmail-sis-commits-archive@sis.apache.org Received: (qmail 37793 invoked by uid 500); 18 Sep 2013 16:57:05 -0000 Mailing-List: contact commits-help@sis.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sis-dev@sis.apache.org Delivered-To: mailing list commits@sis.apache.org Received: (qmail 37756 invoked by uid 99); 18 Sep 2013 16:57:04 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 Sep 2013 16:57:04 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 Sep 2013 16:56:59 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 271732388860; Wed, 18 Sep 2013 16:56:38 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r1524489 - in /sis/branches/JDK7/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/matrix/ test/java/org/apache/sis/referencing/operation/matrix/ test/java/org/apache/sis/test/suite/ Date: Wed, 18 Sep 2013 16:56:38 -0000 To: commits@sis.apache.org From: desruisseaux@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130918165638.271732388860@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: desruisseaux Date: Wed Sep 18 16:56:37 2013 New Revision: 1524489 URL: http://svn.apache.org/r1524489 Log: Ported Matrices.createPassThrough(...) method. Added: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java (with props) Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java 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=1524489&r1=1524488&r2=1524489&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] Wed Sep 18 16:56:37 2013 @@ -31,6 +31,30 @@ import java.util.Objects; /** * {@link Matrix} factory methods and utilities. + * This class provides the following methods: + * + *
    + *
  • Creating new matrices of arbitrary size: + * {@link #createIdentity(int)}, + * {@link #createDiagonal(int, int)}, + * {@link #createZero(int, int)}, + * {@link #create(int, int, double[])}. + *
  • + *
  • Creating new matrices for coordinate operation steps: + * {@link #createDimensionFilter(int, int[])}, + * {@link #createPassThrough(int, Matrix, int)}. + *
  • + *
  • Copies matrices to a SIS implementation: + * {@link #copy(Matrix)}, + * {@link #castOrCopy(Matrix)}. + *
  • + *
  • Information: + * {@link #isAffine(Matrix)}, + * {@link #isIdentity(Matrix, double)}, + * {@link #equals(Matrix, Matrix, double, boolean)}, + * {@link #equals(Matrix, Matrix, ComparisonMode)}. + *
  • + *
* * @author Martin Desruisseaux (IRD, Geomatys) * @since 0.4 (derived from geotk-2.2) @@ -58,7 +82,7 @@ public final class Matrices extends Stat * {@value org.apache.sis.referencing.operation.matrix.Matrix4#SIZE} inclusive, the matrix * is guaranteed to be an instance of one of {@link Matrix1} … {@link Matrix4} subtypes. * - * @param size Numbers of row and columns. For an affine transform, this is the number of + * @param size Numbers of row and columns. For an affine transform matrix, this is the number of * {@linkplain MathTransform#getSourceDimensions() source} and * {@linkplain MathTransform#getTargetDimensions() target} dimensions + 1. * @return An identity matrix of the given size. @@ -84,8 +108,8 @@ public final class Matrices extends Stat * {@value org.apache.sis.referencing.operation.matrix.Matrix4#SIZE} inclusive, the matrix * is guaranteed to be an instance of one of {@link Matrix1} … {@link Matrix4} subtypes. * - * @param numRow For an affine transform, this is the number of {@linkplain MathTransform#getTargetDimensions() target dimensions} + 1. - * @param numCol For an affine transform, this is the number of {@linkplain MathTransform#getSourceDimensions() source dimensions} + 1. + * @param numRow For a math transform, this is the number of {@linkplain MathTransform#getTargetDimensions() target dimensions} + 1. + * @param numCol For a math transform, this is the number of {@linkplain MathTransform#getSourceDimensions() source dimensions} + 1. * @return An identity matrix of the given size. */ public static MatrixSIS createDiagonal(final int numRow, final int numCol) { @@ -106,8 +130,8 @@ public final class Matrices extends Stat * {@value org.apache.sis.referencing.operation.matrix.Matrix4#SIZE} inclusive, the matrix * is guaranteed to be an instance of one of {@link Matrix1} … {@link Matrix4} subtypes. * - * @param numRow For an affine transform, this is the number of {@linkplain MathTransform#getTargetDimensions() target dimensions} + 1. - * @param numCol For an affine transform, this is the number of {@linkplain MathTransform#getSourceDimensions() source dimensions} + 1. + * @param numRow For a math transform, this is the number of {@linkplain MathTransform#getTargetDimensions() target dimensions} + 1. + * @param numCol For a math transform, this is the number of {@linkplain MathTransform#getSourceDimensions() source dimensions} + 1. * @return A matrix of the given size with only zero values. */ public static MatrixSIS createZero(final int numRow, final int numCol) { @@ -151,48 +175,161 @@ public final class Matrices extends Stat /** * Creates a matrix for a transform that keep only a subset of source ordinate values. - * The matrix size will be ({@code selectedSourceDim.length}+1) × ({@code numSourceDim}+1). + * The matrix size will be ({@code selectedDimensions.length}+1) × ({@code sourceDimensions}+1). * The matrix will contain only zero elements, except for the following cells which will contain 1: * *
    *
  • The last column in the last row.
  • - *
  • For any row j other than the last row, the column {@code selectedSourceDim[j]}.
  • + *
  • For any row j other than the last row, the column {@code selectedDimensions[j]}.
  • *
* - * {@example Given (x,y,z,t) ordinate values, if one wants to + * Example: Given (x,y,z,t) ordinate values, if one wants to * keep (y,x,t) ordinates (note the xy swapping) - * and discard the z values, then one can use the following method call: + * and discard the z values, then the indices of source ordinates to select are 1 for y, + * 0 for x and 3 for t. One can use the following method call: * - *
matrix = createDimensionFilter(4, new int[] {1, 0, 3});
+ * {@preformat java + * matrix = Matrices.createDimensionFilter(4, new int[] {1, 0, 3}); + * } * * The above method call will create the following 4×5 matrix, * which can be used for converting coordinates as below: * - *
 ┌   ┐   ┌           ┐   ┌   ┐
-     * │ y │   │ 0 1 0 0 0 │   │ x │
-     * │ x │   │ 1 0 0 0 0 │   │ y │
-     * │ t │ = │ 0 0 0 1 0 │ × │ z │
-     * │ 1 │   │ 0 0 0 0 1 │   │ t │
-     * └   ┘   └           ┘   │ 1 │
-     *                         └   ┘
} - * - * @param numSourceDim The number of dimension of source coordinates. - * @param selectedSourceDim The indices of source ordinate values to keep. - * @return The matrix for an affine transform keeping only the given source dimensions, and discarding all others. - * @throws IllegalArgumentException if a value of {@code selectedSourceDim} is lower than 0 - * or not smaller than {@code numSourceDim}. + * {@preformat math + * ┌ ┐ ┌ ┐ ┌ ┐ + * │ y │ │ 0 1 0 0 0 │ │ x │ + * │ x │ │ 1 0 0 0 0 │ │ y │ + * │ t │ = │ 0 0 0 1 0 │ × │ z │ + * │ 1 │ │ 0 0 0 0 1 │ │ t │ + * └ ┘ └ ┘ │ 1 │ + * └ ┘ + * } + * + * @param sourceDimensions The number of dimensions in source coordinates. + * @param selectedDimensions The 0-based indices of source ordinate values to keep. + * The length of this array will be the number of dimensions in target coordinates. + * @return An affine transform matrix keeping only the given source dimensions, and discarding all others. + * @throws IllegalArgumentException if a value of {@code selectedDimensions} is lower than 0 + * or not smaller than {@code sourceDimensions}. * * @see org.apache.sis.referencing.operation.MathTransforms#dimensionFilter(int, int[]) */ - public static MatrixSIS createDimensionFilter(final int numSourceDim, final int[] selectedSourceDim) { - final int numTargetDim = selectedSourceDim.length; - final MatrixSIS matrix = createZero(numTargetDim+1, numSourceDim+1); + public static MatrixSIS createDimensionFilter(final int sourceDimensions, final int[] selectedDimensions) { + final int numTargetDim = selectedDimensions.length; + final MatrixSIS matrix = createZero(numTargetDim+1, sourceDimensions+1); for (int j=0; jlatitude, longitude, height) coordinates, + * a pass through operation can convert the height values from feet to metres without affecting + * the (latitude, longitude) values. + * + *

The given sub-matrix shall have the following properties:

+ *
    + *
  • The last column contains translation terms, except in the last row.
  • + *
  • The last row often (but not necessarily) contains 0 values except in the last column.
  • + *
+ * + * A square matrix complying with the above conditions is often {@linkplain #isAffine(Matrix) affine}, + * but this is not mandatory + * (for example a perspective transform may contain non-zero values in the last row). + * + *

This method builds a new matrix with the following content:

+ *
    + *
  • An amount of {@code firstAffectedOrdinate} rows and columns are inserted before the first + * row and columns of the sub-matrix. The elements for the new rows and columns are set to 1 + * on the diagonal, and 0 elsewhere.
  • + *
  • The sub-matrix - except for its last row and column - is copied in the new matrix starting + * at index ({@code firstAffectedOrdinate}, {@code firstAffectedOrdinate}).
  • + *
  • An amount of {@code numTrailingOrdinates} rows and columns are appended after the above sub-matrix. + * Their elements are set to 1 on the pseudo-diagonal ending in the lower-right corner, and 0 elsewhere.
  • + *
  • The last sub-matrix row is copied in the last row of the new matrix, and the last sub-matrix column + * is copied in the last column of the sub-matrix.
  • + *
+ * + * Example: Given the following sub-matrix which convert height values from feet to metres: + * + * {@preformat math + * ┌ ┐ ┌ ┐ ┌ ┐ + * │ z' │ = │ 0.3048 0 │ × │ z │ + * │ 1 │ │ 0 1 │ │ 1 │ + * └ ┘ └ ┘ └ ┘ + * } + * + * Then a call to {@code Matrices.createPassThrough(2, subMatrix, 1)} will return the following matrix, + * which can be used for converting the height (z) without affecting the other ordinate values + * in (x,y,z,t) coordinates: + * + * {@preformat math + * ┌ ┐ ┌ ┐ ┌ ┐ + * │ x │ │ 1 0 0 0 0 │ │ x │ + * │ y │ │ 0 1 0 0 0 │ │ y │ + * │ z' │ = │ 0 0 0.3048 0 0 │ × │ z │ + * │ t │ │ 0 0 0 1 0 │ │ t │ + * │ 1 │ │ 0 0 0 0 1 │ │ 1 │ + * └ ┘ └ ┘ └ ┘ + * } + * + * @param firstAffectedOrdinate The lowest index of the affected ordinates. + * @param subMatrix The matrix to use for affected ordinates. + * @param numTrailingOrdinates Number of trailing ordinates to pass through. + * @return A matrix + * + * @see org.apache.sis.referencing.operation.DefaultMathTransformFactory#createPassThroughTransform(int, MathTransform, int) + */ + public static MatrixSIS createPassThrough(final int firstAffectedOrdinate, + final Matrix subMatrix, final int numTrailingOrdinates) + { + ArgumentChecks.ensurePositive("firstAffectedOrdinate", firstAffectedOrdinate); + ArgumentChecks.ensurePositive("numTrailingOrdinates", numTrailingOrdinates); + final int expansion = firstAffectedOrdinate + numTrailingOrdinates; + int sourceDimensions = subMatrix.getNumCol(); + int targetDimensions = subMatrix.getNumRow(); + final MatrixSIS matrix = createZero(targetDimensions-- + expansion, + sourceDimensions-- + expansion); + /* + * Following code process for upper row to lower row. + * First, set the diagonal elements on leading new dimensions. + */ + for (int j=0; j