Author: desruisseaux
Date: Tue Jun 24 14:30:54 2014
New Revision: 1605093
URL: http://svn.apache.org/r1605093
Log:
Simplify LogarithmicTransform1D by removing the explicit support of arbitrary
logarithm bases. Instead, for the rare
cases where someone wants a base other than e or 10, we concatenate the natural
logarithm with a linear transform.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java?rev=1605093&r1=1605092&r2=1605093&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
[UTF-8] Tue Jun 24 14:30:54 2014
@@ -62,7 +62,7 @@ final class ExponentialTransform1D exten
/**
* The base to be raised to a power.
*/
- protected final double base;
+ final double base;
/**
* Natural logarithm of {@link #base}, used for {@link
#derivative(double)} computation.
@@ -77,7 +77,7 @@ final class ExponentialTransform1D exten
* is extensively used as a <cite>transfer function</cite> in grid
coverages. Consequently we keep this explicit
* field for performance reasons.</div>
*/
- protected final double scale;
+ final double scale;
/**
* The inverse of this transform. Created only when first needed.
Serialized in order to avoid
@@ -89,9 +89,9 @@ final class ExponentialTransform1D exten
* Constructs a new exponential transform which is the inverse of the
supplied logarithmic transform.
*/
ExponentialTransform1D(final LogarithmicTransform1D inverse) {
- this.base = inverse.base;
- this.lnBase = inverse.lnBase;
- this.scale = Math.pow(base, -inverse.offset);
+ this.base = inverse.getBase();
+ this.lnBase = inverse.getLogBase();
+ this.scale = Math.pow(base, -inverse.getOffset());
this.inverse = inverse;
}
@@ -257,17 +257,17 @@ final class ExponentialTransform1D exten
final MathTransform concatenateLog(final LogarithmicTransform1D other,
final boolean applyOtherFirst) {
if (applyOtherFirst) {
return MathTransforms.concatenate(
- PowerTransform1D.create(lnBase / other.lnBase),
- LinearTransform1D.create(scale * Math.pow(base,
other.offset), 0));
+ PowerTransform1D.create(lnBase / other.getLogBase()),
+ LinearTransform1D.create(scale * Math.pow(base,
other.getOffset()), 0));
} else {
- final double newScale = lnBase / other.lnBase;
+ final double newScale = lnBase / other.getLogBase();
final double newOffset;
if (scale > 0) {
- newOffset = other.log(scale) + other.offset;
+ newOffset = other.log(scale) + other.getOffset();
} else {
// Maybe the Math.log(...) argument will become
// positive if we rewrite the equation that way...
- newOffset = other.log(scale * other.offset * other.lnBase);
+ newOffset = other.log(scale * other.getOffset() *
other.getLogBase());
}
if (!Double.isNaN(newOffset)) {
return LinearTransform1D.create(newScale, newOffset);
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java?rev=1605093&r1=1605092&r2=1605093&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
[UTF-8] Tue Jun 24 14:30:54 2014
@@ -26,12 +26,13 @@ import org.apache.sis.util.ComparisonMod
/**
* A one dimensional, logarithmic transform. This transform is the inverse of
{@link ExponentialTransform1D}.
- * Input values <var>x</var> are converted into output values <var>y</var>
using the following equation:
+ * The default implementation computes the natural logarithm of input values
using {@link Math#log(double)}.
+ * Subclasses compute alternate logarithms, for example in base 10 computed by
{@link Math#log10(double)}.
*
- * <blockquote><table class="compact" summary="y = offset + log(x)">
- * <tr><td><var>y</var></td><td> = </td><td>{@linkplain #offset} +
log<sub>{@linkplain #base}</sub>(<var>x</var>)</td></tr>
- * <tr><td> </td><td> = </td><td>{@linkplain #offset} +
ln(<var>x</var>) / ln({@linkplain #base})</td></tr>
- * </table></blockquote>
+ * <p>Logarithms in bases other than <var>e</var> or 10 are computed by
concatenating a linear transform,
+ * using the following mathematical identity:</p>
+ *
+ * <blockquote> log<sub>base</sub>(<var>x</var>) = ln(<var>x</var>) /
ln(base) </blockquote>
*
* {@section Serialization}
* Serialized instances of this class are not guaranteed to be compatible with
future SIS versions.
@@ -50,24 +51,9 @@ class LogarithmicTransform1D extends Abs
private static final long serialVersionUID = 1535101265352133948L;
/**
- * The logarithm base.
- */
- protected final double base;
-
- /**
- * Natural logarithm of {@link #base}, used for {@link
#derivative(double)} computation.
- */
- final double lnBase;
-
- /**
- * The offset to add to the logarithm.
- *
- * <span class="note"><b>Note:</b> the offset could be handled by a
concatenation with {@link LinearTransform1D}.
- * instead than an explicit field in this class. However the
<var>offset</var> + log<sub>base</sub>(<var>x</var>)
- * formula is extensively used as a <cite>transfer function</cite> in grid
coverages. Consequently we keep this
- * explicit field for performance reasons.</span>
+ * The unique instance of the natural logarithmic transform.
*/
- protected final double offset;
+ private static final LogarithmicTransform1D NATURAL = new
LogarithmicTransform1D();
/**
* The inverse of this transform. Created only when first needed.
Serialized in order to avoid
@@ -76,62 +62,78 @@ class LogarithmicTransform1D extends Abs
private MathTransform1D inverse;
/**
- * Constructs a new logarithmic transform which is the
- * inverse of the supplied exponential transform.
+ * Constructs a new logarithmic transform.
*
- * @see #create(ExponentialTransform1D)
+ * @see #create(double, double)
*/
- private LogarithmicTransform1D(final ExponentialTransform1D inverse) {
- this.base = inverse.base;
- this.lnBase = inverse.lnBase;
- this.offset = -Math.log(inverse.scale) / lnBase;
- this.inverse = inverse;
+ LogarithmicTransform1D() {
}
/**
- * Constructs a new logarithmic transform. This constructor is provided
for subclasses only.
- * Instances should be created using the {@linkplain #create(double,
double) factory method},
- * which may return optimized implementations for some particular argument
values.
- *
- * @param base The base of the logarithm (typically 10).
- * @param offset The offset to add to the logarithm.
- */
- protected LogarithmicTransform1D(final double base, final double offset) {
- ArgumentChecks.ensureStrictlyPositive("base", base);
- this.base = base;
- this.offset = offset;
- this.lnBase = Math.log(base);
- }
-
- /**
- * Constructs a new logarithmic transform which include the given offset
after the logarithm.
+ * Constructs a new logarithmic transform which add the given offset after
the logarithm.
*
* @param base The base of the logarithm (typically 10).
* @param offset The offset to add to the logarithm.
* @return The math transform.
*/
public static MathTransform1D create(final double base, final double
offset) {
+ ArgumentChecks.ensureStrictlyPositive("base", base);
if (base == 10) {
- return (offset == 0) ? Base10.INSTANCE : new Base10(offset);
+ return Base10.create(offset);
}
- if (base == 0 || base == Double.POSITIVE_INFINITY) {
- /*
- * offset + ln(x) / ln(0) = offset + ln(x) / -∞ = offset +
-0 for 0 < x < ∞
- * offset + ln(x) / ln(∞) = offset + ln(x) / +∞ = offset +
0 for 0 < x < ∞
- */
- return LinearTransform1D.create(0, offset);
- }
- return new LogarithmicTransform1D(base, offset);
+ return NATURAL.concatenate(1 / Math.log(base), offset);
}
/**
* Constructs a new logarithmic transform which is the inverse of the
supplied exponential transform.
*/
- static LogarithmicTransform1D create(final ExponentialTransform1D inverse)
{
+ static MathTransform1D create(final ExponentialTransform1D inverse) {
if (inverse.base == 10) {
- return new Base10(inverse);
+ return Base10.create(-Math.log10(inverse.scale));
+ } else {
+ return NATURAL.concatenate(1 / inverse.lnBase,
-Math.log(inverse.scale) / inverse.lnBase);
}
- return new LogarithmicTransform1D(inverse);
+ }
+
+ /**
+ * Returns the concatenation of this transform by the given scale and
offset.
+ * This method does not check if a simplification is possible.
+ */
+ private MathTransform1D concatenate(final double scale, final double
offset) {
+ final LinearTransform1D t = LinearTransform1D.create(scale, offset);
+ return t.isIdentity() ? this : new ConcatenatedTransformDirect1D(this,
t);
+ }
+
+ /**
+ * Concatenates in an optimized way a {@link MathTransform} {@code other}
to this
+ * {@code MathTransform}. This implementation can optimize some
concatenation with
+ * {@link LinearTransform1D} and {@link ExponentialTransform1D}.
+ *
+ * @param other The math transform to apply.
+ * @param applyOtherFirst {@code true} if the transformation order is
{@code other}
+ * followed by {@code this}, or {@code false} if the
transformation order is
+ * {@code this} followed by {@code other}.
+ * @return The combined math transform, or {@code null} if no optimized
combined
+ * transform is available.
+ */
+ @Override
+ final MathTransform concatenate(final MathTransform other, final boolean
applyOtherFirst) {
+ if (other instanceof LinearTransform1D) {
+ final LinearTransform1D linear = (LinearTransform1D) other;
+ if (applyOtherFirst) {
+ if (linear.offset == 0 && linear.scale > 0) {
+ return create(getBase(), Math.log(linear.scale) /
getLogBase() + getOffset());
+ }
+ } else {
+ final double newBase = Math.pow(getBase(), 1 / linear.scale);
+ if (!Double.isNaN(newBase)) {
+ return create(newBase, linear.scale * getOffset() +
linear.offset);
+ }
+ }
+ } else if (other instanceof ExponentialTransform1D) {
+ return ((ExponentialTransform1D) other).concatenateLog(this,
!applyOtherFirst);
+ }
+ return super.concatenate(other, applyOtherFirst);
}
/**
@@ -147,11 +149,33 @@ class LogarithmicTransform1D extends Abs
}
/**
+ * Returns the base of this logarithmic function.
+ */
+ double getBase() {
+ return Math.E;
+ }
+
+ /**
+ * Returns the natural logarithm of the base of this logarithmic function.
+ * More specifically, returns <code>{@linkplain Math#log(double)
Math.log}({@linkplain #getBase()})</code>.
+ */
+ double getLogBase() {
+ return 1;
+ }
+
+ /**
+ * Returns the offset applied after this logarithmic function.
+ */
+ double getOffset() {
+ return 0;
+ }
+
+ /**
* Gets the derivative of this function at a value.
*/
@Override
public double derivative(final double value) {
- return 1 / (lnBase * value);
+ return 1 / value;
}
/**
@@ -162,7 +186,7 @@ class LogarithmicTransform1D extends Abs
* @return The log of the given value in the base used by this transform.
*/
double log(final double value) {
- return Math.log(value) / lnBase;
+ return Math.log(value);
}
/**
@@ -170,7 +194,7 @@ class LogarithmicTransform1D extends Abs
*/
@Override
public double transform(final double value) {
- return Math.log(value) / lnBase + offset;
+ return Math.log(value);
}
/**
@@ -180,13 +204,13 @@ class LogarithmicTransform1D extends Abs
public void transform(final double[] srcPts, int srcOff, final double[]
dstPts, int dstOff, int numPts) {
if (srcPts != dstPts || srcOff >= dstOff) {
while (--numPts >= 0) {
- dstPts[dstOff++] = Math.log(srcPts[srcOff++]) / lnBase +
offset;
+ dstPts[dstOff++] = Math.log(srcPts[srcOff++]);
}
} else {
srcOff += numPts;
dstOff += numPts;
while (--numPts >= 0) {
- dstPts[--dstOff] = Math.log(srcPts[--srcOff]) / lnBase +
offset;
+ dstPts[--dstOff] = Math.log(srcPts[--srcOff]);
}
}
}
@@ -198,13 +222,13 @@ class LogarithmicTransform1D extends Abs
public void transform(final float[] srcPts, int srcOff, final float[]
dstPts, int dstOff, int numPts) {
if (srcPts != dstPts || srcOff >= dstOff) {
while (--numPts >= 0) {
- dstPts[dstOff++] = (float) (Math.log(srcPts[srcOff++]) /
lnBase + offset);
+ dstPts[dstOff++] = (float) Math.log(srcPts[srcOff++]);
}
} else {
srcOff += numPts;
dstOff += numPts;
while (--numPts >= 0) {
- dstPts[--dstOff] = (float) (Math.log(srcPts[--srcOff]) /
lnBase + offset);
+ dstPts[--dstOff] = (float) Math.log(srcPts[--srcOff]);
}
}
}
@@ -215,7 +239,7 @@ class LogarithmicTransform1D extends Abs
@Override
public void transform(final double[] srcPts, int srcOff, final float[]
dstPts, int dstOff, int numPts) {
while (--numPts >= 0) {
- dstPts[dstOff++] = (float) (Math.log(srcPts[srcOff++]) / lnBase +
offset);
+ dstPts[dstOff++] = (float) Math.log(srcPts[srcOff++]);
}
}
@@ -225,28 +249,77 @@ class LogarithmicTransform1D extends Abs
@Override
public void transform(final float[] srcPts, int srcOff, final double[]
dstPts, int dstOff, int numPts) {
while (--numPts >= 0) {
- dstPts[dstOff++] = Math.log(srcPts[srcOff++]) / lnBase + offset;
+ dstPts[dstOff++] = Math.log(srcPts[srcOff++]);
}
}
/**
* Special case for base 10 taking advantage of extra precision provided
by {@link Math#log10(double)}.
*/
- private static final class Base10 extends LogarithmicTransform1D {
- /** For cross-version compatibility. */
+ static final class Base10 extends LogarithmicTransform1D {
+ /**
+ * For cross-version compatibility.
+ */
private static final long serialVersionUID = -5435804027536647558L;
- /** Commonly used instance. */
- static LogarithmicTransform1D INSTANCE = new Base10(0);
+ /**
+ * The natural logarithm of 10.
+ */
+ private static final double LOG_10 = 2.302585092994045684;
+
+ /**
+ * Commonly used instance with no offset.
+ */
+ static final Base10 INSTANCE = new Base10(0);
+
+ /**
+ * The offset to add to the logarithm.
+ *
+ * <span class="note"><b>Note:</b> the offset could be handled by a
concatenation with {@link LinearTransform1D}.
+ * instead than an explicit field in this class. However the
<var>offset</var> + log<sub>base</sub>(<var>x</var>)
+ * formula is extensively used as a <cite>transfer function</cite> in
grid coverages. Consequently we keep this
+ * explicit field for performance reasons.</span>
+ */
+ private final double offset;
+
+ /**
+ * Creates a new instance with the given offset.
+ *
+ * @see #create(double)
+ */
+ private Base10(final double offset) {
+ this.offset = offset;
+ }
+
+ /**
+ * Creates a new instance with the given offset.
+ */
+ public static Base10 create(final double offset) {
+ return (offset == 0) ? INSTANCE : new Base10(offset);
+ }
- /** Constructs the inverse of the supplied exponential transform. */
- Base10(final ExponentialTransform1D inverse) {
- super(inverse);
+ /** {@inheritDoc} */
+ @Override
+ double getBase() {
+ return 10;
}
- /** Creates a new instance with the given offset. */
- protected Base10(final double offset) {
- super(10, offset);
+ /** {@inheritDoc} */
+ @Override
+ double getLogBase() {
+ return LOG_10;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ double getOffset() {
+ return offset;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public double derivative(final double value) {
+ return (1 / LOG_10) / value;
}
/** {@inheritDoc} */
@@ -308,62 +381,23 @@ class LogarithmicTransform1D extends Abs
dstPts[dstOff++] = Math.log10(srcPts[srcOff++]) + offset;
}
}
- }
- /**
- * Concatenates in an optimized way a {@link MathTransform} {@code other}
to this
- * {@code MathTransform}. This implementation can optimize some
concatenation with
- * {@link LinearTransform1D} and {@link ExponentialTransform1D}.
- *
- * @param other The math transform to apply.
- * @param applyOtherFirst {@code true} if the transformation order is
{@code other}
- * followed by {@code this}, or {@code false} if the
transformation order is
- * {@code this} followed by {@code other}.
- * @return The combined math transform, or {@code null} if no optimized
combined
- * transform is available.
- */
- @Override
- final MathTransform concatenate(final MathTransform other, final boolean
applyOtherFirst) {
- if (other instanceof LinearTransform) {
- final LinearTransform1D linear = (LinearTransform1D) other;
- if (applyOtherFirst) {
- if (linear.offset == 0 && linear.scale > 0) {
- return create(base, Math.log(linear.scale) / lnBase +
offset);
- }
- } else {
- final double newBase = Math.pow(base, 1 / linear.scale);
- if (!Double.isNaN(newBase)) {
- return create(newBase, linear.scale * offset +
linear.offset);
- }
- }
- } else if (other instanceof ExponentialTransform1D) {
- return ((ExponentialTransform1D) other).concatenateLog(this,
!applyOtherFirst);
+ /** {@inheritDoc} */
+ @Override
+ protected int computeHashCode() {
+ return Numerics.hashCode(Double.doubleToLongBits(offset)) ^
super.computeHashCode();
}
- return super.concatenate(other, applyOtherFirst);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int computeHashCode() {
- return Numerics.hashCode(Double.doubleToLongBits(base) +
- 31 * Double.doubleToLongBits(offset)) ^
super.computeHashCode();
- }
- /**
- * Compares the specified object with this math transform for equality.
- */
- @Override
- public boolean equals(final Object object, final ComparisonMode mode) {
- if (object == this) {
- return true; // Optimization for a common case.
- }
- if (super.equals(object, mode)) {
- final LogarithmicTransform1D that = (LogarithmicTransform1D)
object;
- return Numerics.equals(this.base, that.base) &&
- Numerics.equals(this.offset, that.offset);
+ /** Compares the specified object with this math transform for
equality. */
+ @Override
+ public boolean equals(final Object object, final ComparisonMode mode) {
+ if (object == this) {
+ return true; // Optimization for a common case.
+ }
+ if (super.equals(object, mode)) {
+ return Numerics.equals(offset, ((Base10) object).offset);
+ }
+ return false;
}
- return false;
}
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java?rev=1605093&r1=1605092&r2=1605093&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
[UTF-8] Tue Jun 24 14:30:54 2014
@@ -246,11 +246,31 @@ public class TransferFunction implements
} else if (function instanceof LogarithmicTransform1D) {
final LogarithmicTransform1D f = (LogarithmicTransform1D) function;
type = TransferFunctionType.LOGARITHMIC;
- base = f.base;
- offset = f.offset;
+ base = f.getBase();
+ offset = f.getOffset();
scale = 1;
} else {
- throw new
IllegalArgumentException(Errors.format(Errors.Keys.UnknownType_1,
function.getClass()));
+ /*
+ * If we did not recognized one of the known types, maybe the
given function
+ * is the result of some concatenation. Try to concatenate a
logarithmic or
+ * exponential transform and see if the result is linear.
+ */
+ final LogarithmicTransform1D log =
LogarithmicTransform1D.Base10.INSTANCE;
+ MathTransform1D f = MathTransforms.concatenate(function, log);
+ if (f instanceof LinearTransform) {
+ setLinearTerms((LinearTransform) f);
+ type = TransferFunctionType.EXPONENTIAL;
+ base = 10;
+ } else {
+ f = MathTransforms.concatenate(log.inverse(), function);
+ if (f instanceof LinearTransform) {
+ setLinearTerms((LinearTransform) f);
+ type = TransferFunctionType.LOGARITHMIC;
+ base = 10;
+ } else {
+ throw new
IllegalArgumentException(Errors.format(Errors.Keys.UnknownType_1,
function.getClass()));
+ }
+ }
}
transform = function;
}
@@ -287,7 +307,7 @@ public class TransferFunction implements
if (scale == -1) {
b.append('−');
} else {
- StringBuilders.trimFractionalPart(b.append(scale).append('∙'));
+ StringBuilders.trimFractionalPart(b.append(scale).append('⋅'));
}
}
if (TransferFunctionType.LINEAR.equals(type)) {
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java?rev=1605093&r1=1605092&r2=1605093&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
[UTF-8] Tue Jun 24 14:30:54 2014
@@ -56,7 +56,7 @@ public final class TransferFunctionTest
f.setScale(0.15);
f.setOffset(-2);
- assertEquals("toString", "y = 0.15∙x − 2", f.toString());
+ assertEquals("toString", "y = 0.15⋅x − 2", f.toString());
final MathTransform1D transform = f.getTransform();
assertInstanceOf("transform", LinearTransform.class, transform);
assertMatrixEquals("transform.matrix", new Matrix2(0.15, -2, 0, 1),
@@ -106,7 +106,7 @@ public final class TransferFunctionTest
f.setType(TransferFunctionType.EXPONENTIAL);
f.setScale(0.15);
assertEquals("base", 10, f.getBase(), STRICT);
- assertEquals("toString", "y = 0.15∙10ˣ", f.toString());
+ assertEquals("toString", "y = 0.15⋅10ˣ", f.toString());
final MathTransform1D transform = f.getTransform();
assertInstanceOf("transform", ExponentialTransform1D.class, transform);
/*
@@ -119,4 +119,28 @@ public final class TransferFunctionTest
assertEquals("scale", 0.15, b.getScale(), STRICT);
assertEquals("offset", 0, b.getOffset(), STRICT);
}
+
+ /**
+ * Tests the creation of a concatenated transfer function.
+ */
+ @Test
+ @DependsOnMethod("testLogarithmic")
+ public void testConcatenated() {
+ final TransferFunction f = new TransferFunction();
+ f.setType(TransferFunctionType.LOGARITHMIC);
+ f.setScale(0.15);
+ f.setOffset(-2);
+ assertEquals("toString", "y = 0.15⋅㏒⒳ − 2", f.toString());
+ final MathTransform1D transform = f.getTransform();
+ assertInstanceOf("transform", ConcatenatedTransformDirect1D.class,
transform);
+ /*
+ * Get back the coefficients.
+ */
+ final TransferFunction b = new TransferFunction();
+ b.setTransform(transform);
+ assertEquals("type", TransferFunctionType.LOGARITHMIC, b.getType());
+ assertEquals("base", 10, b.getBase(), STRICT);
+ assertEquals("scale", 0.15, b.getScale(), 1E-16);
+ assertEquals("offset", -2, b.getOffset(), 1E-16);
+ }
}