You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2018/08/06 16:53:52 UTC
[sis] branch geoapi-4.0 updated: Add a Units.converter(scale,
offset) method.
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 <ma...@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