Removed references to deprecated MathRuntimeException (MATH-677).

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1227008 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastien Brisard 2012-01-04 00:57:19 +00:00
parent 2d16e3fe0a
commit 2689ee367b
1 changed files with 87 additions and 50 deletions

View File

@ -16,8 +16,10 @@
*/ */
package org.apache.commons.math.transform; package org.apache.commons.math.transform;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateFunction; import org.apache.commons.math.analysis.UnivariateFunction;
import org.apache.commons.math.exception.MathIllegalArgumentException;
import org.apache.commons.math.exception.NonMonotonicSequenceException;
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.util.LocalizedFormats; import org.apache.commons.math.exception.util.LocalizedFormats;
/** /**
@ -33,44 +35,79 @@ import org.apache.commons.math.exception.util.LocalizedFormats;
*/ */
public class FastHadamardTransformer implements RealTransformer { public class FastHadamardTransformer implements RealTransformer {
/** {@inheritDoc} */ /**
public double[] transform(double[] f) * {@inheritDoc}
throws IllegalArgumentException { *
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/
public double[] transform(double[] f) throws MathIllegalArgumentException {
return fht(f); return fht(f);
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two
*/
public double[] transform(UnivariateFunction f, public double[] transform(UnivariateFunction f,
double min, double max, int n) double min, double max, int n) throws
throws IllegalArgumentException { NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
return fht(FastFourierTransformer.sample(f, min, max, n)); return fht(FastFourierTransformer.sample(f, min, max, n));
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/
public double[] inverseTransform(double[] f) public double[] inverseTransform(double[] f)
throws IllegalArgumentException { throws IllegalArgumentException {
return FastFourierTransformer.scaleArray(fht(f), 1.0 / f.length); return FastFourierTransformer.scaleArray(fht(f), 1.0 / f.length);
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two
*/
public double[] inverseTransform(UnivariateFunction f, public double[] inverseTransform(UnivariateFunction f,
double min, double max, int n) double min, double max, int n) throws
throws IllegalArgumentException { NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
final double[] unscaled = final double[] unscaled =
fht(FastFourierTransformer.sample(f, min, max, n)); fht(FastFourierTransformer.sample(f, min, max, n));
return FastFourierTransformer.scaleArray(unscaled, 1.0 / n); return FastFourierTransformer.scaleArray(unscaled, 1.0 / n);
} }
/** /**
* Transform the given real data set. * Returns the forward transform of the specified integer data set.The
* <p>The integer transform cannot be inverted directly, due to a scaling * integer transform cannot be inverted directly, due to a scaling factor
* factor it may lead to double results.</p> * which may lead to double results.
*
* @param f the integer data array to be transformed (signal) * @param f the integer data array to be transformed (signal)
* @return the integer transformed array (spectrum) * @return the integer transformed array (spectrum)
* @throws IllegalArgumentException if any parameters are invalid * @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/ */
public int[] transform(int[] f) public int[] transform(int[] f) throws MathIllegalArgumentException {
throws IllegalArgumentException {
return fht(f); return fht(f);
} }
@ -212,25 +249,26 @@ public class FastHadamardTransformer implements RealTransformer {
* </tbody> * </tbody>
* </table> * </table>
* *
* @param x the input vector * @param x the real data array to be transformed
* @return the output vector, {@code y} * @return the real transformed array, {@code y}
* @exception IllegalArgumentException if input array is not a power of 2 * @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/ */
protected double[] fht(double[] x) throws IllegalArgumentException { protected double[] fht(double[] x) throws MathIllegalArgumentException {
// n is the row count of the input vector x
final int n = x.length; final int n = x.length;
final int halfN = n / 2; final int halfN = n / 2;
// n has to be of the form n = 2^p !!
if (!FastFourierTransformer.isPowerOf2(n)) { if (!FastFourierTransformer.isPowerOf2(n)) {
throw MathRuntimeException.createIllegalArgumentException( throw new MathIllegalArgumentException(
LocalizedFormats.NOT_POWER_OF_TWO, LocalizedFormats.NOT_POWER_OF_TWO,
n); Integer.valueOf(n));
} }
// Instead of creating a matrix with p+1 columns and n rows /*
// we will use two single dimension arrays which we will use in an alternating way. * Instead of creating a matrix with p+1 columns and n rows, we use two
* one dimension arrays which we are used in an alternating way.
*/
double[] yPrevious = new double[n]; double[] yPrevious = new double[n];
double[] yCurrent = x.clone(); double[] yCurrent = x.clone();
@ -244,44 +282,45 @@ public class FastHadamardTransformer implements RealTransformer {
// iterate from top to bottom (row) // iterate from top to bottom (row)
for (int i = 0; i < halfN; ++i) { for (int i = 0; i < halfN; ++i) {
// D<sub>top</sub> // Dtop: the top part works with addition
// The top part works with addition
final int twoI = 2 * i; final int twoI = 2 * i;
yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1]; yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1];
} }
for (int i = halfN; i < n; ++i) { for (int i = halfN; i < n; ++i) {
// D<sub>bottom</sub> // Dbottom: the bottom part works with subtraction
// The bottom part works with subtraction
final int twoI = 2 * i; final int twoI = 2 * i;
yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1]; yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1];
} }
} }
// return the last computed output vector y
return yCurrent; return yCurrent;
} }
/**
* The FHT (Fast Hadamard Transformation) which uses only subtraction and addition.
* @param x input vector
* @return y output vector
* @exception IllegalArgumentException if input array is not a power of 2
*/
protected int[] fht(int[] x) throws IllegalArgumentException {
// n is the row count of the input vector x /**
* Returns the forward transform of the specified integer data set. The FHT
* (Fast Hadamard Transform) uses only subtraction and addition.
*
* @param x the integer data array to be transformed
* @return the integer transformed array, {@code y}
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/
protected int[] fht(int[] x) throws MathIllegalArgumentException {
final int n = x.length; final int n = x.length;
final int halfN = n / 2; final int halfN = n / 2;
// n has to be of the form n = 2^p !!
if (!FastFourierTransformer.isPowerOf2(n)) { if (!FastFourierTransformer.isPowerOf2(n)) {
throw MathRuntimeException.createIllegalArgumentException( throw new MathIllegalArgumentException(
LocalizedFormats.NOT_POWER_OF_TWO, LocalizedFormats.NOT_POWER_OF_TWO,
n); Integer.valueOf(n));
} }
// Instead of creating a matrix with p+1 columns and n rows /*
// we will use two single dimension arrays which we will use in an alternating way. * Instead of creating a matrix with p+1 columns and n rows, we use two
* one dimension arrays which we are used in an alternating way.
*/
int[] yPrevious = new int[n]; int[] yPrevious = new int[n];
int[] yCurrent = x.clone(); int[] yCurrent = x.clone();
@ -295,14 +334,12 @@ public class FastHadamardTransformer implements RealTransformer {
// iterate from top to bottom (row) // iterate from top to bottom (row)
for (int i = 0; i < halfN; ++i) { for (int i = 0; i < halfN; ++i) {
// D<sub>top</sub> // Dtop: the top part works with addition
// The top part works with addition
final int twoI = 2 * i; final int twoI = 2 * i;
yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1]; yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1];
} }
for (int i = halfN; i < n; ++i) { for (int i = halfN; i < n; ++i) {
// D<sub>bottom</sub> // Dbottom: the bottom part works with subtraction
// The bottom part works with subtraction
final int twoI = 2 * i; final int twoI = 2 * i;
yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1]; yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1];
} }