Author: celestin
Date: Fri Dec  9 06:47:23 2011
New Revision: 1212262

URL: http://svn.apache.org/viewvc?rev=1212262&view=rev
Log:
In distribution.FastCosineTransformer, 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/FastCosineTransformer.java
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastCosineTransformerTest.java

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java?rev=1212262&r1=1212261&r2=1212262&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java
 Fri Dec  9 06:47:23 2011
@@ -40,167 +40,142 @@ import org.apache.commons.math.util.Fast
  * @since 1.2
  */
 public class FastCosineTransformer implements RealTransformer {
-
-    /** Construct a default transformer. */
-    public FastCosineTransformer() {
-        super();
-    }
-
     /**
-     * Transform the given real data set.
-     * <p>
-     * The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> 
f<sub>N</sub>] +
-     *                        &sum;<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> 
cos(&pi; 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 fct(f);
-    }
+    private final boolean orthogonal;
 
     /**
-     * Transform the given real function, sampled on the given interval.
-     * <p>
-     * The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> 
f<sub>N</sub>] +
-     *                        &sum;<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> 
cos(&pi; 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 DCT 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);
-        return fct(data);
+    public FastCosineTransformer(final boolean orthogonal) {
+        this.orthogonal = orthogonal;
     }
 
     /**
-     * Transform the given real data set.
      * <p>
-     * The formula is F<sub>n</sub> = &radic;(1/2N) [f<sub>0</sub> + 
(-1)<sup>n</sup> f<sub>N</sub>] +
-     *                        &radic;(2/N) &sum;<sub>k=1</sub><sup>N-1</sup> 
f<sub>k</sub> cos(&pi; 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> = (1/2) [x<sub>0</sub> + (-1)<sup>n</sup>x<sub>N-1</sub>]
+     * + &sum;<sub>k=1</sub><sup>N-2</sup>
+     * x<sub>k</sub> cos[&pi; nk / (N - 1)],</li>
+     * <li>Inverse transform:
+     * x<sub>k</sub> = [1 / (N - 1)] [y<sub>0</sub>
+     * + (-1)<sup>k</sup>y<sub>N-1</sub>]
+     * + [2 / (N - 1)] &sum;<sub>n=1</sub><sup>N-2</sup>
+     * y<sub>n</sub> cos[&pi; nk / (N - 1)],</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 DCT transformer, with "standard" normalizing conventions
      */
-    public double[] transform2(double[] f) throws IllegalArgumentException {
-
-        double scalingCoefficient = FastMath.sqrt(2.0 / (f.length - 1));
-        return FastFourierTransformer.scaleArray(fct(f), scalingCoefficient);
+    public static FastCosineTransformer create() {
+        return new FastCosineTransformer(false);
     }
 
     /**
-     * Transform the given real function, sampled on the given interval.
      * <p>
-     * The formula is F<sub>n</sub> = &radic;(1/2N) [f<sub>0</sub> + 
(-1)<sup>n</sup> f<sub>N</sub>] +
-     *                        &radic;(2/N) &sum;<sub>k=1</sub><sup>N-1</sup> 
f<sub>k</sub> cos(&pi; 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 - 1)]<sup>-1/2</sup> [x<sub>0</sub>
+     * + (-1)<sup>n</sup>x<sub>N-1</sub>]
+     * + [2 / (N - 1)]<sup>1/2</sup> &sum;<sub>k=1</sub><sup>N-2</sup>
+     * x<sub>k</sub> cos[&pi; nk / (N - 1)],</li>
+     * <li>Inverse transform:
+     * x<sub>k</sub> = [2(N - 1)]<sup>-1/2</sup> [y<sub>0</sub>
+     * + (-1)<sup>k</sup>y<sub>N-1</sub>]
+     * + [2 / (N - 1)]<sup>1/2</sup> &sum;<sub>n=1</sub><sup>N-2</sup>
+     * y<sub>n</sub> cos[&pi; nk / (N - 1)],</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 DCT 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);
-        double scalingCoefficient = FastMath.sqrt(2.0 / (n - 1));
-        return FastFourierTransformer.scaleArray(fct(data), 
scalingCoefficient);
+    public static FastCosineTransformer createOrthogonal() {
+        return new FastCosineTransformer(true);
     }
 
     /**
-     * Inversely transform the given real data set.
-     * <p>
-     * The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> 
F<sub>N</sub>] +
-     *                        (2/N) &sum;<sub>n=1</sub><sup>N-1</sup> 
F<sub>n</sub> cos(&pi; nk/N)
-     * </p>
+     * Returns the forward transform of the specified real data set.
      *
-     * @param f the real data array to be inversely transformed
-     * @return the real inversely transformed array
+     * @param f the real data array to be transformed
+     * @return the real transformed array
      * @throws IllegalArgumentException if any parameters are invalid
      */
-    public double[] inverseTransform(double[] f)
-    throws IllegalArgumentException {
+    public double[] transform(double[] f) throws IllegalArgumentException {
 
-        double scalingCoefficient = 2.0 / (f.length - 1);
-        return FastFourierTransformer.scaleArray(fct(f), scalingCoefficient);
+        if (orthogonal) {
+            final double s = FastMath.sqrt(2.0 / (f.length - 1));
+            return FastFourierTransformer.scaleArray(fct(f), s);
+        }
+        return fct(f);
     }
 
     /**
-     * Inversely transform the given real function, sampled on the given
-     * interval.
-     * <p>
-     * The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> 
F<sub>N</sub>] +
-     *                        (2/N) &sum;<sub>n=1</sub><sup>N-1</sup> 
F<sub>n</sub> cos(&pi; nk/N)
-     * </p>
+     * Returns the forward transform of the specified real function, sampled on
+     * the specified interval.
      *
-     * @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 f the function to be sampled and transformed
+     * @param min the (inclusive) lower bound for the interval
+     * @param max the (exclusive) upper bound for the interval
      * @param n the number of sample points
-     * @return the real inversely transformed array
+     * @return the real transformed array
      * @throws IllegalArgumentException if any parameters are invalid
      */
-    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);
-        double scalingCoefficient = 2.0 / (n - 1);
-        return FastFourierTransformer.scaleArray(fct(data), 
scalingCoefficient);
+        final double[] data = FastFourierTransformer.sample(f, min, max, n);
+        return transform(data);
     }
 
     /**
-     * Inversely transform the given real data set.
-     * <p>
-     * The formula is f<sub>k</sub> = &radic;(1/2N) [F<sub>0</sub> + 
(-1)<sup>k</sup> F<sub>N</sub>] +
-     *                        &radic;(2/N) &sum;<sub>n=1</sub><sup>N-1</sup> 
F<sub>n</sub> cos(&pi; nk/N)
-     * </p>
+     * Returns the inverse transform of the specified real data set.
      *
      * @param f the real data array to be inversely transformed
      * @return the real inversely transformed array
      * @throws IllegalArgumentException if any parameters are invalid
      */
-    public double[] inverseTransform2(double[] f)
+    public double[] inverseTransform(double[] f)
         throws IllegalArgumentException {
-        return transform2(f);
+
+        final double s2 = 2.0 / (f.length - 1);
+        final double s1 = orthogonal ? FastMath.sqrt(s2) : s2;
+        return FastFourierTransformer.scaleArray(fct(f), s1);
     }
 
     /**
-     * Inversely transform the given real function, sampled on the given
-     * interval.
-     * <p>
-     * The formula is f<sub>k</sub> = &radic;(1/2N) [F<sub>0</sub> + 
(-1)<sup>k</sup> F<sub>N</sub>] +
-     *                        &radic;(2/N) &sum;<sub>n=1</sub><sup>N-1</sup> 
F<sub>n</sub> cos(&pi; nk/N)
-     * </p>
+     * Returns the inverse transform of the specified real function, sampled
+     * on the given interval.
      *
      * @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 min the (inclusive) lower bound for the interval
+     * @param max the (exclusive) 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
      */
-    public double[] inverseTransform2(UnivariateFunction f,
-                                      double min, double max, int n)
-        throws IllegalArgumentException {
+    public double[] inverseTransform(UnivariateFunction f,
+        double min, double max, int n) throws IllegalArgumentException {
 
-        return transform2(f, min, max, n);
+        final double[] data = FastFourierTransformer.sample(f, min, max, n);
+        return inverseTransform(data);
     }
 
     /**

Modified: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastCosineTransformerTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastCosineTransformerTest.java?rev=1212262&r1=1212261&r2=1212262&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastCosineTransformerTest.java
 (original)
+++ 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/transform/FastCosineTransformerTest.java
 Fri Dec  9 06:47:23 2011
@@ -36,7 +36,7 @@ public final class FastCosineTransformer
      */
     @Test
     public void testAdHocData() {
-        FastCosineTransformer transformer = new FastCosineTransformer();
+        FastCosineTransformer transformer = FastCosineTransformer.create();
         double result[], tolerance = 1E-12;
 
         double x[] = { 0.0, 1.0, 4.0, 9.0, 16.0, 25.0, 36.0, 49.0, 64.0 };
@@ -56,12 +56,13 @@ public final class FastCosineTransformer
 
         FastFourierTransformer.scaleArray(x, FastMath.sqrt(0.5 * 
(x.length-1)));
 
-        result = transformer.transform2(y);
+        transformer = FastCosineTransformer.createOrthogonal();
+        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 FastCosineTransformer
     @Test
     public void testSinFunction() {
         UnivariateFunction f = new SinFunction();
-        FastCosineTransformer transformer = new FastCosineTransformer();
+        FastCosineTransformer transformer = FastCosineTransformer.create();
         double min, max, result[], tolerance = 1E-12; int N = 9;
 
         double expected[] = { 0.0, 3.26197262739567, 0.0,
@@ -98,7 +99,7 @@ public final class FastCosineTransformer
     @Test
     public void testParameters() throws Exception {
         UnivariateFunction f = new SinFunction();
-        FastCosineTransformer transformer = new FastCosineTransformer();
+        FastCosineTransformer transformer = FastCosineTransformer.create();
 
         try {
             // bad interval


Reply via email to