You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ce...@apache.org on 2012/02/01 02:50:56 UTC

svn commit: r1238898 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/complex/RootsOfUnity.java main/java/org/apache/commons/math/transform/FastFourierTransformer.java test/java/org/apache/commons/math/complex/RootsOfUnityTest.java

Author: celestin
Date: Wed Feb  1 01:50:56 2012
New Revision: 1238898

URL: http://svn.apache.org/viewvc?rev=1238898&view=rev
Log:
In o.a.c.m.complex.RootsOfUnity
- renamed computeOmega(int) to computeRoots(int)
- renamed getOmegaReal(int) to getReal(int)
- renamed getOmegaImaginary(int) to getImaginary(int)
- added int getNumberOfRoots()
- added unit tests.
See MATH-677

Added:
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/RootsOfUnityTest.java   (with props)
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/RootsOfUnity.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/RootsOfUnity.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/RootsOfUnity.java?rev=1238898&r1=1238897&r2=1238898&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/RootsOfUnity.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/complex/RootsOfUnity.java Wed Feb  1 01:50:56 2012
@@ -57,7 +57,7 @@ public class RootsOfUnity implements Ser
     private double[] omegaImaginaryClockwise;
 
     /**
-     * {@code true} if {@link #computeOmega(int)} was called with a positive
+     * {@code true} if {@link #computeRoots(int)} was called with a positive
      * value of its argument {@code n}. In this case, counter-clockwise ordering
      * of the roots of unity should be used.
      */
@@ -76,7 +76,7 @@ public class RootsOfUnity implements Ser
     }
 
     /**
-     * Returns {@code true} if {@link #computeOmega(int)} was called with a
+     * Returns {@code true} if {@link #computeRoots(int)} was called with a
      * positive value of its argument {@code n}. If {@code true}, then
      * counter-clockwise ordering of the roots of unity should be used.
      *
@@ -114,7 +114,7 @@ public class RootsOfUnity implements Ser
      * @param n the (signed) number of roots of unity to be computed
      * @throws ZeroException if {@code n = 0}
      */
