org.opengis.referencing.operation.Matrix Java Examples

The following examples show how to use org.opengis.referencing.operation.Matrix. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TensorValuesTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests {@link TensorParameters#ALPHANUM} formatting.
 * <ul>
 *   <li>Group name shall be {@code "Affine parametric transformation"}.</li>
 *   <li>No {@code "num_row"} or {@code "num_col"} parameters if their value is equals to 3.</li>
 *   <li>Parameter names shall be of the form {@code "A0"}.</li>
 *   <li>Identifiers present, but only for A0-A2 and B0-B2.</li>
 * </ul>
 */
@Test
public void testWKT2() {
    final Matrix matrix = Matrices.createIdentity(3);
    matrix.setElement(0,2,  4);
    matrix.setElement(1,0, -2);
    matrix.setElement(2,2,  7);
    final ParameterValueGroup group = TensorParameters.ALPHANUM.createValueGroup(
            singletonMap(TensorValues.NAME_KEY, Affine.NAME), matrix);
    validate(group);
    assertWktEquals(
            "PARAMETERGROUP[“Affine parametric transformation”,\n" +
            "  PARAMETER[“A2”, 4.0, ID[“EPSG”, 8625]],\n"  +
            "  PARAMETER[“B0”, -2.0, ID[“EPSG”, 8639]],\n" +
            "  PARAMETER[“C2”, 7.0]]", group);
}
 
Example #2
Source File: AlbersEqualArea.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate)
{
    // θ = n⋅λ  reduced to  [−n⋅π … n⋅π]  range.
    final double θ = wraparoundScaledLongitude(srcPts[srcOff], θ_bound);
    final double φ = srcPts[srcOff + 1];
    final double cosθ = cos(θ);
    final double sinθ = sin(θ);
    final double sinφ = sin(φ);
    final double ρ = sqrt(C - 2*nm*sinφ);           // Snyder 14-3 with radius and division by n omitted.
    if (dstPts != null) {
        dstPts[dstOff  ] = ρ * sinθ;                // Snyder 14-1
        dstPts[dstOff+1] = ρ * cosθ;                // Snyder 14-2
    }
    if (!derivate) {
        return null;
    }
    final double dρ_dφ = -nm*cos(φ) / ρ;
    return new Matrix2(cosθ*ρ, dρ_dφ*sinθ,          // ∂x/∂λ, ∂x/∂φ
                      -sinθ*ρ, dρ_dφ*cosθ);         // ∂y/∂λ, ∂y/∂φ
}
 
