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