sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Add a Units.converter(scale, offset) method.
Date Mon, 06 Aug 2018 16:53:52 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 4c685b5  Add a Units.converter(scale, offset) method.
4c685b5 is described below

commit 4c685b550d04354050a5934e7486b2e1b64f21f0
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Mon Aug 6 18:53:16 2018 +0200

    Add a Units.converter(scale, offset) method.
---
 .../operation/transform/MathTransforms.java        |  4 ++-
 .../java/org/apache/sis/measure/AbstractUnit.java  |  3 ++
 .../org/apache/sis/measure/LinearConverter.java    | 34 ++++++++++++++++++++--
 .../main/java/org/apache/sis/measure/Units.java    | 15 ++++++++++
 .../apache/sis/measure/LinearConverterTest.java    | 10 +++++++
 5 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
index c62765d..8322ba6 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
@@ -93,6 +93,8 @@ public final class MathTransforms extends Static {
      * @param  scale   the {@code scale}  term in the linear equation.
      * @param  offset  the {@code offset} term in the linear equation.
      * @return the linear transform for the given scale and offset.
+     *
+     * @see org.apache.sis.measure.Units#converter(Number, Number)
      */
     public static LinearTransform linear(final double scale, final double offset) {
         return LinearTransform1D.create(scale, offset);
@@ -154,7 +156,7 @@ public final class MathTransforms extends Static {
      * Both {@code preimage} (the <var>x</var>) and {@code values} (the <var>y</var>)
arguments can be null:
      *
      * <ul>
-     *   <li>If both {@code preimage} and {@code values} arrays are non-null, then
the must have the same length.</li>
+     *   <li>If both {@code preimage} and {@code values} arrays are non-null, then
they must have the same length.</li>
      *   <li>If both {@code preimage} and {@code values} arrays are null, then this
method returns the identity transform.</li>
      *   <li>If only {@code preimage} is null, then the <var>x</var> values
are taken as {0, 1, 2, …, {@code values.length} - 1}.</li>
      *   <li>If only {@code values} is null, then the <var>y</var> values
are taken as {0, 1, 2, …, {@code preimage.length} - 1}.</li>
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
index 66b7530..6e4783d 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/AbstractUnit.java
@@ -241,6 +241,7 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements
Unit<Q>, LenientCo
      */
     @Override
     public final Unit<Q> shift(final double offset) {
+        if (offset == 0) return this;
         return transform(LinearConverter.offset(offset, 1));
     }
 
@@ -253,6 +254,7 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements
Unit<Q>, LenientCo
      */
     @Override
     public final Unit<Q> multiply(double multiplier) {
+        if (multiplier == 1) return this;
         final double divisor = inverse(multiplier);
         if (divisor != 1) multiplier = 1;
         return transform(LinearConverter.scale(multiplier, divisor));
@@ -267,6 +269,7 @@ abstract class AbstractUnit<Q extends Quantity<Q>> implements
Unit<Q>, LenientCo
      */
     @Override
     public final Unit<Q> divide(double divisor) {
+        if (divisor == 1) return this;
         final double multiplier = inverse(divisor);
         if (multiplier != 1) divisor = 1;
         return transform(LinearConverter.scale(multiplier, divisor));
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java b/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java
index 1277864..42fb5b0 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/LinearConverter.java
@@ -100,12 +100,31 @@ final class LinearConverter extends AbstractConverter implements LenientComparab
     }
 
     /**
+     * Creates a linear converter from the given scale and offset, which may be {@link BigDecimal}
instances.
+     * This is the implementation of public {@link Units#converter(Number, Number)} method.
+     */
+    static LinearConverter create(final Number scale, final Number offset) {
+        final double numerator, divisor;
+        double shift = (offset != null) ? offset.doubleValue() : 0;
+        if (scale instanceof Fraction) {
+            numerator = ((Fraction) scale).numerator;
+            divisor   = ((Fraction) scale).denominator;
+            shift    *= divisor;
+        } else {
+            numerator = (scale != null) ? scale.doubleValue() : 1;
+            divisor   = 1;
+        }
+        final LinearConverter c = create(numerator, shift, divisor);
+        if (scale  instanceof BigDecimal) c.scale10  = (BigDecimal) scale;
+        if (offset instanceof BigDecimal) c.offset10 = (BigDecimal) offset;
+        return c;
+    }
+
+    /**
      * Returns a linear converter for the given scale and offset.
      */
     private static LinearConverter create(final double scale, final double offset, final
double divisor) {
-        if (offset == 0) {
-            if (scale == divisor) return IDENTITY;
-        }
+        if (offset == 0 && scale == divisor) return IDENTITY;
         return new LinearConverter(scale, offset, divisor);
     }
 
@@ -113,6 +132,9 @@ final class LinearConverter extends AbstractConverter implements LenientComparab
      * 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.
+     *
+     * <p>It is caller's responsibility to skip this method call when {@code numerator}
= {@code denominator}.
+     * This method does not perform this check because it is usually already done (indirectly)
by the caller.</p>
      */
     static LinearConverter scale(final double numerator, final double denominator) {
         return new LinearConverter(numerator, 0, denominator);
@@ -122,6 +144,9 @@ final class LinearConverter extends AbstractConverter implements LenientComparab
      * 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.
+     *
+     * <p>It is caller's responsibility to skip this method call when {@code numerator}
= 0.
+     * This method does not perform this check because it is usually already done by the
caller.</p>
      */
     static LinearConverter offset(final double numerator, final double denominator) {
         return new LinearConverter(denominator, numerator, denominator);
@@ -132,6 +157,9 @@ final class LinearConverter extends AbstractConverter implements LenientComparab
      * {@linkplain #isLinear() is linear} (this is not verified) and takes only the scale
factor;
      * the offset (if any) is ignored.
      *
+     * <p>It is caller's responsibility to skip this method call when {@code n} = 1.
+     * This method does not perform this check because it is usually already done (indirectly)
by the caller.</p>
+     *
      * @param  converter  the converter to raise to the given power.
      * @param  n          the exponent.
      * @param  root       {@code true} for raising to 1/n instead of n.
diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
index 1b7335d..8822a43 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
@@ -1503,6 +1503,21 @@ public final class Units extends Static {
     }
 
     /**
+     * Creates a linear converter from the given scale and offset.
+     *
+     * @param  scale   the scale factor, or {@code null} if none.
+     * @param  offset  the offset, or {@code null} if none.
+     * @return a converter for the given scale and offset.
+     *
+     * @see org.apache.sis.referencing.operation.transform.MathTransforms#linear(double,
double)
+     *
+     * @since 1.0
+     */
+    public static UnitConverter converter(final Number scale, final Number offset) {
+        return LinearConverter.create(scale, offset);
+    }
+
+    /**
      * Returns the coefficients of the given converter expressed as a polynomial equation.
      * This method returns the first of the following choices that apply:
      *
diff --git a/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java
b/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java
index d25e8d5..c4b3ca0 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/measure/LinearConverterTest.java
@@ -59,6 +59,16 @@ public final strictfp class LinearConverterTest extends TestCase {
     }
 
     /**
+     * Tests {@link LinearConverter#create(Number, Number)}.
+     */
+    @Test
+    public void testCreate() {
+        assertTrue(LinearConverter.create(null, null).isIdentity());
+        assertScale(3, 1, LinearConverter.create(3, 0));
+        assertScale(3, 2, LinearConverter.create(new Fraction(3, 2), null));
+    }
+
+    /**
      * Tests {@link LinearConverter#pow(UnitConverter, int, boolean)}.
      */
     @Test


Mime
View raw message