Added a RealTransformer interface on top of cosine, sine and Hadamard transforms.
The Fourier transform cannot implement this interface since it produces complex results. Improved error messages. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@729758 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f8cc8e9d37
commit
dff725b2e8
|
@ -343,6 +343,26 @@ public class MessagesResources_fr
|
||||||
{ "{0} is not a power of 2",
|
{ "{0} is not a power of 2",
|
||||||
"{0} n''est pas une puissance de 2" },
|
"{0} n''est pas une puissance de 2" },
|
||||||
|
|
||||||
|
// org.apache.commons.math.transform.FastFourierTransformer
|
||||||
|
{ "cannot compute 0-th root of unity, indefinite result",
|
||||||
|
"impossible de calculer la racine z\u00e9roi\u00e8me de l''unit\u00e9, r\u00e9sultat ind\u00e9fini" },
|
||||||
|
{ "number of sample is not positive: {0}",
|
||||||
|
"le nombre d''\u00e9chantillons n''est pas positif : {0}" },
|
||||||
|
{ "{0} is not a power of 2, consider padding for fix",
|
||||||
|
"{0} n''est pas une puissance de 2, ajoutez des \u00e9l\u00e9ments pour corriger" },
|
||||||
|
{ "endpoints do not specify an interval: [{0}, {1}]",
|
||||||
|
"les extr\u00e9mit\u00e9s ne constituent pas un intervalle : [{0}, {1}]" },
|
||||||
|
{ "some dimensions don't math: {0} != {1}",
|
||||||
|
"certaines dimensions sont incoh\u00e9rentes : {0} != {1}" },
|
||||||
|
|
||||||
|
// org.apache.commons.math.transform.FastCosineTransformer
|
||||||
|
{ "{0} is not a power of 2 plus one",
|
||||||
|
"{0} n''est pas une puissance de 2 plus un" },
|
||||||
|
|
||||||
|
// org.apache.commons.math.transform.FastSineTransformer
|
||||||
|
{ "first element is not 0: {0}",
|
||||||
|
"le premier \u00e9l\u00e9ment n''est pas nul : {0}" },
|
||||||
|
|
||||||
// org.apache.commons.math.util.OpenIntToDoubleHashMap
|
// org.apache.commons.math.util.OpenIntToDoubleHashMap
|
||||||
{ "map has been modified while iterating",
|
{ "map has been modified while iterating",
|
||||||
"la table d''adressage a \u00e9t\u00e9 modifi\u00e9e pendant l''it\u00e9ration" },
|
"la table d''adressage a \u00e9t\u00e9 modifi\u00e9e pendant l''it\u00e9ration" },
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.commons.math.transform;
|
package org.apache.commons.math.transform;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import org.apache.commons.math.FunctionEvaluationException;
|
||||||
import org.apache.commons.math.analysis.*;
|
import org.apache.commons.math.MathRuntimeException;
|
||||||
import org.apache.commons.math.complex.*;
|
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
||||||
import org.apache.commons.math.MathException;
|
import org.apache.commons.math.complex.Complex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/
|
* Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/
|
||||||
|
@ -37,10 +37,10 @@ import org.apache.commons.math.MathException;
|
||||||
* @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $
|
* @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public class FastCosineTransformer implements Serializable {
|
public class FastCosineTransformer implements RealTransformer {
|
||||||
|
|
||||||
/** serializable version identifier */
|
/** serializable version identifier */
|
||||||
static final long serialVersionUID = -7673941545134707766L;
|
private static final long serialVersionUID = -831323620109865380L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a default transformer.
|
* Construct a default transformer.
|
||||||
|
@ -52,26 +52,23 @@ public class FastCosineTransformer implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Transform the given real data set.
|
* Transform the given real data set.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ F_n = (1/2) [f_0 + (-1)^n f_N] +
|
* The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
|
||||||
* \Sigma_{k=1}^{N-1} f_k \cos(\pi nk/N) $
|
* ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform(double f[]) throws MathException,
|
public double[] transform(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
return fct(f);
|
return fct(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform the given real function, sampled on the given interval.
|
* Transform the given real function, sampled on the given interval.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ F_n = (1/2) [f_0 + (-1)^n f_N] +
|
* The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
|
||||||
* \Sigma_{k=1}^{N-1} f_k \cos(\pi nk/N) $
|
* ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param f the function to be sampled and transformed
|
* @param f the function to be sampled and transformed
|
||||||
|
@ -79,13 +76,13 @@ public class FastCosineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform(
|
public double[] transform(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
||||||
return fct(data);
|
return fct(data);
|
||||||
}
|
}
|
||||||
|
@ -93,17 +90,15 @@ public class FastCosineTransformer implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Transform the given real data set.
|
* Transform the given real data set.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ F_n = \sqrt{1/2N} [f_0 + (-1)^n f_N] +
|
* The formula is F<sub>n</sub> = \sqrt{1/2N} [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
|
||||||
* \sqrt{2/N} \Sigma_{k=1}^{N-1} f_k \cos(\pi nk/N) $
|
* √(2/N) ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform2(double f[]) throws MathException,
|
public double[] transform2(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
double scaling_coefficient = Math.sqrt(2.0 / (f.length-1));
|
double scaling_coefficient = Math.sqrt(2.0 / (f.length-1));
|
||||||
return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient);
|
return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient);
|
||||||
|
@ -112,8 +107,8 @@ public class FastCosineTransformer implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Transform the given real function, sampled on the given interval.
|
* Transform the given real function, sampled on the given interval.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ F_n = \sqrt{1/2N} [f_0 + (-1)^n f_N] +
|
* The formula is F<sub>n</sub> = \sqrt{1/2N} [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
|
||||||
* \sqrt{2/N} \Sigma_{k=1}^{N-1} f_k \cos(\pi nk/N) $
|
* √(2/N) ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N)
|
||||||
*
|
*
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
|
@ -122,12 +117,13 @@ public class FastCosineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform2(
|
public double[] transform2(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
||||||
double scaling_coefficient = Math.sqrt(2.0 / (n-1));
|
double scaling_coefficient = Math.sqrt(2.0 / (n-1));
|
||||||
|
@ -137,17 +133,15 @@ public class FastCosineTransformer implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Inversely transform the given real data set.
|
* Inversely transform the given real data set.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ f_k = (1/N) [F_0 + (-1)^k F_N] +
|
* The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
|
||||||
* (2/N) \Sigma_{n=1}^{N-1} F_n \cos(\pi nk/N) $
|
* (2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param f the real data array to be inversely transformed
|
* @param f the real data array to be inversely transformed
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform(double f[]) throws MathException,
|
public double[] inversetransform(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
double scaling_coefficient = 2.0 / (f.length - 1);
|
double scaling_coefficient = 2.0 / (f.length - 1);
|
||||||
return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient);
|
return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient);
|
||||||
|
@ -156,8 +150,8 @@ public class FastCosineTransformer implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Inversely transform the given real function, sampled on the given interval.
|
* Inversely transform the given real function, sampled on the given interval.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ f_k = (1/N) [F_0 + (-1)^k F_N] +
|
* The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
|
||||||
* (2/N) \Sigma_{n=1}^{N-1} F_n \cos(\pi nk/N) $
|
* (2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param f the function to be sampled and inversely transformed
|
* @param f the function to be sampled and inversely transformed
|
||||||
|
@ -165,12 +159,13 @@ public class FastCosineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform(
|
public double[] inversetransform(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
||||||
double scaling_coefficient = 2.0 / (n - 1);
|
double scaling_coefficient = 2.0 / (n - 1);
|
||||||
|
@ -180,26 +175,23 @@ public class FastCosineTransformer implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Inversely transform the given real data set.
|
* Inversely transform the given real data set.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ f_k = \sqrt{1/2N} [F_0 + (-1)^k F_N] +
|
* The formula is f<sub>k</sub> = √(1/2N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
|
||||||
* \sqrt{2/N} \Sigma_{n=1}^{N-1} F_n \cos(\pi nk/N) $
|
* √(2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param f the real data array to be inversely transformed
|
* @param f the real data array to be inversely transformed
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform2(double f[]) throws MathException,
|
public double[] inversetransform2(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
return transform2(f);
|
return transform2(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inversely transform the given real function, sampled on the given interval.
|
* Inversely transform the given real function, sampled on the given interval.
|
||||||
* <p>
|
* <p>
|
||||||
* The formula is $ f_k = \sqrt{1/2N} [F_0 + (-1)^k F_N] +
|
* The formula is f<sub>k</sub> = √(1/2N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
|
||||||
* \sqrt{2/N} \Sigma_{n=1}^{N-1} F_n \cos(\pi nk/N) $
|
* √(2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N)
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param f the function to be sampled and inversely transformed
|
* @param f the function to be sampled and inversely transformed
|
||||||
|
@ -207,12 +199,13 @@ public class FastCosineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform2(
|
public double[] inversetransform2(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
return transform2(f, min, max, n);
|
return transform2(f, min, max, n);
|
||||||
}
|
}
|
||||||
|
@ -222,18 +215,17 @@ public class FastCosineTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
protected double[] fct(double f[]) throws MathException,
|
protected double[] fct(double f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
double A, B, C, F1, x[], F[] = new double[f.length];
|
double A, B, C, F1, x[], F[] = new double[f.length];
|
||||||
|
|
||||||
int N = f.length - 1;
|
int N = f.length - 1;
|
||||||
if (!FastFourierTransformer.isPowerOf2(N)) {
|
if (!FastFourierTransformer.isPowerOf2(N)) {
|
||||||
throw new IllegalArgumentException
|
throw MathRuntimeException.createIllegalArgumentException("{0} is not a power of 2 plus one",
|
||||||
("Number of samples not power of 2 plus one: " + f.length);
|
new Object[] { f.length });
|
||||||
}
|
}
|
||||||
if (N == 1) { // trivial case
|
if (N == 1) { // trivial case
|
||||||
F[0] = 0.5 * (f[0] + f[1]);
|
F[0] = 0.5 * (f[0] + f[1]);
|
||||||
|
|
|
@ -19,7 +19,8 @@ package org.apache.commons.math.transform;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
|
|
||||||
import org.apache.commons.math.MathException;
|
import org.apache.commons.math.FunctionEvaluationException;
|
||||||
|
import org.apache.commons.math.MathRuntimeException;
|
||||||
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
||||||
import org.apache.commons.math.complex.Complex;
|
import org.apache.commons.math.complex.Complex;
|
||||||
|
|
||||||
|
@ -71,12 +72,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] transform(double f[]) throws MathException,
|
public Complex[] transform(double f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
return fft(f, false);
|
return fft(f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,13 +90,13 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the 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 MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] transform(
|
public Complex[] transform(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = sample(f, min, max, n);
|
double data[] = sample(f, min, max, n);
|
||||||
return fft(data, false);
|
return fft(data, false);
|
||||||
}
|
}
|
||||||
|
@ -110,12 +109,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] transform(Complex f[]) throws MathException,
|
public Complex[] transform(Complex f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
computeOmega(f.length);
|
computeOmega(f.length);
|
||||||
return fft(f);
|
return fft(f);
|
||||||
}
|
}
|
||||||
|
@ -128,11 +125,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] transform2(double f[]) throws MathException,
|
public Complex[] transform2(double f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
||||||
return scaleArray(fft(f, false), scaling_coefficient);
|
return scaleArray(fft(f, false), scaling_coefficient);
|
||||||
|
@ -149,12 +145,13 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the 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 MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] transform2(
|
public Complex[] transform2(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = sample(f, min, max, n);
|
double data[] = sample(f, min, max, n);
|
||||||
double scaling_coefficient = 1.0 / Math.sqrt(n);
|
double scaling_coefficient = 1.0 / Math.sqrt(n);
|
||||||
|
@ -169,11 +166,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] transform2(Complex f[]) throws MathException,
|
public Complex[] transform2(Complex f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
computeOmega(f.length);
|
computeOmega(f.length);
|
||||||
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
||||||
|
@ -188,11 +184,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] inversetransform(double f[]) throws MathException,
|
public Complex[] inversetransform(double f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
double scaling_coefficient = 1.0 / f.length;
|
double scaling_coefficient = 1.0 / f.length;
|
||||||
return scaleArray(fft(f, true), scaling_coefficient);
|
return scaleArray(fft(f, true), scaling_coefficient);
|
||||||
|
@ -209,12 +204,13 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the 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 MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] inversetransform(
|
public Complex[] inversetransform(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = sample(f, min, max, n);
|
double data[] = sample(f, min, max, n);
|
||||||
double scaling_coefficient = 1.0 / n;
|
double scaling_coefficient = 1.0 / n;
|
||||||
|
@ -229,11 +225,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] inversetransform(Complex f[]) throws MathException,
|
public Complex[] inversetransform(Complex f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
computeOmega(-f.length); // pass negative argument
|
computeOmega(-f.length); // pass negative argument
|
||||||
double scaling_coefficient = 1.0 / f.length;
|
double scaling_coefficient = 1.0 / f.length;
|
||||||
|
@ -248,11 +243,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] inversetransform2(double f[]) throws MathException,
|
public Complex[] inversetransform2(double f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
||||||
return scaleArray(fft(f, true), scaling_coefficient);
|
return scaleArray(fft(f, true), scaling_coefficient);
|
||||||
|
@ -269,12 +263,13 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the 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 MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] inversetransform2(
|
public Complex[] inversetransform2(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = sample(f, min, max, n);
|
double data[] = sample(f, min, max, n);
|
||||||
double scaling_coefficient = 1.0 / Math.sqrt(n);
|
double scaling_coefficient = 1.0 / Math.sqrt(n);
|
||||||
|
@ -289,11 +284,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @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
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public Complex[] inversetransform2(Complex f[]) throws MathException,
|
public Complex[] inversetransform2(Complex f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
computeOmega(-f.length); // pass negative argument
|
computeOmega(-f.length); // pass negative argument
|
||||||
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
double scaling_coefficient = 1.0 / Math.sqrt(f.length);
|
||||||
|
@ -306,11 +300,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @param isInverse the indicator of forward or inverse transform
|
* @param isInverse the indicator of forward or inverse transform
|
||||||
* @return the complex transformed array
|
* @return the complex transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
protected Complex[] fft(double f[], boolean isInverse) throws
|
protected Complex[] fft(double f[], boolean isInverse)
|
||||||
MathException, IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
verifyDataSet(f);
|
verifyDataSet(f);
|
||||||
Complex F[] = new Complex[f.length];
|
Complex F[] = new Complex[f.length];
|
||||||
|
@ -350,11 +343,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @param data the complex data array to be transformed
|
* @param data the complex data array to be transformed
|
||||||
* @return the complex transformed array
|
* @return the complex transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
protected Complex[] fft(Complex data[]) throws MathException,
|
protected Complex[] fft(Complex data[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
int i, j, k, m, N = data.length;
|
int i, j, k, m, N = data.length;
|
||||||
Complex A, B, C, D, E, F, z, f[] = new Complex[N];
|
Complex A, B, C, D, E, F, z, f[] = new Complex[N];
|
||||||
|
@ -421,10 +413,11 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param n the integer passed in
|
* @param n the integer passed in
|
||||||
* @throws IllegalArgumentException if n = 0
|
* @throws IllegalArgumentException if n = 0
|
||||||
*/
|
*/
|
||||||
protected void computeOmega(int n) throws IllegalArgumentException {
|
protected void computeOmega(int n)
|
||||||
|
throws IllegalArgumentException {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
throw new IllegalArgumentException
|
throw MathRuntimeException.createIllegalArgumentException("cannot compute 0-th root of unity, indefinite result",
|
||||||
("Cannot compute 0-th root of unity, indefinite result.");
|
null);
|
||||||
}
|
}
|
||||||
// avoid repetitive calculations
|
// avoid repetitive calculations
|
||||||
if (n == omegaCount) { return; }
|
if (n == omegaCount) { return; }
|
||||||
|
@ -462,15 +455,17 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the 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 MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public static double[] sample(
|
public static double[] sample(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
throw new IllegalArgumentException("Number of samples not positive.");
|
throw MathRuntimeException.createIllegalArgumentException("number of sample is not positive: {0}",
|
||||||
|
new Object[] { n });
|
||||||
}
|
}
|
||||||
verifyInterval(min, max);
|
verifyInterval(min, max);
|
||||||
|
|
||||||
|
@ -530,8 +525,8 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*/
|
*/
|
||||||
public static void verifyDataSet(double d[]) throws IllegalArgumentException {
|
public static void verifyDataSet(double d[]) throws IllegalArgumentException {
|
||||||
if (!isPowerOf2(d.length)) {
|
if (!isPowerOf2(d.length)) {
|
||||||
throw new IllegalArgumentException
|
throw MathRuntimeException.createIllegalArgumentException("{0} is not a power of 2, consider padding for fix",
|
||||||
("Number of samples not power of 2, consider padding for fix.");
|
new Object[] { d.length });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,8 +538,8 @@ public class FastFourierTransformer implements Serializable {
|
||||||
*/
|
*/
|
||||||
public static void verifyDataSet(Object o[]) throws IllegalArgumentException {
|
public static void verifyDataSet(Object o[]) throws IllegalArgumentException {
|
||||||
if (!isPowerOf2(o.length)) {
|
if (!isPowerOf2(o.length)) {
|
||||||
throw new IllegalArgumentException
|
throw MathRuntimeException.createIllegalArgumentException("{0} is not a power of 2, consider padding for fix",
|
||||||
("Number of samples not power of 2, consider padding for fix.");
|
new Object[] { o.length });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,13 +550,12 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param upper upper endpoint
|
* @param upper upper endpoint
|
||||||
* @throws IllegalArgumentException if not interval
|
* @throws IllegalArgumentException if not interval
|
||||||
*/
|
*/
|
||||||
public static void verifyInterval(double lower, double upper) throws
|
public static void verifyInterval(double lower, double upper)
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
if (lower >= upper) {
|
if (lower >= upper) {
|
||||||
throw new IllegalArgumentException
|
throw MathRuntimeException.createIllegalArgumentException("endpoints do not specify an interval: [{0}, {1}]",
|
||||||
("Endpoints do not specify an interval: [" + lower +
|
new Object[] { lower, upper });
|
||||||
", " + upper + "]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,9 +571,10 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param mdca Multi-Dimensional Complex Array id est Complex[][][][]
|
* @param mdca Multi-Dimensional Complex Array id est Complex[][][][]
|
||||||
* @param forward inverseTransform2 is preformed if this is false
|
* @param forward inverseTransform2 is preformed if this is false
|
||||||
* @return transform of mdca as a Multi-Dimensional Complex Array id est Complex[][][][]
|
* @return transform of mdca as a Multi-Dimensional Complex Array id est Complex[][][][]
|
||||||
* @throws MathException 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) throws MathException {
|
public Object mdfft(Object mdca, boolean forward)
|
||||||
|
throws IllegalArgumentException {
|
||||||
MultiDimensionalComplexMatrix mdcm = (MultiDimensionalComplexMatrix)
|
MultiDimensionalComplexMatrix mdcm = (MultiDimensionalComplexMatrix)
|
||||||
new MultiDimensionalComplexMatrix(mdca).clone();
|
new MultiDimensionalComplexMatrix(mdca).clone();
|
||||||
int[] dimensionSize = mdcm.getDimensionSizes();
|
int[] dimensionSize = mdcm.getDimensionSizes();
|
||||||
|
@ -597,10 +592,11 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param forward inverseTransform2 is preformed if this is false
|
* @param forward inverseTransform2 is preformed if this is 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 MathException if any dimension is not a power of two
|
* @throws IllegalArgumentException if any dimension is not a power of two
|
||||||
*/
|
*/
|
||||||
private void mdfft(MultiDimensionalComplexMatrix mdcm, boolean forward,
|
private void mdfft(MultiDimensionalComplexMatrix mdcm, boolean forward,
|
||||||
int d, int[] subVector) throws MathException {
|
int d, int[] subVector)
|
||||||
|
throws IllegalArgumentException {
|
||||||
int[] dimensionSize = mdcm.getDimensionSizes();
|
int[] dimensionSize = mdcm.getDimensionSizes();
|
||||||
//if done
|
//if done
|
||||||
if (subVector.length == dimensionSize.length) {
|
if (subVector.length == dimensionSize.length) {
|
||||||
|
@ -646,8 +642,8 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* http://jcp.org/en/jsr/detail?id=83
|
* http://jcp.org/en/jsr/detail?id=83
|
||||||
* may require additional exception throws for other basic requirements.
|
* may require additional exception throws for other basic requirements.
|
||||||
*/
|
*/
|
||||||
private class MultiDimensionalComplexMatrix implements Serializable,
|
private class MultiDimensionalComplexMatrix
|
||||||
Cloneable {
|
implements Serializable, Cloneable {
|
||||||
|
|
||||||
/** Serializable version identifier. */
|
/** Serializable version identifier. */
|
||||||
private static final long serialVersionUID = 0x564FCD47EBA8169BL;
|
private static final long serialVersionUID = 0x564FCD47EBA8169BL;
|
||||||
|
@ -693,11 +689,20 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* Get a matrix element.
|
* Get a matrix element.
|
||||||
* @param vector indices of the element
|
* @param vector indices of the element
|
||||||
* @return matrix element
|
* @return matrix element
|
||||||
|
* @exception IllegalArgumentException if dimensions do not match
|
||||||
*/
|
*/
|
||||||
public Complex get(int... vector) {
|
public Complex get(int... vector)
|
||||||
if ((vector == null && dimensionSize.length > 1) ||
|
throws IllegalArgumentException {
|
||||||
(vector != null && vector.length != dimensionSize.length)) {
|
if (vector == null && dimensionSize.length > 1) {
|
||||||
throw new IllegalArgumentException("Number of dimensions must match");
|
throw MathRuntimeException.createIllegalArgumentException("some dimensions don't math: {0} != {1}",
|
||||||
|
new Object[] { 0, dimensionSize.length });
|
||||||
|
}
|
||||||
|
if (vector != null && vector.length != dimensionSize.length) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException("some dimensions don't math: {0} != {1}",
|
||||||
|
new Object[] {
|
||||||
|
vector.length,
|
||||||
|
dimensionSize.length
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Object lastDimension = multiDimensionalComplexArray;
|
Object lastDimension = multiDimensionalComplexArray;
|
||||||
|
@ -713,11 +718,20 @@ public class FastFourierTransformer implements Serializable {
|
||||||
* @param magnitude magnitude of the element
|
* @param magnitude magnitude of the element
|
||||||
* @param vector indices of the element
|
* @param vector indices of the element
|
||||||
* @return the previous value
|
* @return the previous value
|
||||||
|
* @exception IllegalArgumentException if dimensions do not match
|
||||||
*/
|
*/
|
||||||
public Complex set(Complex magnitude, int... vector) {
|
public Complex set(Complex magnitude, int... vector)
|
||||||
if ((vector == null && dimensionSize.length > 1) ||
|
throws IllegalArgumentException {
|
||||||
(vector != null && vector.length != dimensionSize.length)) {
|
if (vector == null && dimensionSize.length > 1) {
|
||||||
throw new IllegalArgumentException("Number of dimensions must match");
|
throw MathRuntimeException.createIllegalArgumentException("some dimensions don't math: {0} != {1}",
|
||||||
|
new Object[] { 0, dimensionSize.length });
|
||||||
|
}
|
||||||
|
if (vector != null && vector.length != dimensionSize.length) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException("some dimensions don't math: {0} != {1}",
|
||||||
|
new Object[] {
|
||||||
|
vector.length,
|
||||||
|
dimensionSize.length
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Object lastDimension = multiDimensionalComplexArray;
|
Object lastDimension = multiDimensionalComplexArray;
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.commons.math.transform;
|
package org.apache.commons.math.transform;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import org.apache.commons.math.FunctionEvaluationException;
|
||||||
|
|
||||||
import org.apache.commons.math.MathRuntimeException;
|
import org.apache.commons.math.MathRuntimeException;
|
||||||
|
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the <a href="http://www.archive.chipcenter.com/dsp/DSP000517F1.html">Fast Hadamard Transform</a> (FHT).
|
* Implements the <a href="http://www.archive.chipcenter.com/dsp/DSP000517F1.html">Fast Hadamard Transform</a> (FHT).
|
||||||
|
@ -26,22 +26,35 @@ import org.apache.commons.math.MathRuntimeException;
|
||||||
* @version $Revision$ $Date$
|
* @version $Revision$ $Date$
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public class FastHadamardTransformer implements Serializable {
|
public class FastHadamardTransformer implements RealTransformer {
|
||||||
|
|
||||||
/** Serializable version identifier. */
|
/** Serializable version identifier. */
|
||||||
private static final long serialVersionUID = 5044269102877526860L;
|
private static final long serialVersionUID = -710169279109099264L;
|
||||||
|
|
||||||
/**
|
/** {@inheritDoc} */
|
||||||
* Wrapper method for fht() for double vectors
|
public double[] transform(double f[]) throws IllegalArgumentException {
|
||||||
*
|
return fht(f);
|
||||||
* @param x input vector
|
|
||||||
* @return y output vector
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
*/
|
|
||||||
public double[] transform(double x[]) throws IllegalArgumentException {
|
|
||||||
return fht(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public double[] transform(UnivariateRealFunction f,
|
||||||
|
double min, double max, int n)
|
||||||
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
return fht(FastFourierTransformer.sample(f, min, max, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public double[] inversetransform(double f[])
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
return fht(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public double[] inversetransform(UnivariateRealFunction f,
|
||||||
|
double min, double max, int n)
|
||||||
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
return fht(FastFourierTransformer.sample(f, min, max, n));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FHT (Fast Hadamard Transformation) which uses only subtraction and addition.
|
* The FHT (Fast Hadamard Transformation) which uses only subtraction and addition.
|
||||||
|
@ -123,16 +136,11 @@ public class FastHadamardTransformer implements Serializable {
|
||||||
protected double[] fht(double x[]) throws IllegalArgumentException {
|
protected double[] fht(double x[]) throws IllegalArgumentException {
|
||||||
|
|
||||||
// n is the row count of the input vector x
|
// n is the row count of the input vector x
|
||||||
int n = x.length;
|
final int n = x.length;
|
||||||
|
final int halfN = n / 2;
|
||||||
|
|
||||||
// n has to be of the form n = 2^p !!
|
// n has to be of the form n = 2^p !!
|
||||||
int p = 0;
|
if (!FastFourierTransformer.isPowerOf2(n)) {
|
||||||
int twoP = 1;
|
|
||||||
while (twoP < n) {
|
|
||||||
++p;
|
|
||||||
twoP *= 2;
|
|
||||||
}
|
|
||||||
if (n != twoP) {
|
|
||||||
throw MathRuntimeException.createIllegalArgumentException("{0} is not a power of 2",
|
throw MathRuntimeException.createIllegalArgumentException("{0} is not a power of 2",
|
||||||
new Object[] { n });
|
new Object[] { n });
|
||||||
}
|
}
|
||||||
|
@ -143,7 +151,7 @@ public class FastHadamardTransformer implements Serializable {
|
||||||
double[] yCurrent = x.clone();
|
double[] yCurrent = x.clone();
|
||||||
|
|
||||||
// iterate from left to right (column)
|
// iterate from left to right (column)
|
||||||
for (int j = 0; j < p; j++) {
|
for (int j = 1; j < n; j <<= 1) {
|
||||||
|
|
||||||
// switch columns
|
// switch columns
|
||||||
final double[] yTmp = yCurrent;
|
final double[] yTmp = yCurrent;
|
||||||
|
@ -151,16 +159,17 @@ public class FastHadamardTransformer implements Serializable {
|
||||||
yPrevious = yTmp;
|
yPrevious = yTmp;
|
||||||
|
|
||||||
// iterate from top to bottom (row)
|
// iterate from top to bottom (row)
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < halfN; ++i) {
|
||||||
if (i < n / 2) {
|
// D<sub>top</sub>
|
||||||
// D<sub>top</sub>
|
// The top part works with addition
|
||||||
// The top part works with addition
|
final int twoI = 2 * i;
|
||||||
yCurrent[i] = yPrevious[i*2] + yPrevious[i*2 +1];
|
yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1];
|
||||||
} else {
|
}
|
||||||
// D<sub>bottom</sub>
|
for (int i = halfN; i < n; ++i) {
|
||||||
// The bottom part works with subtraction
|
// D<sub>bottom</sub>
|
||||||
yCurrent[i] = yPrevious[(i-n/2)*2] - yPrevious[(i-n/2)*2 +1];
|
// The bottom part works with subtraction
|
||||||
}
|
final int twoI = 2 * i;
|
||||||
|
yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.commons.math.transform;
|
package org.apache.commons.math.transform;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import org.apache.commons.math.analysis.*;
|
import org.apache.commons.math.analysis.*;
|
||||||
import org.apache.commons.math.complex.*;
|
import org.apache.commons.math.complex.*;
|
||||||
import org.apache.commons.math.MathException;
|
import org.apache.commons.math.FunctionEvaluationException;
|
||||||
|
import org.apache.commons.math.MathRuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/
|
* Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/
|
||||||
|
@ -37,10 +37,10 @@ import org.apache.commons.math.MathException;
|
||||||
* @version $Revision$ $Date$
|
* @version $Revision$ $Date$
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public class FastSineTransformer implements Serializable {
|
public class FastSineTransformer implements RealTransformer {
|
||||||
|
|
||||||
/** serializable version identifier */
|
/** serializable version identifier */
|
||||||
static final long serialVersionUID = -478002039949390854L;
|
private static final long serialVersionUID = -7557024407476823001L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a default transformer.
|
* Construct a default transformer.
|
||||||
|
@ -57,12 +57,10 @@ public class FastSineTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform(double f[]) throws MathException,
|
public double[] transform(double f[])
|
||||||
IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
return fst(f);
|
return fst(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,12 +75,13 @@ public class FastSineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform(
|
public double[] transform(UnivariateRealFunction f,
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
||||||
data[0] = 0.0;
|
data[0] = 0.0;
|
||||||
|
@ -97,11 +96,9 @@ public class FastSineTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform2(double f[]) throws MathException,
|
public double[] transform2(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
double scaling_coefficient = Math.sqrt(2.0 / f.length);
|
double scaling_coefficient = Math.sqrt(2.0 / f.length);
|
||||||
return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient);
|
return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient);
|
||||||
|
@ -118,12 +115,13 @@ public class FastSineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] transform2(
|
public double[] transform2(
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
UnivariateRealFunction f, double min, double max, int n)
|
||||||
throws MathException, IllegalArgumentException {
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
|
|
||||||
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
||||||
data[0] = 0.0;
|
data[0] = 0.0;
|
||||||
|
@ -139,11 +137,9 @@ public class FastSineTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @param f the real data array to be inversely transformed
|
* @param f the real data array to be inversely transformed
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform(double f[]) throws MathException,
|
public double[] inversetransform(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
double scaling_coefficient = 2.0 / f.length;
|
double scaling_coefficient = 2.0 / f.length;
|
||||||
return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient);
|
return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient);
|
||||||
|
@ -160,12 +156,12 @@ public class FastSineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform(
|
public double[] inversetransform(UnivariateRealFunction f, double min, double max, int n)
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
throws MathException, IllegalArgumentException {
|
|
||||||
|
|
||||||
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
double data[] = FastFourierTransformer.sample(f, min, max, n);
|
||||||
data[0] = 0.0;
|
data[0] = 0.0;
|
||||||
|
@ -181,11 +177,9 @@ public class FastSineTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @param f the real data array to be inversely transformed
|
* @param f the real data array to be inversely transformed
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform2(double f[]) throws MathException,
|
public double[] inversetransform2(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
return transform2(f);
|
return transform2(f);
|
||||||
}
|
}
|
||||||
|
@ -201,12 +195,12 @@ public class FastSineTransformer implements Serializable {
|
||||||
* @param max the upper bound for the interval
|
* @param max the upper bound for the interval
|
||||||
* @param n the number of sample points
|
* @param n the number of sample points
|
||||||
* @return the real inversely transformed array
|
* @return the real inversely transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
public double[] inversetransform2(
|
public double[] inversetransform2(UnivariateRealFunction f, double min, double max, int n)
|
||||||
UnivariateRealFunction f, double min, double max, int n)
|
throws FunctionEvaluationException, IllegalArgumentException {
|
||||||
throws MathException, IllegalArgumentException {
|
|
||||||
|
|
||||||
return transform2(f, min, max, n);
|
return transform2(f, min, max, n);
|
||||||
}
|
}
|
||||||
|
@ -216,18 +210,16 @@ public class FastSineTransformer implements Serializable {
|
||||||
*
|
*
|
||||||
* @param f the real data array to be transformed
|
* @param f the real data array to be transformed
|
||||||
* @return the real transformed array
|
* @return the real transformed array
|
||||||
* @throws MathException if any math-related errors occur
|
|
||||||
* @throws IllegalArgumentException if any parameters are invalid
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
*/
|
*/
|
||||||
protected double[] fst(double f[]) throws MathException,
|
protected double[] fst(double f[]) throws IllegalArgumentException {
|
||||||
IllegalArgumentException {
|
|
||||||
|
|
||||||
double A, B, x[], F[] = new double[f.length];
|
double A, B, x[], F[] = new double[f.length];
|
||||||
|
|
||||||
FastFourierTransformer.verifyDataSet(f);
|
FastFourierTransformer.verifyDataSet(f);
|
||||||
if (f[0] != 0.0) {
|
if (f[0] != 0.0) {
|
||||||
throw new IllegalArgumentException
|
throw MathRuntimeException.createIllegalArgumentException("first element is not 0: {0}",
|
||||||
("The first element is not zero: " + f[0]);
|
new Object[] { f[0] });
|
||||||
}
|
}
|
||||||
int N = f.length;
|
int N = f.length;
|
||||||
if (N == 1) { // trivial case
|
if (N == 1) { // trivial case
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
package org.apache.commons.math.transform;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.apache.commons.math.FunctionEvaluationException;
|
||||||
|
import org.apache.commons.math.analysis.UnivariateRealFunction;
|
||||||
|
import org.apache.commons.math.complex.Complex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for one-dimensional data sets transformations producing real results.
|
||||||
|
* <p>Such transforms include {@link FastSineTransformer sine transform},
|
||||||
|
* {@link FastCosineTransformer cosine transform} or {@link
|
||||||
|
* FastHadamardTransformer Hadamard transform}. {@link FastFourierTransformer
|
||||||
|
* Fourier transform} is of a different kind and does not implement this
|
||||||
|
* interface since it produces {@link Complex complex} results instead of real
|
||||||
|
* ones.
|
||||||
|
* </p>
|
||||||
|
* @version $Revision$ $Date$
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public interface RealTransformer extends Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given real data set.
|
||||||
|
* @param f the real data array to be transformed (signal)
|
||||||
|
* @return the real transformed array (spectrum)
|
||||||
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
|
*/
|
||||||
|
double[] transform(double f[])
|
||||||
|
throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the given real function, sampled on the given interval.
|
||||||
|
* @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 FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
|
*/
|
||||||
|
double[] transform(UnivariateRealFunction f, double min, double max, int n)
|
||||||
|
throws FunctionEvaluationException, IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inversely transform the given real data set.
|
||||||
|
* @param f the real data array to be inversely transformed (spectrum)
|
||||||
|
* @return the real inversely transformed array (signal)
|
||||||
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
|
*/
|
||||||
|
public abstract double[] inversetransform(double f[])
|
||||||
|
throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inversely transform the given 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 n the number of sample points
|
||||||
|
* @return the real inversely transformed array
|
||||||
|
* @throws FunctionEvaluationException if function cannot be evaluated
|
||||||
|
* at some point
|
||||||
|
* @throws IllegalArgumentException if any parameters are invalid
|
||||||
|
*/
|
||||||
|
double[] inversetransform(UnivariateRealFunction f, double min, double max, int n)
|
||||||
|
throws FunctionEvaluationException, IllegalArgumentException;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue