Class LinearConverter

java.lang.Object
org.apache.sis.measure.AbstractConverter
org.apache.sis.measure.LinearConverter
All Implemented Interfaces:
Serializable, javax.measure.UnitConverter, LenientComparable

final class LinearConverter extends AbstractConverter implements LenientComparable
Conversions between units that can be represented by a linear operation (scale or offset). Note that the "linear" word in this class does not have the same meaning than the same word in the isLinear() method inherited from JSR-363.

Implementation note: for performance reason we should create specialized subtypes for the case where there is only a scale to apply, or only an offset, etc. But we don't do that in Apache SIS implementation because we will rarely use the UnitConverter for converting a lot of values. We rather use MathTransform for operations on n-dimensional tuples, and unit conversions are only a special case of those more generic operations. The sis-referencing module provided the specialized implementations needed for efficient operations and know how to copy the UnitConverter coefficients into an affine transform matrix.

Since:
0.8
Version:
1.0
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private final double
    A divisor applied after the conversion.
    The inverse of this unit converter.
    private final double
    The offset to apply after the scale, before division by divisor.
    private BigDecimal
    The scale and offset factors represented in base 10, computed when first needed.
    private final double
    The scale to apply for converting values, before division by divisor.
    private BigDecimal
    The scale and offset factors represented in base 10, computed when first needed.
    private static final long
    For cross-version compatibility.
  • Constructor Summary

    Constructors
    Constructor
    Description
    LinearConverter(double scale, double offset, double divisor)
    Creates a new linear converter for the given scale and offset.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) final boolean
    Returns true if this converter is close to an identity converter.
    (package private) final Number[]
    Returns the coefficient of this linear conversion.
    javax.measure.UnitConverter
    concatenate(javax.measure.UnitConverter converter)
    Concatenates this converter with another converter.
    double
    convert(double value)
    Applies the linear conversion on the given IEEE 754 floating-point value.
    convert(Number value)
    Applies the linear conversion on the given value.
    (package private) static AbstractConverter
    create(Number scale, Number offset)
    Creates a linear converter from the given scale and offset, which may be BigDecimal instances.
    double
    derivative(double value)
    Returns the derivative of the conversion at the given value.
    boolean
    equals(Object other)
    Compares this converter with the given object for equality.
    boolean
    Compares this converter with the given object for equality, optionally ignoring rounding errors.
    (package private) final boolean
    Returns true if the given converter perform the same conversion than this converter, except for rounding errors.
    int
    Returns a hash code value for this unit converter.
    javax.measure.UnitConverter
    Returns the inverse of this unit converter.
    boolean
    Returns true if the effective scale factor is 1 and the offset is zero.
    boolean
    Indicates if this converter is linear.
    (package private) static LinearConverter
    offset(double numerator, double denominator)
    Returns a converter for the given shift.
    (package private) static LinearConverter
    pow(javax.measure.UnitConverter converter, int n, boolean root)
    Raises the given converter to the given power.
    private static Number
    ratio(double value, double divisor)
    Returns the given ratio as a Fraction if possible, or as a Double otherwise.
    (package private) static LinearConverter
    scale(double numerator, double denominator)
    Returns a linear converter for the given ratio.
    Returns a string representation of this converter for debugging purpose.

    Methods inherited from class org.apache.sis.measure.AbstractConverter

    derivative, doubleValue, epsilonEquals, getConversionSteps, scale

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      For cross-version compatibility.
      See Also:
    • scale

      private final double scale
      The scale to apply for converting values, before division by divisor.
    • offset

      private final double offset
      The offset to apply after the scale, before division by divisor.
    • divisor

      private final double divisor
      A divisor applied after the conversion. The complete formula used by Apache SIS is y = (x*scale + offset) / divisor. This division is mathematically unneeded since we could divide the offset and scale factor directly, but we keep it for accuracy reasons because most unit conversion factors are defined in base 10 and IEEE 754 cannot represent fractional values in base 10 accurately.
    • scale10

      private transient volatile BigDecimal scale10
      The scale and offset factors represented in base 10, computed when first needed. Those terms are pre-divided by the divisor.
    • offset10

      private transient volatile BigDecimal offset10
      The scale and offset factors represented in base 10, computed when first needed. Those terms are pre-divided by the divisor.
    • inverse

      private transient volatile LinearConverter inverse
      The inverse of this unit converter. Computed when first needed.
  • Constructor Details

    • LinearConverter

      LinearConverter(double scale, double offset, double divisor)
      Creates a new linear converter for the given scale and offset. The complete formula applied is y = (x*scale + offset) / divisor.
  • Method Details

    • create

      static AbstractConverter create(Number scale, Number offset)
      Creates a linear converter from the given scale and offset, which may be BigDecimal instances. This is the implementation of public Units.converter(Number, Number) method.
    • scale

      static LinearConverter scale(double numerator, double denominator)
      Returns a linear converter for the given ratio. The scale factor is specified as a ratio because the unit conversion factors are often defined with a value in base 10. That value is considered exact by definition, but IEEE 754 has no exact representation of decimal fraction digits.

      It is caller's responsibility to skip this method call when numerator = denominator. This method does not perform this check because it is usually already done (indirectly) by the caller.

    • offset

      static LinearConverter offset(double numerator, double denominator)
      Returns a converter for the given shift. The translation is specified as a fraction because the unit conversion terms are often defined with a value in base 10. That value is considered exact by definition, but IEEE 754 has no exact representation of decimal fraction digits.

      It is caller's responsibility to skip this method call when numerator = 0. This method does not perform this check because it is usually already done by the caller.

    • pow

      static LinearConverter pow(javax.measure.UnitConverter converter, int n, boolean root)
      Raises the given converter to the given power. This method assumes that the given converter is linear (this is not verified) and takes only the scale factor; the offset (if any) is ignored.

      It is caller's responsibility to skip this method call when n = 1. This method does not perform this check because it is usually already done (indirectly) by the caller.

      Parameters:
      converter - the converter to raise to the given power.
      n - the exponent.
      root - true for raising to 1/n instead of n.
      Returns:
      the converter raised to the given power.
    • isLinear

      public boolean isLinear()
      Indicates if this converter is linear. JSR-363 defines a converter as linear if:
      • convert(u + v) == convert(u) + convert(v)
      • convert(r * u) == r * convert(u)
      Note that this definition allows scale factors but does not allow offsets. Consequently, this is a different definition of "linear" than this class and the rest of Apache SIS.
      Specified by:
      isLinear in interface javax.measure.UnitConverter
      Overrides:
      isLinear in class AbstractConverter
    • isIdentity

      public boolean isIdentity()
      Returns true if the effective scale factor is 1 and the offset is zero.
      Specified by:
      isIdentity in interface javax.measure.UnitConverter
      Overrides:
      isIdentity in class AbstractConverter
    • almostIdentity

      final boolean almostIdentity()
      Returns true if this converter is close to an identity converter.
    • inverse

      public javax.measure.UnitConverter inverse()
      Returns the inverse of this unit converter. Given that the formula applied by this converter is: the inverse formula is:
      Specified by:
      inverse in interface javax.measure.UnitConverter
    • coefficients

      final Number[] coefficients()
      Returns the coefficient of this linear conversion.
      Overrides:
      coefficients in class AbstractConverter
    • ratio

      private static Number ratio(double value, double divisor)
      Returns the given ratio as a Fraction if possible, or as a Double otherwise. The use of Fraction allows the org.apache.sis.referencing.operation.matrix package to perform more accurate calculations.
    • convert

      public double convert(double value)
      Applies the linear conversion on the given IEEE 754 floating-point value.
      Specified by:
      convert in interface javax.measure.UnitConverter
    • convert

      public Number convert(Number value)
      Applies the linear conversion on the given value. This method uses BigDecimal arithmetic if the given value is an instance of BigDecimal, or IEEE 754 floating-point arithmetic otherwise.

      Apache SIS rarely uses BigDecimal arithmetic, so providing an efficient implementation of this method is not a goal.

      Specified by:
      convert in interface javax.measure.UnitConverter
      Overrides:
      convert in class AbstractConverter
    • derivative

      public double derivative(double value)
      Returns the derivative of the conversion at the given value. For a linear converter, the derivative is the same everywhere.
      Specified by:
      derivative in class AbstractConverter
      Parameters:
      value - the point at which to compute the derivative. Ignored (can be Double.NaN) if the conversion is linear.
    • concatenate

      public javax.measure.UnitConverter concatenate(javax.measure.UnitConverter converter)
      Concatenates this converter with another converter. The resulting converter is equivalent to first converting by the specified converter (right converter), and then converting by this converter (left converter). In the following equations, the 1 subscript is for the specified converter and the 2 subscript is for this converter: We rewrite as:
      Specified by:
      concatenate in interface javax.measure.UnitConverter
      Overrides:
      concatenate in class AbstractConverter
    • hashCode

      public int hashCode()
      Returns a hash code value for this unit converter.
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object other)
      Compares this converter with the given object for equality.
      Specified by:
      equals in interface LenientComparable
      Overrides:
      equals in class Object
      Parameters:
      other - the object to compare to this.
      Returns:
      true if both objects are strictly equal.
      See Also:
    • equals

      public boolean equals(Object other, ComparisonMode mode)
      Compares this converter with the given object for equality, optionally ignoring rounding errors.
      Specified by:
      equals in interface LenientComparable
      Parameters:
      other - the object to compare to this.
      mode - the strictness level of the comparison.
      Returns:
      true if both objects are equal according the given comparison mode.
      See Also:
    • equivalent

      final boolean equivalent(LinearConverter other)
      Returns true if the given converter perform the same conversion than this converter, except for rounding errors.
    • toString

      public String toString()
      Returns a string representation of this converter for debugging purpose. This string representation may change in any future SIS release. Current format is of the form "y = scaleā‹…x + offset".
      Overrides:
      toString in class Object