-    public synchronized void computeOmega(int n) throws ZeroException {
+    public synchronized void computeRoots(int n) throws ZeroException {
 
         if (n == 0) {
             throw new ZeroException(
@@ -159,7 +159,7 @@ public class RootsOfUnity implements Ser
      * computed yet
      * @throws MathIllegalArgumentException if {@code k} is out of range
      */
-    public synchronized double getOmegaReal(int k)
+    public synchronized double getReal(int k)
             throws MathIllegalStateException, MathIllegalArgumentException {
 
         if (omegaCount == 0) {
@@ -186,7 +186,7 @@ public class RootsOfUnity implements Ser
      * computed yet
      * @throws OutOfRangeException if {@code k} is out of range
      */
-    public synchronized double getOmegaImaginary(int k)
+    public synchronized double getImaginary(int k)
             throws MathIllegalStateException, OutOfRangeException {
 
         if (omegaCount == 0) {
@@ -204,4 +204,16 @@ public class RootsOfUnity implements Ser
         return isCounterClockWise ? omegaImaginaryCounterClockwise[k] :
             omegaImaginaryClockwise[k];
     }
+
+    /**
+     * Returns the number of roots of unity currently stored. If
+     * {@link #computeRoots(int)} was called with {@code n}, then this method
+     * returns {@code abs(n)}. If no roots of unity have been computed yet, this
+     * method returns 0.
+     *
+     * @return the number of roots of unity currently stored
+     */
+    public synchronized int getNumberOfRoots() {
+        return omegaCount;
+    }
 }

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java?rev=1238898&r1=1238897&r2=1238898&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java Wed Feb  1 01:50:56 2012
@@ -189,7 +189,7 @@ public class FastFourierTransformer impl
      * not a power of two
      */
     public Complex[] transform(Complex[] f) {
-        roots.computeOmega(-f.length);
+        roots.computeRoots(-f.length);
         if (unitary) {
             final double s = 1.0 / FastMath.sqrt(f.length);
             return TransformUtils.scaleArray(fft(f), s);
@@ -242,7 +242,7 @@ public class FastFourierTransformer impl
      * not a power of two
      */
     public Complex[] inverseTransform(Complex[] f) {
-        roots.computeOmega(f.length);
+        roots.computeRoots(f.length);
         final double s = 1.0 / (unitary ? FastMath.sqrt(f.length) : f.length);
         return TransformUtils.scaleArray(fft(f), s);
     }
@@ -277,11 +277,11 @@ public class FastFourierTransformer impl
         for (int i = 0; i < n; i++) {
             repacked[i] = new Complex(f[2 * i], f[2 * i + 1]);
         }
-        roots.computeOmega(isInverse ? n : -n);
+        roots.computeRoots(isInverse ? n : -n);
         Complex[] z = fft(repacked);
 
         // reconstruct the FFT result for the original array
-        roots.computeOmega(isInverse ? 2 * n : -2 * n);
+        roots.computeRoots(isInverse ? 2 * n : -2 * n);
         transformed[0] = new Complex(2 * (z[0].getReal() + z[0].getImaginary()), 0.0);
         transformed[n] = new Complex(2 * (z[0].getReal() - z[0].getImaginary()), 0.0);
         for (int i = 1; i < n; i++) {
@@ -289,8 +289,8 @@ public class FastFourierTransformer impl
             Complex b = z[i].add(a);
             Complex c = z[i].subtract(a);
             //Complex D = roots.getOmega(i).multiply(Complex.I);
-            Complex d = new Complex(-roots.getOmegaImaginary(i),
-                                    roots.getOmegaReal(i));
+            Complex d = new Complex(-roots.getImaginary(i),
+                                    roots.getReal(i));
             transformed[i] = b.subtract(c.multiply(d));
             transformed[2 * n - i] = transformed[i].conjugate();
         }
@@ -362,8 +362,8 @@ public class FastFourierTransformer impl
                 for (int k = 0; k < i; k++) {
                     //z = f[i+j+k].multiply(roots.getOmega(k*m));
                     final int km = k * m;
-                    final double omegaKmReal = roots.getOmegaReal(km);
-                    final double omegaKmImag = roots.getOmegaImaginary(km);
+                    final double omegaKmReal = roots.getReal(km);
+                    final double omegaKmImag = roots.getImaginary(km);
                     //z = f[i+j+k].multiply(omega[k*m]);
                     final Complex z = new Complex(
                         f[i + j + k].getReal() * omegaKmReal -

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/RootsOfUnityTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/RootsOfUnityTest.java?rev=1238898&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/RootsOfUnityTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/RootsOfUnityTest.java Wed Feb  1 01:50:56 2012
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.complex;
+
+import org.apache.commons.math.exception.MathIllegalStateException;
+import org.apache.commons.math.exception.ZeroException;
+import org.apache.commons.math.util.FastMath;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+/**
+ * Unit tests for the {@link RootsOfUnity} class.
+ *
+ * @version $Id$
+ */
+public class RootsOfUnityTest {
+
+    @Test(expected = MathIllegalStateException.class)
+    public void testMathIllegalState1() {
+        final RootsOfUnity roots = new RootsOfUnity();
+        roots.getReal(0);
+    }
+
+    @Test(expected = MathIllegalStateException.class)
+    public void testMathIllegalState2() {
+        final RootsOfUnity roots = new RootsOfUnity();
+        roots.getImaginary(0);
+    }
+
+    @Test(expected = MathIllegalStateException.class)
+    public void testMathIllegalState3() {
+        final RootsOfUnity roots = new RootsOfUnity();
+        roots.isCounterClockWise();
+    }
+
+    @Test(expected = ZeroException.class)
+    public void testZeroNumberOfRoots() {
+        final RootsOfUnity roots = new RootsOfUnity();
+        roots.computeRoots(0);
+    }
+
+    @Test
+    public void testGetNumberOfRoots() {
+        final RootsOfUnity roots = new RootsOfUnity();
+        Assert.assertEquals("", 0, roots.getNumberOfRoots());
+        roots.computeRoots(5);
+        Assert.assertEquals("", 5, roots.getNumberOfRoots());
+        /*
+         * Testing -5 right after 5 is important, as the roots in this case are
+         * not recomputed.
+         */
+        roots.computeRoots(-5);
+        Assert.assertEquals("", 5, roots.getNumberOfRoots());
+        roots.computeRoots(6);
+        Assert.assertEquals("", 6, roots.getNumberOfRoots());
+    }
+
+    @Test
+    public void testComputeRoots() {
+        final RootsOfUnity roots = new RootsOfUnity();
+        for (int n = -10; n < 11; n++) {
+            /*
+             * Testing -n right after n is important, as the roots in this case
+             * are not recomputed.
+             */
+            if (n != 0) {
+                roots.computeRoots(n);
+                doTestComputeRoots(roots);
+                roots.computeRoots(-n);
+                doTestComputeRoots(roots);
+            }
+        }
+    }
+
+    private void doTestComputeRoots(final RootsOfUnity roots) {
+        final int n = roots.isCounterClockWise() ? roots.getNumberOfRoots() :
+            -roots.getNumberOfRoots();
+        final double tol = 10 * Math.ulp(1.0);
+        for (int k = 0; k < n; k++) {
+            final double t = 2.0 * FastMath.PI * k / n;
+            final String msg = String.format("n = %d, k = %d", n, k);
+            Assert.assertEquals(msg, FastMath.cos(t), roots.getReal(k), tol);
+            Assert.assertEquals(msg, FastMath.sin(t), roots.getImaginary(k), tol);
+        }
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/RootsOfUnityTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/complex/RootsOfUnityTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision