In package transform, replaced FastFourierTransformer.transform2 and FastFourierTransformer.inverseTransform2 with a combination of transform()/inverseTransform(), combined with appropriate factory methods (MATH-677).
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1211318 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e994c42a8e
commit
e967bbf8df
|
@ -241,7 +241,7 @@ public class FastCosineTransformer implements RealTransformer {
|
||||||
x[n - i] = a + b;
|
x[n - i] = a + b;
|
||||||
t1 += c;
|
t1 += c;
|
||||||
}
|
}
|
||||||
FastFourierTransformer transformer = new FastFourierTransformer();
|
FastFourierTransformer transformer = FastFourierTransformer.create();
|
||||||
Complex[] y = transformer.transform(x);
|
Complex[] y = transformer.transform(x);
|
||||||
|
|
||||||
// reconstruct the FCT result for the original array
|
// reconstruct the FCT result for the original array
|
||||||
|
|
|
@ -32,14 +32,17 @@ import org.apache.commons.math.util.FastMath;
|
||||||
* chapter 6.
|
* chapter 6.
|
||||||
* <p>
|
* <p>
|
||||||
* There are several conventions for the definition of FFT and inverse FFT,
|
* There are several conventions for the definition of FFT and inverse FFT,
|
||||||
* mainly on different coefficient and exponent. Here the equations are listed
|
* mainly on different coefficient and exponent. The conventions adopted in the
|
||||||
* in the comments of the corresponding methods.</p>
|
* present implementation are specified in the comments of the two provided
|
||||||
|
* factory methods, {@link #create()} and {@link #createUnitary()}.
|
||||||
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* We require the length of data set to be power of 2, this greatly simplifies
|
* We require the length of data set to be power of 2, this greatly simplifies
|
||||||
* and speeds up the code. Users can pad the data with zeros to meet this
|
* and speeds up the code. Users can pad the data with zeros to meet this
|
||||||
* requirement. There are other flavors of FFT, for reference, see S. Winograd,
|
* requirement. There are other flavors of FFT, for reference, see S. Winograd,
|
||||||
* <i>On computing the discrete Fourier transform</i>, Mathematics of Computation,
|
* <i>On computing the discrete Fourier transform</i>, Mathematics of
|
||||||
* 32 (1978), 175 - 199.</p>
|
* Computation, 32 (1978), 175 - 199.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
|
@ -49,19 +52,82 @@ public class FastFourierTransformer implements Serializable {
|
||||||
/** Serializable version identifier. */
|
/** Serializable version identifier. */
|
||||||
static final long serialVersionUID = 5138259215438106000L;
|
static final long serialVersionUID = 5138259215438106000L;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code true} if the orthogonal version of the FFT should be used.
|
||||||
|
*
|
||||||
|
* @see #create()
|
||||||
|
* @see #createUnitary()
|
||||||
|
*/
|
||||||
|
private final boolean unitary;
|
||||||
|
|
||||||
/** The roots of unity. */
|
/** The roots of unity. */
|
||||||
private RootsOfUnity roots = new RootsOfUnity();
|
private RootsOfUnity roots = new RootsOfUnity();
|
||||||
|
|
||||||
/** Construct a default transformer. */
|
/** Construct a default transformer. */
|
||||||
public FastFourierTransformer() {
|
private FastFourierTransformer() {
|
||||||
super();
|
super();
|
||||||
|
this.unitary = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of this class, with various normalization
|
||||||
|
* conventions.
|
||||||
|
*
|
||||||
|
* @param unitary {@code false} if the direct Fourier transform is
|
||||||
|
* <em>not</em> to be scaled, {@code true} if it is to be scaled so as to
|
||||||
|
* make the transform unitary.
|
||||||
|
* @see #create()
|
||||||
|
* @see #createUnitary()
|
||||||
|
*/
|
||||||
|
private FastFourierTransformer(final boolean unitary) {
|
||||||
|
this.unitary = unitary;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the given real data set.
|
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $
|
* Returns a new instance of this class. The returned transformer uses the
|
||||||
|
* normalizing conventions described below.
|
||||||
* </p>
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>Forward transform:
|
||||||
|
* y<sub>n</sub> = ∑<sub>k=0</sub><sup>N-1</sup>
|
||||||
|
* x<sub>k</sub> exp(-2πi n k / N),</li>
|
||||||
|
* <li>Inverse transform:
|
||||||
|
* x<sub>k</sub> = N<sup>-1</sup> ∑<sub>n=0</sub><sup>N-1</sup>
|
||||||
|
* y<sub>n</sub> exp(2πi n k / N).</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return a new FFT transformer, with "standard" normalizing conventions
|
||||||
|
*/
|
||||||
|
public static FastFourierTransformer create() {
|
||||||
|
return new FastFourierTransformer(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Returns a new instance of this class. The returned transformer uses the
|
||||||
|
* normalizing conventions described below.
|
||||||
|
* <ul>
|
||||||
|
* <li>Forward transform:
|
||||||
|
* y<sub>n</sub> = N<sup>-1/2</sup> ∑<sub>k=0</sub><sup>N-1</sup>
|
||||||
|
* x<sub>k</sub> exp(-2πi n k / N),</li>
|
||||||
|
* <li>Inverse transform:
|
||||||
|
* x<sub>k</sub> = N<sup>-1/2</sup> ∑<sub>n=0</sub><sup>N-1</sup>
|
||||||
|
* y<sub>n</sub> exp(2πi n k / N),</li>
|
||||||
|
* </ul>
|
||||||
|
* which make the transform unitary.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a new FFT transformer, with unitary normalizing conventions
|
||||||
|
*/
|
||||||
|
public static FastFourierTransformer createUnitary() {
|
||||||
|
return new FastFourierTransformer(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the forward transform of the specified real data set.
|
||||||
*
|
*
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @return the complex transformed array
|
* @return the complex transformed array
|
||||||
|
@ -69,18 +135,20 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*/
|
*/
|
||||||
public Complex[] transform(double[] f)
|
public Complex[] transform(double[] f)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
if (unitary) {
|
||||||
|
final double s = 1.0 / FastMath.sqrt(f.length);
|
||||||
|
return scaleArray(fft(f, false), s);
|
||||||
|
}
|
||||||
return fft(f, false);
|
return fft(f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the given real function, sampled on the given interval.
|
* Returns the forward transform of the specified real function, sampled on
|
||||||
* <p>
|
* the specified interval.
|
||||||
* The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @param f the function to be sampled and transformed
|
* @param f the function to be sampled and transformed
|
||||||
* @param min the lower bound for the interval
|
* @param min the (inclusive) lower bound for the interval
|
||||||
* @param max the upper bound for the interval
|
* @param max the (exclusive) upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the complex transformed array
|
* @return the complex transformed array
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
|
@ -88,15 +156,16 @@ public class FastFourierTransformer implements Serializable {
|
||||||
public Complex[] transform(UnivariateFunction f,
|
public Complex[] transform(UnivariateFunction f,
|
||||||
double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
double[] data = sample(f, min, max, n);
|
final double[] data = sample(f, min, max, n);
|
||||||
|
if (unitary) {
|
||||||
|
final double s = 1.0 / FastMath.sqrt(n);
|
||||||
|
return scaleArray(fft(data, false), s);
|
||||||
|
}
|
||||||
return fft(data, false);
|
return fft(data, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the given complex data set.
|
* Returns the forward transform of the specified complex data set.
|
||||||
* <p>
|
|
||||||
* The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @param f the complex data array to be transformed
|
* @param f the complex data array to be transformed
|
||||||
* @return the complex transformed array
|
* @return the complex transformed array
|
||||||
|
@ -105,71 +174,15 @@ public class FastFourierTransformer implements Serializable {
|
||||||
public Complex[] transform(Complex[] f)
|
public Complex[] transform(Complex[] f)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
roots.computeOmega(f.length);
|
roots.computeOmega(f.length);
|
||||||
|
if (unitary) {
|
||||||
|
final double s = 1.0 / FastMath.sqrt(f.length);
|
||||||
|
return scaleArray(fft(f), s);
|
||||||
|
}
|
||||||
return fft(f);
|
return fft(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the given real data set.
|
* Returns the inverse transform of the specified real data set.
|
||||||
* <p>
|
|
||||||
* The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param f the real data array to be transformed
|
|
||||||
* @return the complex transformed array
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
|
||||||
*/
|
|
||||||
public Complex[] transform2(double[] f)
|
|
||||||
throws IllegalArgumentException {
|
|
||||||
|
|
||||||
double scalingCoefficient = 1.0 / FastMath.sqrt(f.length);
|
|
||||||
return scaleArray(fft(f, false), scalingCoefficient);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform the given real function, sampled on the given interval.
|
|
||||||
* <p>
|
|
||||||
* The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$
|
|
||||||
* </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 complex transformed array
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
|
||||||
*/
|
|
||||||
public Complex[] transform2(UnivariateFunction f,
|
|
||||||
double min, double max, int n)
|
|
||||||
throws IllegalArgumentException {
|
|
||||||
|
|
||||||
double[] data = sample(f, min, max, n);
|
|
||||||
double scalingCoefficient = 1.0 / FastMath.sqrt(n);
|
|
||||||
return scaleArray(fft(data, false), scalingCoefficient);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform the given complex data set.
|
|
||||||
* <p>
|
|
||||||
* The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param f the complex data array to be transformed
|
|
||||||
* @return the complex transformed array
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
|
||||||
*/
|
|
||||||
public Complex[] transform2(Complex[] f)
|
|
||||||
throws IllegalArgumentException {
|
|
||||||
|
|
||||||
roots.computeOmega(f.length);
|
|
||||||
double scalingCoefficient = 1.0 / FastMath.sqrt(f.length);
|
|
||||||
return scaleArray(fft(f), scalingCoefficient);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inversely transform the given real data set.
|
|
||||||
* <p>
|
|
||||||
* The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @param f the real data array to be inversely transformed
|
* @param f the real data array to be inversely transformed
|
||||||
* @return the complex inversely transformed array
|
* @return the complex inversely transformed array
|
||||||
|
@ -178,19 +191,17 @@ public class FastFourierTransformer implements Serializable {
|
||||||
public Complex[] inverseTransform(double[] f)
|
public Complex[] inverseTransform(double[] f)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
double scalingCoefficient = 1.0 / f.length;
|
final double s = 1.0 / (unitary ? FastMath.sqrt(f.length) : f.length);
|
||||||
return scaleArray(fft(f, true), scalingCoefficient);
|
return scaleArray(fft(f, true), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inversely transform the given real function, sampled on the given interval.
|
* Returns the inverse transform of the specified real function, sampled
|
||||||
* <p>
|
* on the given interval.
|
||||||
* The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @param f the function to be sampled and inversely transformed
|
* @param f the function to be sampled and inversely transformed
|
||||||
* @param min the lower bound for the interval
|
* @param min the (inclusive) lower bound for the interval
|
||||||
* @param max the upper bound for the interval
|
* @param max the (exclusive) upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the complex inversely transformed array
|
* @return the complex inversely transformed array
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
|
@ -199,16 +210,13 @@ public class FastFourierTransformer implements Serializable {
|
||||||
double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
double[] data = sample(f, min, max, n);
|
final double[] data = sample(f, min, max, n);
|
||||||
double scalingCoefficient = 1.0 / n;
|
final double s = 1.0 / (unitary ? FastMath.sqrt(n) : n);
|
||||||
return scaleArray(fft(data, true), scalingCoefficient);
|
return scaleArray(fft(data, true), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inversely transform the given complex data set.
|
* Returns the inverse transform of the specified complex data set.
|
||||||
* <p>
|
|
||||||
* The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @param f the complex data array to be inversely transformed
|
* @param f the complex data array to be inversely transformed
|
||||||
* @return the complex inversely transformed array
|
* @return the complex inversely transformed array
|
||||||
|
@ -218,65 +226,8 @@ public class FastFourierTransformer implements Serializable {
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
roots.computeOmega(-f.length); // pass negative argument
|
roots.computeOmega(-f.length); // pass negative argument
|
||||||
double scalingCoefficient = 1.0 / f.length;
|
final double s = 1.0 / (unitary ? FastMath.sqrt(f.length) : f.length);
|
||||||
return scaleArray(fft(f), scalingCoefficient);
|
return scaleArray(fft(f), s);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inversely transform the given real data set.
|
|
||||||
* <p>
|
|
||||||
* The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param f the real data array to be inversely transformed
|
|
||||||
* @return the complex inversely transformed array
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
|
||||||
*/
|
|
||||||
public Complex[] inverseTransform2(double[] f)
|
|
||||||
throws IllegalArgumentException {
|
|
||||||
|
|
||||||
double scalingCoefficient = 1.0 / FastMath.sqrt(f.length);
|
|
||||||
return scaleArray(fft(f, true), scalingCoefficient);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inversely transform the given real function, sampled on the given interval.
|
|
||||||
* <p>
|
|
||||||
* The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @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 complex inversely transformed array
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
|
||||||
*/
|
|
||||||
public Complex[] inverseTransform2(UnivariateFunction f,
|
|
||||||
double min, double max, int n)
|
|
||||||
throws IllegalArgumentException {
|
|
||||||
|
|
||||||
double[] data = sample(f, min, max, n);
|
|
||||||
double scalingCoefficient = 1.0 / FastMath.sqrt(n);
|
|
||||||
return scaleArray(fft(data, true), scalingCoefficient);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inversely transform the given complex data set.
|
|
||||||
* <p>
|
|
||||||
* The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param f the complex data array to be inversely transformed
|
|
||||||
* @return the complex inversely transformed array
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
|
||||||
*/
|
|
||||||
public Complex[] inverseTransform2(Complex[] f)
|
|
||||||
throws IllegalArgumentException {
|
|
||||||
|
|
||||||
roots.computeOmega(-f.length); // pass negative argument
|
|
||||||
double scalingCoefficient = 1.0 / FastMath.sqrt(f.length);
|
|
||||||
return scaleArray(fft(f), scalingCoefficient);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -387,10 +338,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
final double omegaKmImag = roots.getOmegaImaginary(km);
|
final double omegaKmImag = roots.getOmegaImaginary(km);
|
||||||
//z = f[i+j+k].multiply(omega[k*m]);
|
//z = f[i+j+k].multiply(omega[k*m]);
|
||||||
final Complex z = new Complex(
|
final Complex z = new Complex(
|
||||||
f[i + j + k].getReal() * omegaKmReal
|
f[i + j + k].getReal() * omegaKmReal -
|
||||||
- f[i + j + k].getImaginary() * omegaKmImag,
|
f[i + j + k].getImaginary() * omegaKmImag,
|
||||||
f[i + j + k].getReal() * omegaKmImag
|
f[i + j + k].getReal() * omegaKmImag +
|
||||||
+ f[i + j + k].getImaginary() * omegaKmReal);
|
f[i + j + k].getImaginary() * omegaKmReal);
|
||||||
|
|
||||||
f[i + j + k] = f[j + k].subtract(z);
|
f[i + j + k] = f[j + k].subtract(z);
|
||||||
f[j + k] = f[j + k].add(z);
|
f[j + k] = f[j + k].add(z);
|
||||||
|
@ -409,8 +360,8 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* require that.</p>
|
* require that.</p>
|
||||||
*
|
*
|
||||||
* @param f the function to be sampled
|
* @param f the function to be sampled
|
||||||
* @param min the lower bound for the interval
|
* @param min the (inclusive) lower bound for the interval
|
||||||
* @param max the upper bound for the interval
|
* @param max the (exclusive) upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the samples array
|
* @return the samples array
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
|
@ -517,17 +468,20 @@ public class FastFourierTransformer implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a multi-dimensional Fourier transform on a given array.
|
* Performs a multi-dimensional Fourier transform on a given array. Use
|
||||||
* Use {@link #inverseTransform2(Complex[])} and
|
* {@link #transform(Complex[])} and {@link #inverseTransform(Complex[])} in
|
||||||
* {@link #transform2(Complex[])} in a row-column implementation
|
* a row-column implementation in any number of dimensions with
|
||||||
* in any number of dimensions with O(N×log(N)) complexity with
|
* O(N×log(N)) complexity with
|
||||||
* N=n<sub>1</sub>×n<sub>2</sub>×n<sub>3</sub>×...×n<sub>d</sub>,
|
* N = n<sub>1</sub> × n<sub>2</sub> ×n<sub>3</sub> × ...
|
||||||
* n<sub>x</sub>=number of elements in dimension x,
|
* × n<sub>d</sub>, where n<sub>k</sub> is the number of elements in
|
||||||
* and d=total number of dimensions.
|
* dimension k, and d is the total number of dimensions.
|
||||||
*
|
*
|
||||||
* @param mdca Multi-Dimensional Complex Array id est Complex[][][][]
|
* @param mdca Multi-Dimensional Complex Array id est
|
||||||
* @param forward inverseTransform2 is preformed if this is false
|
* {@code Complex[][][][]}
|
||||||
* @return transform of mdca as a Multi-Dimensional Complex Array id est Complex[][][][]
|
* @param forward {@link #inverseTransform} is performed if this is
|
||||||
|
* {@code false}
|
||||||
|
* @return transform of {@code mdca} as a Multi-Dimensional Complex Array
|
||||||
|
* id est {@code Complex[][][][]}
|
||||||
* @throws IllegalArgumentException if any dimension is not a power of two
|
* @throws IllegalArgumentException if any dimension is not a power of two
|
||||||
*/
|
*/
|
||||||
public Object mdfft(Object mdca, boolean forward)
|
public Object mdfft(Object mdca, boolean forward)
|
||||||
|
@ -546,7 +500,8 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* Performs one dimension of a multi-dimensional Fourier transform.
|
* Performs one dimension of a multi-dimensional Fourier transform.
|
||||||
*
|
*
|
||||||
* @param mdcm input matrix
|
* @param mdcm input matrix
|
||||||
* @param forward inverseTransform2 is preformed if this is false
|
* @param forward {@link #inverseTransform} is performed if this is
|
||||||
|
* {@code false}
|
||||||
* @param d index of the dimension to process
|
* @param d index of the dimension to process
|
||||||
* @param subVector recursion subvector
|
* @param subVector recursion subvector
|
||||||
* @throws IllegalArgumentException if any dimension is not a power of two
|
* @throws IllegalArgumentException if any dimension is not a power of two
|
||||||
|
@ -565,9 +520,9 @@ public class FastFourierTransformer implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forward) {
|
if (forward) {
|
||||||
temp = transform2(temp);
|
temp = transform(temp);
|
||||||
} else {
|
} else {
|
||||||
temp = inverseTransform2(temp);
|
temp = inverseTransform(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < dimensionSize[d]; i++) {
|
for (int i = 0; i < dimensionSize[d]; i++) {
|
||||||
|
@ -842,10 +797,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
omegaImaginaryForward[0] = 0.0;
|
omegaImaginaryForward[0] = 0.0;
|
||||||
omegaImaginaryInverse[0] = 0.0;
|
omegaImaginaryInverse[0] = 0.0;
|
||||||
for (int i = 1; i < absN; i++) {
|
for (int i = 1; i < absN; i++) {
|
||||||
omegaReal[i] = omegaReal[i - 1] * cosT
|
omegaReal[i] = omegaReal[i - 1] * cosT +
|
||||||
+ omegaImaginaryForward[i - 1] * sinT;
|
omegaImaginaryForward[i - 1] * sinT;
|
||||||
omegaImaginaryForward[i] = omegaImaginaryForward[i - 1] * cosT
|
omegaImaginaryForward[i] = omegaImaginaryForward[i - 1] * cosT -
|
||||||
- omegaReal[i - 1] * sinT;
|
omegaReal[i - 1] * sinT;
|
||||||
omegaImaginaryInverse[i] = -omegaImaginaryForward[i];
|
omegaImaginaryInverse[i] = -omegaImaginaryForward[i];
|
||||||
}
|
}
|
||||||
omegaCount = absN;
|
omegaCount = absN;
|
||||||
|
|
|
@ -227,7 +227,7 @@ public class FastSineTransformer implements RealTransformer {
|
||||||
x[i] = a + b;
|
x[i] = a + b;
|
||||||
x[n - i] = a - b;
|
x[n - i] = a - b;
|
||||||
}
|
}
|
||||||
FastFourierTransformer transformer = new FastFourierTransformer();
|
FastFourierTransformer transformer = FastFourierTransformer.create();
|
||||||
Complex[] y = transformer.transform(x);
|
Complex[] y = transformer.transform(x);
|
||||||
|
|
||||||
// reconstruct the FST result for the original array
|
// reconstruct the FST result for the original array
|
||||||
|
|
Loading…
Reference in New Issue