/** Gets the derivative of this function at a value. */ public double derivative(final double value) throws TransformException { final double value1 = transform1.derivative(value); final double value2 = transform2.derivative(transform1.transform(value)); return value2 * value1; }
final MathTransform1D direct = (MathTransform1D) factory.createParameterizedTransform(parameters); final MathTransform1D inverse = direct.inverse(); final DirectPosition1D point = new DirectPosition1D(); for (int i = 0; i < expected.length; i++) { final double x = input[i]; final double y = direct.transform(x); assertEquals("transform[x=" + x + ']', expected[i], y, 1E-6); assertEquals("inverse [y=" + y + ']', x, inverse.transform(y), 1E-6); point.setOrdinate(0, x); assertSame(direct.transform(point, point), point); assertEquals(y, point.getOrdinate(0), 1E-9);
MathTransform1D transform = nativeBands[i].getSampleToGeophysics(); if (transform!=null && !toGeo) try { transform = transform.inverse(); // We want the geophysics to native transform. } catch (NoninvertibleTransformException e) { transform = null; isIdentity &= transform.isIdentity(); if (!toGeo) { transform = transform.inverse(); offset = transform.transform(0); scale = transform.derivative(Double.NaN); if (isNaN(scale) || isNaN(offset)) {
if (transforms[i]!=null && !geo) { transforms[i] = (MathTransform1D) transforms[i].inverse(); transform = (MathTransform1D) transform.inverse(); final double offset = transform.transform(0); final double scale = transform.derivative(Double.NaN); if (Double.isNaN(scale) || Double.isNaN(offset)) {
assertSame ("transferFunction", category.toConverse, category.getTransferFunction().get()); assertNotSame ("transferFunction", converse.toConverse, converse.getTransferFunction().get()); assertTrue ("transferFunction", converse.getTransferFunction().get().isIdentity()); assertFalse ("toConverse.isIdentity", category.toConverse.isIdentity()); assertFalse ("toConverse.isIdentity", converse.toConverse.isIdentity()); assertTrue ("isQuantitative", category.isQuantitative()); assertTrue ("isQuantitative", converse.isQuantitative()); assertSame("inverse", inverse, category.toConverse.inverse()); for (int i=0; i<20; i++) { final double x = 100 * random.nextDouble(); final double y = x*scale + offset; assertEquals("toConverse", y, category.toConverse.transform(x), EPS); assertEquals("inverse", x, inverse.transform(y), EPS);
/** * Returns the sample dimension that describes real values. This method establishes a unidirectional navigation * from sample values to real values. This is in contrast to {@link #converse}, which establish a bidirectional * navigation. * * @see #forConvertedValues(boolean) */ private SampleDimension converted() { // Transfer function shall never be null if 'converse' is non-null. return (converse != null && !transferFunction.isIdentity()) ? converse : this; }
return new Matrix1(((MathTransform1D) this).derivative(point.getOrdinate(0)));
tr = (MathTransform1D) tr.inverse(); final double EPS = 1E-6; // For rounding error. final double ratio = tr.derivative(minimum) / tr.derivative(maximum); if (Math.abs(ratio-1) <= EPS) { linear = true;
assertSame ("sampleRange", category.range, category.getSampleRange()); assertFalse ("measurementRange", category.getMeasurementRange().isPresent()); assertFalse ("toConverse.isIdentity", category.toConverse.isIdentity()); assertFalse ("transferFunction", category.getTransferFunction().isPresent()); assertFalse ("isQuantitative", category.isQuantitative()); assertNotNull("sampleRange", converse.getSampleRange()); assertFalse ("measurementRange", category.getMeasurementRange().isPresent()); assertFalse ("toConverse.isIdentity", converse.toConverse.isIdentity()); assertFalse ("transferFunction", converse.getTransferFunction().isPresent()); assertFalse ("isQuantitative", converse.isQuantitative()); for (int i=0; i<4; i++) { final float x = 100 * random.nextFloat(); final float y = (float) category.toConverse.transform(x); assertTrue("isNaN", Float.isNaN(y)); final int ordinal = MathFunctions.toNanOrdinal(y); assertEquals("ordinal", sample, ordinal); assertEquals("inverse", sample, (float) inverse.transform(y), (float) STRICT);
if (toUnits != null) { toConverse = toUnits; if (toUnits.isIdentity()) { converse = this; if (!(samples instanceof MeasurementRange<?>)) { return; toSamples = toUnits.inverse(); } else {
public synchronized MathTransform1D inverse() throws NoninvertibleTransformException { if (inverse != null) return inverse; if (transform == null) throw new IllegalStateException(Errors.format(ErrorKeys.ILLEGAL_STATE)); inverse = (MathTransform1D) transform.inverse(); return inverse; }
public boolean isIdentity() { return transform.isIdentity(); }
/** * Returns {@code true} if the given conversion seems to change the axis direction. * This happen for example with conversions from "Elevation" axis to "Depth" axis. * In case of doubt, this method returns {@code false}. * * <div class="note"><b>Note about alternatives:</b> * we could compare axis directions instead, but it would not work with user-defined directions * or user-defined unit conversions with negative scale factor (should never happen, but we are * paranoiac). We could compare the minimum and maximum values after conversions, but it would * not work if one or both values are {@code null} or {@code NaN}. Since we want to preserve * {@link NilReason}, we still need to know if axes are reversed in order to put the nil reason * in the right location.</div> * * @param cv the conversion computed by {@link #getConversionFrom(VerticalCRS)} (may be {@code null}). * @param sample the minimum or the maximum value. * @param other the minimum or maximum value at the opposite bound. * @return {@code true} if the axis direction is reversed at the given value. */ private static boolean isReversing(final MathTransform1D cv, Double sample, final Double other) throws TransformException { if (cv == null) { return false; } if (sample == null || sample.isNaN()) { sample = other; } else if (other != null && !other.isNaN()) { sample = (sample + other) / 2; } return MathFunctions.isNegative(cv.derivative(sample != null ? sample : Double.NaN)); }
final MathTransform1D indexToValues = tr; try { tr = create(preimage.clone()).inverse(); // preimageToIndex transform. } catch (NoninvertibleTransformException e) { throw new IllegalArgumentException(Resources.format(Resources.Keys.NonMonotonicSequence_1, "preimage"), e);
transforms[i].transform(array, 0, array, 0, array.length); data[i] = array; transforms[i].transform(array, 0, array, 0, length); data[i] = array; min( max( round(tr.transform(j + offset)), Integer.MIN_VALUE), Integer.MAX_VALUE); min( max( round(tr.transform(j + offset)), minimum), maximum); for (int j = length; --j >= 0; ) { array[j] = (byte) min(max(round(tr.transform(j + offset)), 0), 0xFF);
/** * Gets the derivative of this function at a value. */ @Override public double derivative(final double value) throws TransformException { final double value1 = ((MathTransform1D) transform1).derivative(value); final double value2 = ((MathTransform1D) transform2).derivative( ((MathTransform1D) transform1).transform(value)); return value2 * value1; }
/** * Returns a sample dimension that describes real values or sample values, depending if {@code converted} is {@code true} * or {@code false} respectively. If there is no {@linkplain #getTransferFunction() transfer function}, then this method * returns {@code this}. * * @param converted {@code true} for a sample dimension representing converted values, * or {@code false} for a sample dimension representing sample values. * @return a sample dimension representing converted or sample values, depending on {@code converted} argument value. * May be {@code this} but never {@code null}. */ public SampleDimension forConvertedValues(final boolean converted) { // Transfer function shall never be null if 'converse' is non-null. if (converse != null && transferFunction.isIdentity() != converted) { return converse; } return this; }
/** * Returns {@code true} if the given conversion seems to change the axis direction. * This happen for example with conversions from "Elevation" axis to "Depth" axis. * In case of doubt, this method returns {@code false}. * * <div class="note"><b>Note about alternatives:</b> * we could compare axis directions instead, but it would not work with user-defined directions * or user-defined unit conversions with negative scale factor (should never happen, but we are * paranoiac). We could compare the minimum and maximum values after conversions, but it would * not work if one or both values are {@code null} or {@code NaN}. Since we want to preserve * {@link NilReason}, we still need to know if axes are reversed in order to put the nil reason * in the right location.</div> * * @param cv the conversion computed by {@link #getConversionFrom(VerticalCRS)} (may be {@code null}). * @param sample the minimum or the maximum value. * @param other the minimum or maximum value at the opposite bound. * @return {@code true} if the axis direction is reversed at the given value. */ private static boolean isReversing(final MathTransform1D cv, Double sample, final Double other) throws TransformException { if (cv == null) { return false; } if (sample == null || sample.isNaN()) { sample = other; } else if (other != null && !other.isNaN()) { sample = (sample + other) / 2; } return MathFunctions.isNegative(cv.derivative(sample != null ? sample : Double.NaN)); }