Author: celestin
Date: Mon Dec 12 07:19:23 2011
New Revision: 1213157
URL: http://svn.apache.org/viewvc?rev=1213157&view=rev
Log:
In transform.FastSineTransformer, replaced the pair transform2() /
inverseTransform2() with two factory methods: create() and createOrthogonal()
(MATH-677).
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastSineTransformerTest.java
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java?rev=1213157&r1=1213156&r2=1213157&view=diff
==============================================================================
---
commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java
(original)
+++
commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java
Mon Dec 12 07:19:23 2011
@@ -40,162 +40,138 @@ import org.apache.commons.math.util.Fast
* @since 1.2
*/
public class FastSineTransformer implements RealTransformer {
-
- /** Construct a default transformer. */
- public FastSineTransformer() {
- super();
- }
-
/**
- * Transform the given real data set.
- * <p>
- * The formula is F<sub>n</sub> = ∑<sub>k=0</sub><sup>N-1</sup>
f<sub>k</sub> sin(π nk/N)
- * </p>
+ * {@code true} if the orthogonal version of the DCT should be used.
*
- * @param f the real data array to be transformed
- * @return the real transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * @see #create()
+ * @see #createOrthogonal()
*/
- public double[] transform(double[] f)
- throws IllegalArgumentException {
- return fst(f);
- }
+ private final boolean orthogonal;
/**
- * Transform the given real function, sampled on the given interval.
- * <p>
- * The formula is F<sub>n</sub> = ∑<sub>k=0</sub><sup>N-1</sup>
f<sub>k</sub> sin(π nk/N)
- * </p>
+ * Creates a new instance of this class, with various normalization
+ * conventions.
*
- * @param f the function to be sampled and transformed
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @param n the number of sample points
- * @return the real transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * @param orthogonal {@code false} if the DST is <em>not</em> to be scaled,
+ * {@code true} if it is to be scaled so as to make the transform
+ * orthogonal.
+ * @see #create()
+ * @see #createOrthogonal()
*/
- public double[] transform(UnivariateFunction f,
- double min, double max, int n)
- throws IllegalArgumentException {
-
- double[] data = FastFourierTransformer.sample(f, min, max, n);
- data[0] = 0.0;
- return fst(data);
+ private FastSineTransformer(final boolean orthogonal) {
+ this.orthogonal = orthogonal;
}
/**
- * Transform the given real data set.
* <p>
- * The formula is F<sub>n</sub> = √(2/N)
∑<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(π nk/N)
+ * Returns a new instance of this class. The returned transformer uses the
+ * normalizing conventions described below.
+ * <ul>
+ * <li>Forward transform:
+ * y<sub>n</sub> = ∑<sub>k=0</sub><sup>N-1</sup>
+ * x<sub>k</sub> sin(π nk / N),</li>
+ * <li>Inverse transform:
+ * x<sub>k</sub> = (2 / N) ∑<sub>n=0</sub><sup>N-1</sup>
+ * y<sub>n</sub> sin(π nk / N),</li>
+ * </ul>
+ * where N is the size of the data sample.
* </p>
*
- * @param f the real data array to be transformed
- * @return the real transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * @return a new DST transformer, with "standard" normalizing conventions
*/
- public double[] transform2(double[] f) throws IllegalArgumentException {
-
- double scalingCoefficient = FastMath.sqrt(2.0 / f.length);
- return FastFourierTransformer.scaleArray(fst(f), scalingCoefficient);
+ public static FastSineTransformer create() {
+ return new FastSineTransformer(false);
}
/**
- * Transform the given real function, sampled on the given interval.
* <p>
- * The formula is F<sub>n</sub> = √(2/N)
∑<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(π nk/N)
+ * Returns a new instance of this class. The returned transformer uses the
+ * normalizing conventions described below.
+ * <ul>
+ * <li>Forward transform:
+ * y<sub>n</sub> = √(2 / N) ∑<sub>k=0</sub><sup>N-1</sup>
+ * x<sub>k</sub> sin(π nk / N),</li>
+ * <li>Inverse transform:
+ * x<sub>k</sub> = √(2 / N) ∑<sub>n=0</sub><sup>N-1</sup>
+ * y<sub>n</sub> sin(π nk / N),</li>
+ * </ul>
+ * which make the transform orthogonal. N is the size of the data sample.
* </p>
*
- * @param f the function to be sampled and transformed
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @param n the number of sample points
- * @return the real transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * @return a new DST transformer, with "orthogonal" normalizing conventions
*/
- public double[] transform2(
- UnivariateFunction f, double min, double max, int n)
- throws IllegalArgumentException {
-
- double[] data = FastFourierTransformer.sample(f, min, max, n);
- data[0] = 0.0;
- double scalingCoefficient = FastMath.sqrt(2.0 / n);
- return FastFourierTransformer.scaleArray(fst(data),
scalingCoefficient);
+ public static FastSineTransformer createOrthogonal() {
+ return new FastSineTransformer(true);
}
/**
- * Inversely transform the given real data set.
- * <p>
- * The formula is f<sub>k</sub> = (2/N) ∑<sub>n=0</sub><sup>N-1</sup>
F<sub>n</sub> sin(π nk/N)
- * </p>
+ * {@inheritDoc}
*
- * @param f the real data array to be inversely transformed
- * @return the real inversely transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * The first element of the specified data set is required to be {@code 0}.
*/
- public double[] inverseTransform(double[] f) throws
IllegalArgumentException {
-
- double scalingCoefficient = 2.0 / f.length;
- return FastFourierTransformer.scaleArray(fst(f), scalingCoefficient);
+ public double[] transform(double[] f) throws IllegalArgumentException {
+ if (orthogonal){
+ final double s = FastMath.sqrt(2.0 / f.length);
+ return FastFourierTransformer.scaleArray(fst(f), s);
+ }
+ return fst(f);
}
/**
- * Inversely transform the given real function, sampled on the given
interval.
- * <p>
- * The formula is f<sub>k</sub> = (2/N) ∑<sub>n=0</sub><sup>N-1</sup>
F<sub>n</sub> sin(π nk/N)
- * </p>
+ * {@inheritDoc}
*
- * @param f the function to be sampled and inversely transformed
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @param n the number of sample points
- * @return the real inversely transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * This implementation enforces {@code f(x) = 0.0} at {@code x = 0.0}.
*/
- public double[] inverseTransform(UnivariateFunction f, double min, double
max, int n)
- throws IllegalArgumentException {
+ public double[] transform(UnivariateFunction f,
+ double min, double max, int n) throws IllegalArgumentException {
- double[] data = FastFourierTransformer.sample(f, min, max, n);
+ final double[] data = FastFourierTransformer.sample(f, min, max, n);
data[0] = 0.0;
- double scalingCoefficient = 2.0 / n;
- return FastFourierTransformer.scaleArray(fst(data),
scalingCoefficient);
+ if (orthogonal) {
+ final double s = FastMath.sqrt(2.0 / n);
+ return FastFourierTransformer.scaleArray(fst(data), s);
+ }
+ return fst(data);
}
/**
- * Inversely transform the given real data set.
- * <p>
- * The formula is f<sub>k</sub> = √(2/N)
∑<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(π nk/N)
- * </p>
+ * {@inheritDoc}
*
- * @param f the real data array to be inversely transformed
- * @return the real inversely transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * The first element of the specified data set is required to be {@code 0}.
*/
- public double[] inverseTransform2(double[] f) throws
IllegalArgumentException {
+ public double[] inverseTransform(double[] f)
+ throws IllegalArgumentException {
- return transform2(f);
+ if (orthogonal) {
+ return transform(f);
+ }
+ final double s = 2.0 / f.length;
+ return FastFourierTransformer.scaleArray(fst(f), s);
}
/**
- * Inversely transform the given real function, sampled on the given
interval.
- * <p>
- * The formula is f<sub>k</sub> = √(2/N)
∑<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(π nk/N)
- * </p>
+ * {@inheritDoc}
*
- * @param f the function to be sampled and inversely transformed
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @param n the number of sample points
- * @return the real inversely transformed array
- * @throws IllegalArgumentException if any parameters are invalid
+ * This implementation enforces {@code f(x) = 0.0} at {@code x = 0.0}.
*/
- public double[] inverseTransform2(UnivariateFunction f, double min, double
max, int n)
+ public double[] inverseTransform(UnivariateFunction f,
+ double min, double max, int n)
throws IllegalArgumentException {
- return transform2(f, min, max, n);
+ if (orthogonal) {
+ return transform(f, min, max, n);
+ }
+
+ final double[] data = FastFourierTransformer.sample(f, min, max, n);
+ data[0] = 0.0;
+ final double s = 2.0 / n;
+
+ return FastFourierTransformer.scaleArray(fst(data), s);
}
/**
- * Perform the FST algorithm (including inverse).
+ * Perform the FST algorithm (including inverse). The first element of the
+ * data set is required to be {@code 0}.
*
* @param f the real data array to be transformed
* @return the real transformed array
Modified:
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastSineTransformerTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastSineTransformerTest.java?rev=1213157&r1=1213156&r2=1213157&view=diff
==============================================================================
---
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastSineTransformerTest.java
(original)
+++
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastSineTransformerTest.java
Mon Dec 12 07:19:23 2011
@@ -36,7 +36,7 @@ public final class FastSineTransformerTe
*/
@Test
public void testAdHocData() {
- FastSineTransformer transformer = new FastSineTransformer();
+ FastSineTransformer transformer = FastSineTransformer.create();
double result[], tolerance = 1E-12;
double x[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
@@ -55,13 +55,14 @@ public final class FastSineTransformerTe
}
FastFourierTransformer.scaleArray(x, FastMath.sqrt(x.length / 2.0));
+ transformer = FastSineTransformer.createOrthogonal();
- result = transformer.transform2(y);
+ result = transformer.transform(y);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(x[i], result[i], tolerance);
}
- result = transformer.inverseTransform2(x);
+ result = transformer.inverseTransform(x);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(y[i], result[i], tolerance);
}
@@ -73,7 +74,7 @@ public final class FastSineTransformerTe
@Test
public void testSinFunction() {
UnivariateFunction f = new SinFunction();
- FastSineTransformer transformer = new FastSineTransformer();
+ FastSineTransformer transformer = FastSineTransformer.create();
double min, max, result[], tolerance = 1E-12; int N = 1 << 8;
min = 0.0; max = 2.0 * FastMath.PI;
@@ -97,7 +98,7 @@ public final class FastSineTransformerTe
@Test
public void testParameters() throws Exception {
UnivariateFunction f = new SinFunction();
- FastSineTransformer transformer = new FastSineTransformer();
+ FastSineTransformer transformer = FastSineTransformer.create();
try {
// bad interval