Class InterpolatedTransform.Inverse
java.lang.Object
org.apache.sis.io.wkt.FormattableObject
org.apache.sis.referencing.operation.transform.AbstractMathTransform
org.apache.sis.referencing.operation.transform.AbstractMathTransform.Inverse
org.apache.sis.referencing.operation.transform.InterpolatedTransform.Inverse
- All Implemented Interfaces:
Serializable
,Parameterized
,LenientComparable
,org.opengis.referencing.operation.MathTransform
- Direct Known Subclasses:
InterpolatedTransform2D.Inverse
- Enclosing class:
- InterpolatedTransform
static class InterpolatedTransform.Inverse
extends AbstractMathTransform.Inverse
implements Serializable
Transforms target coordinates to source coordinates. This is done by iteratively finding target coordinates
that shift to the input coordinates. The input coordinates is used as the first approximation.
Algorithm
The algorithm used in this class takes some inspiration from the Gradient descent method, except that we do not use gradient direction. Instead, we use positional error direction computed with Jacobian matrix. Instead of moving in the opposite of gradient direction, we move in the opposite of positional error vector. This algorithm works well when the errors are small, which is the case for datum shift grids such as NADCON. It may work not so well with strongly curved localization grids as found in some netCDF files. In such case, the iterative algorithm may throw aTransformException
with "No convergence" message.
We could improve the algorithm by multiplying the translation vector by some factor 0 < γ < 1,
for example by taking inspiration from the Barzilai–Borwein method. But this is not yet done for avoiding
a computation cost penalty for the main target of this class, which is datum shift grids.
Possible improvement
If strongly curved localization grids need to be supported, a possible strategy for choosing a γ factor could be to compare the translation vector at an iteration step with the translation vector at previous iteration. If the two vectors cancel each other, we can retry with γ=0.5. This is assuming that the position we are looking for is located midway betweeb the two positions explored by the two iteration steps.- Since:
- 0.7
- Version:
- 1.0
-
Nested Class Summary
Nested classes/interfaces inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform
AbstractMathTransform.Inverse
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final boolean
Whether to enable debugging.private final InterpolatedTransform
The enclosing transform.private static final int
Maximum number of iterations.private static final long
Serial number for inter-operability with different versions.private static final boolean
Whether to use a simple version of this inverse transform (where the Jacobian matrix is close to identity in every points) or a more complex version using derivatives (Jacobian matrices) for adjusting the errors.private final double
Difference allowed in iterative computations, in units of grid cell size.Fields inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform
MAXIMUM_BUFFER_SIZE, MAXIMUM_FAILURES
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionorg.opengis.referencing.operation.MathTransform
inverse()
Returns the inverse of this math transform.final org.opengis.referencing.operation.Matrix
transform
(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) Transforms a single position in a list of coordinate values, and optionally returns the derivative at that location.final void
transform
(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) Transforms an arbitrary number of coordinate tuples.Methods inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform.Inverse
beforeFormat, computeHashCode, derivative, equals, formatTo, getDomain, getSourceDimensions, getTargetDimensions, isIdentity
Methods inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform
equals, getContextualParameters, getParameterDescriptors, getParameterValues, hashCode, isInverseEquals, mismatchedDimension, transform, transform, transform, transform, tryConcatenate
Methods inherited from class org.apache.sis.io.wkt.FormattableObject
print, toString, toString, toWKT
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface org.opengis.referencing.operation.MathTransform
toWKT
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDSerial number for inter-operability with different versions.- See Also:
-
DEBUG
private static final boolean DEBUGWhether to enable debugging. Iftrue
, additional but very costlyassert
statements will be enabled, and some information will be printed to the standard output stream. Enabling debugging slows down considerably the transformations; it should be done only for small set of test data.- See Also:
-
SIMPLE
private static final boolean SIMPLEWhether to use a simple version of this inverse transform (where the Jacobian matrix is close to identity in every points) or a more complex version using derivatives (Jacobian matrices) for adjusting the errors. The simple mode is okay for transformations based on e.g. NADCON or NTv2 grids, but is not sufficient for more curved grids like the ones read from netCDF files. We provide this switch for allowing performance comparisons.- See Also:
-
MAXIMUM_ITERATIONS
private static final int MAXIMUM_ITERATIONSMaximum number of iterations. This is set to a higher value thanFormulas.MAXIMUM_ITERATIONS
because the data used inInterpolatedTransform
grid may come from anywhere, in particular localization grids in netCDF files. Deformations in those grids may be much higher than e.g.DatumShiftTransform
grids. The algorithm in this class converges more slowly in area with very strong curvature.- See Also:
-
forward
The enclosing transform. -
tolerance
private final double toleranceDifference allowed in iterative computations, in units of grid cell size.
-
-
Constructor Details
-
Inverse
Inverse(InterpolatedTransform forward) Creates an inverse transform.
-
-
Method Details
-
inverse
public org.opengis.referencing.operation.MathTransform inverse()Returns the inverse of this math transform.- Specified by:
inverse
in interfaceorg.opengis.referencing.operation.MathTransform
- Specified by:
inverse
in classAbstractMathTransform.Inverse
- Returns:
- the inverse of this transform.
-
transform
public final org.opengis.referencing.operation.Matrix transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) throws org.opengis.referencing.operation.TransformException Transforms a single position in a list of coordinate values, and optionally returns the derivative at that location.- Specified by:
transform
in classAbstractMathTransform
- Parameters:
srcPts
- the array containing the source coordinates (cannot benull
).srcOff
- the offset to the point to be transformed in the source array.dstPts
- the array into which the transformed coordinates is returned. May be the same thansrcPts
. May benull
if only the derivative matrix is desired.dstOff
- the offset to the location of the transformed point that is stored in the destination array.derivate
-true
for computing the derivative, orfalse
if not needed.- Returns:
- the matrix of the transform derivative at the given source position,
or
null
if thederivate
argument isfalse
. - Throws:
org.opengis.referencing.operation.TransformException
- if there is no convergence.- See Also:
-
transform
public final void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws org.opengis.referencing.operation.TransformException Transforms an arbitrary number of coordinate tuples. See class javadoc for some information about the algorithm.- Specified by:
transform
in interfaceorg.opengis.referencing.operation.MathTransform
- Overrides:
transform
in classAbstractMathTransform
- Parameters:
srcPts
- the array containing the source point coordinates.srcOff
- the offset to the first point to be transformed in the source array.dstPts
- the array into which the transformed point coordinates are returned. May be the same thansrcPts
.dstOff
- the offset to the location of the first transformed point that is stored in the destination array.numPts
- the number of point objects to be transformed.- Throws:
org.opengis.referencing.operation.TransformException
- if a point cannot be transformed.
-