Example #3
Source File: ProjectionResultComparator.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Checks if transform using {@link #tested} formulas produces the same result than the {@link #reference} formulas.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff, boolean derivate) throws ProjectionException
{
    final double[] point = Arrays.copyOfRange(srcPts, srcOff, srcOff + 2);
    final Matrix derivative = tested.transform(srcPts, srcOff, dstPts, dstOff, derivate);
    final Matrix expected = reference.transform(point, 0, point, 0, derivate);
    if (dstPts != null) {
        assertEquals("x", point[0], dstPts[dstOff  ], FORWARD_TOLERANCE);
        assertEquals("y", point[1], dstPts[dstOff+1], FORWARD_TOLERANCE);
    }
    if (expected != null && derivative != null) {
        assertEquals("m00", expected.getElement(0,0), derivative.getElement(0,0), DERIVATIVE_TOLERANCE);
        assertEquals("m01", expected.getElement(0,1), derivative.getElement(0,1), DERIVATIVE_TOLERANCE);
        assertEquals("m10", expected.getElement(1,0), derivative.getElement(1,0), DERIVATIVE_TOLERANCE);
        assertEquals("m11", expected.getElement(1,1), derivative.getElement(1,1), DERIVATIVE_TOLERANCE);
    }
    return derivative;
}
 
Example #4
Source File: AbstractSingleOperation.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns {@code true} if the specified transform is likely to exists only for axis swapping
 * and/or unit conversions. The heuristic rule checks if the transform is backed by a square
 * matrix with exactly one non-null value in each row and each column.
 */
private static boolean isIgnorable(final MathTransform transform) {
    final Matrix matrix = MathTransforms.getMatrix(transform);
    if (matrix != null) {
        final int size = matrix.getNumRow();
        if (matrix.getNumCol() == size) {
            for (int j=0; j<size; j++) {
                int n1=0, n2=0;
                for (int i=0; i<size; i++) {
                    if (matrix.getElement(j,i) != 0) n1++;
                    if (matrix.getElement(i,j) != 0) n2++;
                }
                if (n1 != 1 || n2 != 1) {
                    return false;
                }
            }
            return true;
        }
    }
    return false;
}
 
Example #5
Source File: CoordinateSystemsTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests {@link CoordinateSystems#swapAndScaleAxes(CoordinateSystem, CoordinateSystem)} for (λ,φ) ↔ (φ,λ).
 * This very common conversion is of critical importance to Apache SIS.
 *
 * @throws IncommensurableException if a conversion between incompatible units was attempted.
 */
@Test
public void testSwapAndScaleAxes2D() throws IncommensurableException {
    final CoordinateSystem λφ = new DefaultEllipsoidalCS(singletonMap(NAME_KEY, "(λ,φ)"),
            HardCodedAxes.GEODETIC_LONGITUDE,
            HardCodedAxes.GEODETIC_LATITUDE);
    final CoordinateSystem φλ = new DefaultEllipsoidalCS(singletonMap(NAME_KEY, "(φ,λ)"),
            HardCodedAxes.GEODETIC_LATITUDE,
            HardCodedAxes.GEODETIC_LONGITUDE);
    final Matrix expected = Matrices.create(3, 3, new double[] {
            0, 1, 0,
            1, 0, 0,
            0, 0, 1});
    assertTrue(swapAndScaleAxes(λφ, λφ).isIdentity());
    assertTrue(swapAndScaleAxes(φλ, φλ).isIdentity());
    assertMatrixEquals("(λ,φ) → (φ,λ)", expected, swapAndScaleAxes(λφ, φλ), STRICT);
    assertMatrixEquals("(φ,λ) → (λ,φ)", expected, swapAndScaleAxes(φλ, λφ), STRICT);
}
 
Example #6
Source File: DatumShiftTransform.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Computes the conversion factors needed for calls to {@link DatumShiftGrid#interpolateInCell(double, double, double[])}.
 * This method takes only the {@value DatumShiftGrid#INTERPOLATED_DIMENSIONS} first dimensions. If a conversion factor can
 * not be computed, then it is set to NaN.
 */
@SuppressWarnings("fallthrough")
private void computeConversionFactors() {
    scaleX = Double.NaN;
    scaleY = Double.NaN;
    x0     = Double.NaN;
    y0     = Double.NaN;
    if (grid != null) {
        final LinearTransform coordinateToGrid = grid.getCoordinateToGrid();
        final double toStandardUnit = Units.toStandardUnit(grid.getCoordinateUnit());
        if (!Double.isNaN(toStandardUnit)) {
            final Matrix m = coordinateToGrid.getMatrix();
            if (Matrices.isAffine(m)) {
                final int n = m.getNumCol() - 1;
                switch (m.getNumRow()) {
                    default: y0 = m.getElement(1,n); scaleY = diagonal(m, 1, n) / toStandardUnit;   // Fall through
                    case 1:  x0 = m.getElement(0,n); scaleX = diagonal(m, 0, n) / toStandardUnit;
                    case 0:  break;
                }
            }
        }
    }
}
 
Example #7
Source File: LinearTransformBuilderTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests a very simple case where an exact answer is expected.
 *
 * @throws FactoryException if the transform can not be created.
 */
@Test
public void testMinimalist1D() throws FactoryException {
    final LinearTransformBuilder builder = new LinearTransformBuilder();
    final Map<DirectPosition1D,DirectPosition1D> pos = new HashMap<>(4);
    assertNull(pos.put(new DirectPosition1D(1), new DirectPosition1D(1)));
    assertNull(pos.put(new DirectPosition1D(2), new DirectPosition1D(3)));
    builder.setControlPoints(pos);

    assertArrayEquals(new double[] {1}, builder.getControlPoint(new int[] {1}), STRICT);
    assertArrayEquals(new double[] {3}, builder.getControlPoint(new int[] {2}), STRICT);
    assertNull(                         builder.getControlPoint(new int[] {3}));

    final Matrix m = builder.create(null).getMatrix();
    assertEquals("m₀₀",  2, m.getElement(0, 0), STRICT);
    assertEquals("m₀₁", -1, m.getElement(0, 1), STRICT);
    assertArrayEquals("correlation", new double[] {1}, builder.correlation(), STRICT);
}
 
Example #8
Source File: ZonedGridSystem.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Converts the specified (λ,φ) coordinate and stores the result in {@code dstPts}.
 * In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.
 * Note that the derivative does not contain zone prefix.
 *
 * @return the matrix of the projection derivative at the given source position,
 *         or {@code null} if the {@code derivate} argument is {@code false}.
 * @throws TransformException if the coordinate can not be converted.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate) throws TransformException
{
    double λ = srcPts[srcOff] - initialLongitude;
    double φ = srcPts[srcOff+1];
    λ -= RANGE * floor(λ / RANGE);
    final double zone = floor(λ / zoneWidth);
    λ -= (zone * zoneWidth);
    dstPts[dstOff  ] = λ;
    dstPts[dstOff+1] = φ;
    final Matrix derivative = projection.transform(dstPts, dstOff, dstPts, dstOff, derivate);
    dstPts[dstOff] += (zone + 1) * ZONE_SCALE;
    return derivative;
}
 
Example #9
Source File: NormalizedProjection.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Concatenates or pre-concatenates in an optimized way this projection with the given transform, if possible.
 * If no optimization is available, returns {@code null}.
 */
@Override
protected MathTransform tryConcatenate(final boolean applyOtherFirst, final MathTransform other,
        final MathTransformFactory factory) throws FactoryException
{
    final Matrix m = getMiddleMatrix(this, other, applyOtherFirst);
    if (m != null) {
        /*
         * 'projectedSpace' values:
         *   - false if applyOtherFirst == false since we have (inverse projection) → (affine) → (projection).
         *   - true  if applyOtherFirst == true  since we have (projection) → (affine) → (inverse projection).
         */
        return forward.tryConcatenate(applyOtherFirst, m, factory);
    }
    return super.tryConcatenate(applyOtherFirst, other, factory);
}
 
Example #10
Source File: CartesianToPolar.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Converts a single coordinate and optionally computes the derivative.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate)
{
    final double x  = srcPts[srcOff  ];
    final double y  = srcPts[srcOff+1];
    final double r  = hypot(x, y);
    if (dstPts != null) {
        dstPts[dstOff  ] = r;
        dstPts[dstOff+1] = atan2(y, x);
    }
    if (!derivate) {
        return null;
    }
    final double r2 = r*r;
    return new Matrix2(x/r,   y/r,
                      -y/r2,  x/r2);
}
 
Example #11
Source File: TransformSeparatorTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests separation of a linear transform containing {@link Double#NaN} values.
 *
 * @throws FactoryException if an error occurred while creating a new transform.
 */
@Test
public void testIncompleteTransform() throws FactoryException {
    Matrix matrix = new Matrix4(
        1,   0,   0,   7,
        0,   0,   1,   8,
        0, NaN,   0,   6,
        0,   0,   0,   1
    );
    TransformSeparator s = new TransformSeparator(MathTransforms.linear(matrix));
    s.addSourceDimensions(1);
    assertMatrixEquals("transform", new Matrix2(
           NaN, 6,
             0, 1
    ), ((LinearTransform) s.separate()).getMatrix(), STRICT);
    assertArrayEquals(new int[] {2}, s.getTargetDimensions());
}
 
Example #12
Source File: NormalizedProjection.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Inverse transforms the specified {@code srcPts} and stores the result in {@code dstPts}.
 * If the derivative has been requested, then this method will delegate the derivative
 * calculation to the enclosing class and inverts the resulting matrix.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                              double[] dstPts,       int dstOff,
                        final boolean derivate) throws TransformException
{
    if (!derivate) {
        forward.inverseTransform(srcPts, srcOff, dstPts, dstOff);
        return null;
    } else {
        if (dstPts == null) {
            dstPts = new double[DIMENSION];
            dstOff = 0;
        }
        forward.inverseTransform(srcPts, srcOff, dstPts, dstOff);
        return Matrices.inverse(forward.transform(dstPts, dstOff, null, 0, true));
    }
}
 
Example #13
Source File: VariableWrapper.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Sets the scale and offset coefficients in the given "grid to CRS" transform if possible.
 * This method is invoked only for variables that represent a coordinate system axis.
 */
@Override
protected boolean trySetTransform(final Matrix gridToCRS, final int srcDim, final int tgtDim, final Vector values)
        throws IOException, DataStoreException
{
    if (variable instanceof CoordinateAxis1D) {
        final CoordinateAxis1D axis = (CoordinateAxis1D) variable;
        if (axis.isRegular()) {
            final double start     = axis.getStart();
            final double increment = axis.getIncrement();
            if (start != 0 || increment != 0) {
                gridToCRS.setElement(tgtDim, srcDim, increment);
                gridToCRS.setElement(tgtDim, gridToCRS.getNumCol() - 1, start);
                return true;
            }
            /*
             * The UCAR library sometime left those information uninitialized.
             * If it seems to be the case, fallback on our own code.
             */
        }
    }
    return super.trySetTransform(gridToCRS, srcDim, tgtDim, values);
}
 
Example #14
Source File: PassThroughTransform.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the derivative of this transform at a point.
 *
 * @return {@inheritDoc}
 * @throws TransformException if the {@linkplain #subTransform sub-transform} failed.
 */
@Override
public Matrix derivative(final DirectPosition point) throws TransformException {
    final int nSkipped = firstAffectedCoordinate + numTrailingCoordinates;
    final int transDim = subTransform.getSourceDimensions();
    ensureDimensionMatches("point", transDim + nSkipped, point);
    final GeneralDirectPosition subPoint = new GeneralDirectPosition(transDim);
    for (int i=0; i<transDim; i++) {
        subPoint.coordinates[i] = point.getOrdinate(i + firstAffectedCoordinate);
    }
    return expand(MatrixSIS.castOrCopy(subTransform.derivative(subPoint)),
            firstAffectedCoordinate, numTrailingCoordinates, 0);
}
 
Example #15
Source File: PassThroughTransform.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Transforms a single coordinate in a list of ordinal values, and opportunistically
 * computes the transform derivative if requested.
 *
 * @return {@inheritDoc}
 * @throws TransformException if the {@linkplain #subTransform sub-transform} failed.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate) throws TransformException
{
    Matrix derivative = null;
    if (derivate) {
        derivative = derivative(new DirectPositionView.Double(srcPts, srcOff, getSourceDimensions()));
    }
    if (dstPts != null) {
        transform(srcPts, srcOff, dstPts, dstOff, 1);
    }
    return derivative;
}
 
Example #16
Source File: MolodenskyTransform.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Transforms the (λ,φ) or (λ,φ,<var>h</var>) coordinates between two geographic CRS,
 * and optionally returns the derivative at that location.
 *
 * @return {@inheritDoc}
 * @throws TransformException if the point can not be transformed or
 *         if a problem occurred while calculating the derivative.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate) throws TransformException
{
    return transform(srcPts[srcOff], srcPts[srcOff+1], isSource3D ? srcPts[srcOff+2] : 0,
                     dstPts, dstOff, tX, tY, tZ, null, derivate);
}
 
Example #17
Source File: ConcatenatedTransformDirect2D.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the derivative of this transform at a point.
 *
 * @param  point  the coordinate point where to evaluate the derivative.
 * @return the derivative at the specified point (never {@code null}).
 * @throws TransformException if the derivative can't be evaluated at the specified point.
 */
@Override
public Matrix derivative(final Point2D point) throws TransformException {
    final MathTransform2D transform1 = (MathTransform2D) this.transform1;
    final MathTransform2D transform2 = (MathTransform2D) this.transform2;
    final Matrix matrix1 = transform1.derivative(point);
    final Matrix matrix2 = transform2.derivative(transform1.transform(point,null));
    return Matrices.multiply(matrix2, matrix1);
}
 
Example #18
Source File: ScaleTransform.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the derivative of this transform at a point.
 * For a matrix transform, the derivative is the same everywhere.
 *
 * @param  point  ignored (can be {@code null}).
 */
@Override
public Matrix derivative(final DirectPosition point) {
    final int n = factors.length;
    final MatrixSIS matrix = Matrices.createZero(n, n + numDroppedDimensions);
    for (int i=0; i<n; i++) {
        matrix.setElement(i, i, factors[i]);
    }
    return matrix;
}
 
Example #19
Source File: MatrixSIS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Ensures that the given matrix has the given dimension.
 * This is a convenience method for subclasses.
 */
static void ensureSizeMatch(final int numRow, final int numCol, final Matrix matrix)
        throws MismatchedMatrixSizeException
{
    final int othRow = matrix.getNumRow();
    final int othCol = matrix.getNumCol();
    if (numRow != othRow || numCol != othCol) {
        throw new MismatchedMatrixSizeException(Errors.format(
                Errors.Keys.MismatchedMatrixSize_4, numRow, numCol, othRow, othCol));
    }
}
 
Example #20
Source File: SphericalToCartesian.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Converts a single coordinate and optionally computes the derivative.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate)
{
    final double θ = srcPts[srcOff  ];          // Spherical longitude
    final double Ω = srcPts[srcOff+1];          // Spherical latitude
    final double r = srcPts[srcOff+2];          // Spherical radius
    final double cosθ = cos(θ);
    final double sinθ = sin(θ);
    final double cosΩ = cos(Ω);
    final double sinΩ = sin(Ω);
    final double rsinΩ = r * sinΩ;
    final double rcosΩ = r * cosΩ;
    if (dstPts != null) {
        dstPts[dstOff  ] = rcosΩ * cosθ;        // X: Toward prime meridian
        dstPts[dstOff+1] = rcosΩ * sinθ;        // Y: Toward 90° east
        dstPts[dstOff+2] = rsinΩ;               // Z: Toward north pole
    }
    if (!derivate) {
        return null;
    }
    final double dX_dr = cosΩ * cosθ;
    final double dY_dr = cosΩ * sinθ;
    return new Matrix3(-r*dY_dr, -rsinΩ*cosθ, dX_dr,       // ∂X/∂θ, ∂X/∂Ω, ∂X/∂r
                        r*dX_dr, -rsinΩ*sinθ, dY_dr,       // ∂Y/∂θ, ∂Y/∂Ω, ∂Y/∂r
                              0,  rcosΩ,      sinΩ);       // ∂Z/∂θ, ∂Z/∂Ω, ∂Z/∂r
}
 
Example #21
Source File: Matrices.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the inverse of the given matrix.
 *
 * @param  matrix  the matrix to inverse, or {@code null}.
 * @return the inverse of this matrix, or {@code null} if the given matrix was null.
 * @throws NoninvertibleMatrixException if the given matrix is not invertible.
 *
 * @see MatrixSIS#inverse()
 *
 * @since 0.6
 */
public static MatrixSIS inverse(final Matrix matrix) throws NoninvertibleMatrixException {
    if (matrix == null) {
        return null;
    } else if (matrix instanceof MatrixSIS) {
        return ((MatrixSIS) matrix).inverse();  // Maybe the subclass override that method.
    } else if (matrix.getNumRow() != matrix.getNumCol()) {
        return new NonSquareMatrix(matrix).inverse();
    } else {
        return Solver.inverse(matrix, true);
    }
}
 
Example #22
Source File: CylindricalEqualArea.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate)
{
    final double φ = srcPts[srcOff+1];
    if (dstPts != null) {
        dstPts[dstOff  ] = srcPts[srcOff];
        dstPts[dstOff+1] = sin(φ);
    }
    return derivate ? new Matrix2(1, 0, 0, cos(φ)) : null;
}
 
Example #23
Source File: AbstractMathTransform1D.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Transforms a single point in the given array and opportunistically computes its derivative if requested.
 * The default implementation delegates to {@link #transform(double)} and potentially to {@link #derivative(double)}.
 * Subclasses may override this method for performance reason.
 *
 * @return {@inheritDoc}
 * @throws TransformException {@inheritDoc}
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate) throws TransformException
{
    final double coordinate = srcPts[srcOff];
    if (dstPts != null) {
        dstPts[dstOff] = transform(coordinate);
    }
    return derivate ? new Matrix1(derivative(coordinate)) : null;
}
 
Example #24
Source File: AbstractMathTransform1D.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the derivative of this transform at a point. The default implementation ensures that
 * {@code point} is one-dimensional, then delegates to {@link #derivative(double)}.
 *
 * @param  point  the coordinate point where to evaluate the derivative, or {@code null}.
 * @return the derivative at the specified point (never {@code null}).
 * @throws MismatchedDimensionException if {@code point} does not have the expected dimension.
 * @throws TransformException if the derivative can not be evaluated at the specified point.
 */
@Override
public Matrix derivative(final DirectPosition point) throws TransformException {
    final double coordinate;
    if (point == null) {
        coordinate = Double.NaN;
    } else {
        ensureDimensionMatches("point", 1, point);
        coordinate = point.getOrdinate(0);
    }
    return new Matrix1(derivative(coordinate));
}
 
Example #25
Source File: NonSquareMatrix.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * {@inheritDoc}
 *
 * <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;
}
 
Example #26
Source File: ProjectiveTransformTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Executed after every test in order to ensure that the {@linkplain #transform transform}
 * implements the {@link MathTransform1D} or {@link MathTransform2D} interface as needed.
 * In addition, all Apache SIS classes for linear transforms shall implement
 * {@link LinearTransform} and {@link Parameterized} interfaces.
 */
@After
public final void ensureImplementRightInterface() {
    if (transform instanceof TransformResultComparator) {
        transform = ((TransformResultComparator) transform).tested;
    }
    /*
     * Below is a copy of MathTransformTestCase.validate(), with minor modifications
     * due to the fact that this class does not extend MathTransformTestCase.
     */
    assertNotNull("The 'transform' field shall be assigned a value.", transform);
    Validators.validate(transform);
    final int dimension = transform.getSourceDimensions();
    if (transform.getTargetDimensions() == dimension && !skipInterfaceCheckForDimension(dimension)) {
        assertEquals("MathTransform1D", dimension == 1, (transform instanceof MathTransform1D));
        assertEquals("MathTransform2D", dimension == 2, (transform instanceof MathTransform2D));
    } else {
        assertFalse("MathTransform1D", transform instanceof MathTransform1D);
        assertFalse("MathTransform2D", transform instanceof MathTransform2D);
    }
    assertInstanceOf("Parameterized", Parameterized.class, transform);
    /*
     * End of MathTransformTestCase.validate(). Remaining is specific to LinearTransform implementations.
     */
    assertInstanceOf("Not a LinearTransform.", LinearTransform.class, transform);
    final Matrix tm = ((LinearTransform) transform).getMatrix();
    assertTrue("The matrix declared by the MathTransform is not equal to the one given at creation time.",
            Matrices.equals(matrix, tm, tolerance, false));

    assertSame("ParameterDescriptor",
            Affine.getProvider(transform.getSourceDimensions(), transform.getTargetDimensions(), true).getParameters(),
            ((Parameterized) transform).getParameterDescriptors());
}
 
Example #27
Source File: PolarStereographic.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Converts the specified (θ,φ) coordinate (units in radians) and stores the result in {@code dstPts}.
 * In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.
 *
 * @return the matrix of the projection derivative at the given source position,
 *         or {@code null} if the {@code derivate} argument is {@code false}.
 * @throws ProjectionException if the coordinate can not be converted.
 */
@Override
public Matrix transform(final double[] srcPts, final int srcOff,
                        final double[] dstPts, final int dstOff,
                        final boolean derivate) throws ProjectionException
{
    /*
     * Note: formulas below are very similar to LambertConicConformal.transform(…) with n = -1.
     */
    final double θ    = srcPts[srcOff  ];   // θ = λ - λ₀
    final double φ    = srcPts[srcOff+1];   // Sign may be reversed
    final double sinθ = sin(θ);
    final double cosθ = cos(θ);
    final double sinφ = sin(φ);
    /*
     * From EPSG guide:
     *
     *    t = tan(π/4 + φ/2) / {[(1 + ℯ⋅sinφ)  /  (1 – ℯ⋅sinφ)]^(ℯ/2)}
     *
     * The next step is to compute ρ = 2⋅a⋅k₀⋅t / …, but those steps are
     * applied by the denormalization matrix and shall not be done here.
     */
    final double t = expΨ(φ, eccentricity*sinφ);
    final double x = t * sinθ;
    final double y = t * cosθ;
    if (dstPts != null) {
        dstPts[dstOff  ] = x;
        dstPts[dstOff+1] = y;
    }
    if (!derivate) {
        return null;
    }
    /*
     * End of map projection. Now compute the derivative.
     */
    final double dt = t * dy_dφ(sinφ, cos(φ));
    return new Matrix2(y, dt*sinθ,   // ∂x/∂λ , ∂x/∂φ
                      -x, dt*cosθ);  // ∂y/∂λ , ∂y/∂φ
}
 
Example #28
Source File: TransferFunction.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Sets the {@link #scale} and {@link #offset} terms from the given function.
 *
 * @param  function  the transform to set.
 * @throws IllegalArgumentException if this method does not recognize the given transform.
 */
private void setLinearTerms(final LinearTransform function) throws IllegalArgumentException {
    final Matrix m = function.getMatrix();
    final int numRow = m.getNumRow();
    final int numCol = m.getNumCol();
    if (numRow != 2 || numCol != 2) {
        final Integer two = 2;
        throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedMatrixSize_4, two, two, numRow, numCol));
    }
    scale  = m.getElement(0, 0);
    offset = m.getElement(0, 1);
}
 
Example #29
Source File: LinearTransformBuilderTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests a very simple case where an exact answer is expected.
 * Tolerance threshold is set to zero because the math transform has been built from exactly 3 points,
 * in which case we expect an exact solution without rounding errors at the scale of the {@code double}
 * type. This is possible because SIS implementation uses double-double arithmetic.
 *
 * @throws FactoryException if the transform can not be created.
 */
@Test
public void testMinimalist2D() throws FactoryException {
    final Map<DirectPosition2D,DirectPosition2D> pos = new HashMap<>(8);
    assertNull(pos.put(new DirectPosition2D(1, 1), new DirectPosition2D(3, 2)));
    assertNull(pos.put(new DirectPosition2D(1, 2), new DirectPosition2D(3, 5)));
    assertNull(pos.put(new DirectPosition2D(2, 2), new DirectPosition2D(5, 5)));
    final LinearTransformBuilder builder = new LinearTransformBuilder();
    builder.setControlPoints(pos);

    assertArrayEquals(new double[] {3, 2}, builder.getControlPoint(new int[] {1, 1}), STRICT);
    assertArrayEquals(new double[] {3, 5}, builder.getControlPoint(new int[] {1, 2}), STRICT);
    assertArrayEquals(new double[] {5, 5}, builder.getControlPoint(new int[] {2, 2}), STRICT);
    assertNull(                            builder.getControlPoint(new int[] {2, 1}));

    final Matrix m = builder.create(null).getMatrix();

    // First row (x)
    assertEquals("m₀₀",  2, m.getElement(0, 0), STRICT);
    assertEquals("m₀₁",  0, m.getElement(0, 1), STRICT);
    assertEquals("m₀₂",  1, m.getElement(0, 2), STRICT);

    // Second row (y)
    assertEquals("m₁₀",  0, m.getElement(1, 0), STRICT);
    assertEquals("m₁₁",  3, m.getElement(1, 1), STRICT);
    assertEquals("m₁₂", -1, m.getElement(1, 2), STRICT);

    assertArrayEquals("correlation", new double[] {1, 1}, builder.correlation(), STRICT);
}
 
Example #30
Source File: EllipsoidToCentricTransform.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Computes the derivative at the given location. We need to override this method because
 * we will inverse 3×2 matrices in a special way, with the knowledge that <var>h</var>
 * can be set to 0.
 */
@Override
public Matrix derivative(final DirectPosition point) throws TransformException {
    ArgumentChecks.ensureNonNull("point", point);
    final double[] coordinate = point.getCoordinate();
    ArgumentChecks.ensureDimensionMatches("point", 3, coordinate);
    return this.transform(coordinate, 0, coordinate, 0, true);
}