MATH-1290 Utilities for manipulating arrays of complex numbers. Also fixes * MATH-1291: method name change * MATH-1349: method for checking equality of arrays of complex numbers (in unit tests)
Thanks to Eric Barnhill. Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/3ab3653e Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/3ab3653e Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/3ab3653e Branch: refs/heads/develop Commit: 3ab3653e48f65bc273c1fb2522cd814ceed8e396 Parents: 7a8dc00 Author: Gilles <er...@apache.org> Authored: Sun Mar 27 01:01:58 2016 +0100 Committer: Gilles <er...@apache.org> Committed: Sun Mar 27 01:01:58 2016 +0100 ---------------------------------------------------------------------- .../math4/analysis/solvers/LaguerreSolver.java | 6 +- .../commons/math4/complex/ComplexUtils.java | 2443 +++++++++++++++++- .../org/apache/commons/math4/TestUtils.java | 68 + .../commons/math4/complex/ComplexUtilsTest.java | 565 +++- 4 files changed, 3012 insertions(+), 70 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/3ab3653e/src/main/java/org/apache/commons/math4/analysis/solvers/LaguerreSolver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/analysis/solvers/LaguerreSolver.java b/src/main/java/org/apache/commons/math4/analysis/solvers/LaguerreSolver.java index b038abb..ab01885 100644 --- a/src/main/java/org/apache/commons/math4/analysis/solvers/LaguerreSolver.java +++ b/src/main/java/org/apache/commons/math4/analysis/solvers/LaguerreSolver.java @@ -147,7 +147,7 @@ public class LaguerreSolver extends AbstractPolynomialSolver { * @return the point at which the function value is zero. */ private double laguerre(double lo, double hi) { - final Complex c[] = ComplexUtils.convertToComplex(getCoefficients()); + final Complex c[] = ComplexUtils.real2Complex(getCoefficients()); final Complex initial = new Complex(0.5 * (lo + hi), 0); final Complex z = complexSolver.solve(c, initial); @@ -193,7 +193,7 @@ public class LaguerreSolver extends AbstractPolynomialSolver { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, initial); - return complexSolver.solveAll(ComplexUtils.convertToComplex(coefficients), + return complexSolver.solveAll(ComplexUtils.real2Complex(coefficients), new Complex(initial, 0d)); } @@ -223,7 +223,7 @@ public class LaguerreSolver extends AbstractPolynomialSolver { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, initial); - return complexSolver.solve(ComplexUtils.convertToComplex(coefficients), + return complexSolver.solve(ComplexUtils.real2Complex(coefficients), new Complex(initial, 0d)); } http://git-wip-us.apache.org/repos/asf/commons-math/blob/3ab3653e/src/main/java/org/apache/commons/math4/complex/ComplexUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/complex/ComplexUtils.java b/src/main/java/org/apache/commons/math4/complex/ComplexUtils.java index 493374f..2f01f0e 100644 --- a/src/main/java/org/apache/commons/math4/complex/ComplexUtils.java +++ b/src/main/java/org/apache/commons/math4/complex/ComplexUtils.java @@ -18,69 +18,2458 @@ package org.apache.commons.math4.complex; import org.apache.commons.math4.exception.MathIllegalArgumentException; +import org.apache.commons.math4.exception.OutOfRangeException; import org.apache.commons.math4.exception.util.LocalizedFormats; import org.apache.commons.math4.util.FastMath; +import org.apache.commons.math4.util.IntegerSequence; +import org.apache.commons.math4.util.IntegerSequence.Range; /** - * Static implementations of common - * {@link org.apache.commons.math4.complex.Complex} utilities functions. - * + * Static implementations of common {@link Complex} utilities functions. */ public class ComplexUtils { /** - * Default constructor. + * Utility class. */ private ComplexUtils() {} /** * Creates a complex number from the given polar representation. * <p> - * The value returned is <code>r·e<sup>i·theta</sup></code>, - * computed as <code>r·cos(theta) + r·sin(theta)i</code></p> + * The value returned is {@code r·e<sup>i·theta</sup>}, + * computed as {@code r·cos(theta) + r·sin(theta)i} * <p> - * If either <code>r</code> or <code>theta</code> is NaN, or - * <code>theta</code> is infinite, {@link Complex#NaN} is returned.</p> + * If either {@code r} or {@code theta} is NaN, or {@code theta} is + * infinite, {@link Complex#NaN} is returned. * <p> - * If <code>r</code> is infinite and <code>theta</code> is finite, - * infinite or NaN values may be returned in parts of the result, following - * the rules for double arithmetic.<pre> + * If {@code r} is infinite and {@code theta} is finite, infinite or NaN + * values may be returned in parts of the result, following the rules for + * double arithmetic. + * + * <pre> * Examples: - * <code> + * {@code * polar2Complex(INFINITY, π/4) = INFINITY + INFINITY i * polar2Complex(INFINITY, 0) = INFINITY + NaN i * polar2Complex(INFINITY, -π/4) = INFINITY - INFINITY i - * polar2Complex(INFINITY, 5π/4) = -INFINITY - INFINITY i </code></pre></p> + * polar2Complex(INFINITY, 5π/4) = -INFINITY - INFINITY i } + * </pre> * - * @param r the modulus of the complex number to create - * @param theta the argument of the complex number to create - * @return <code>r·e<sup>i·theta</sup></code> - * @throws MathIllegalArgumentException if {@code r} is negative. + * @param r + * the modulus of the complex number to create + * @param theta + * the argument of the complex number to create + * @return {@code Complex} + * @throws MathIllegalArgumentException + * if {@code r} is negative. * @since 1.1 */ public static Complex polar2Complex(double r, double theta) throws MathIllegalArgumentException { if (r < 0) { - throw new MathIllegalArgumentException( - LocalizedFormats.NEGATIVE_COMPLEX_MODULE, r); + throw new MathIllegalArgumentException(LocalizedFormats.NEGATIVE_COMPLEX_MODULE, r); } return new Complex(r * FastMath.cos(theta), r * FastMath.sin(theta)); } /** - * Convert an array of primitive doubles to an array of {@code Complex} objects. + * Creates {@code Complex[]} array given {@code double[]} arrays of r and + * theta. + * + * @param r {@code double[]} of moduli + * @param theta {@code double[]} of arguments + * @return {@code Complex[]} + * @throws MathIllegalArgumentException + * if {@code r} is negative. + * @since 4.0 + */ + public static Complex[] polar2Complex(double[] r, double[] theta) throws MathIllegalArgumentException { + final int length = r.length; + final Complex[] c = new Complex[length]; + for (int x = 0; x < length; x++) { + if (r[x] < 0) { + throw new MathIllegalArgumentException(LocalizedFormats.NEGATIVE_COMPLEX_MODULE, r[x]); + } + c[x] = new Complex(r[x] * FastMath.cos(theta[x]), r[x] * FastMath.sin(theta[x])); + } + return c; + } + + /** + * Creates {@code Complex[][]} array given {@code double[][]} arrays of r + * and theta. + * + * @param r {@code double[]} of moduli + * @param theta {@code double[]} of arguments + * @return {@code Complex[][]} + * @throws MathIllegalArgumentException + * if {@code r} is negative. + * @since 4.0 + */ + public static Complex[][] polar2Complex(double[][] r, double[][] theta) throws MathIllegalArgumentException { + final int length = r.length; + final Complex[][] c = new Complex[length][]; + for (int x = 0; x < length; x++) { + c[x] = polar2Complex(r[x], theta[x]); + } + return c; + } + + /** + * Creates {@code Complex[][][]} array given {@code double[][][]} arrays of + * r and theta. + * + * @param r {@code double[]} of moduli + * @param theta {@code double[]} of arguments + * @return {@code Complex[][][]} + * @throws MathIllegalArgumentException + * if {@code r} is negative. + * @since 4.0 + */ + public static Complex[][][] polar2Complex(double[][][] r, double[][][] theta) throws MathIllegalArgumentException { + final int length = r.length; + final Complex[][][] c = new Complex[length][][]; + for (int x = 0; x < length; x++) { + c[x] = polar2Complex(r[x], theta[x]); + } + return c; + } + + /** + * Returns double from array {@code real[]} at entry {@code index} as a + * {@code Complex}. + * + * @param real + * Array of real numbers. + * @param index + * Location in the array. + * @return {@code Complex}. + * + * @since 4.0 + */ + public static Complex extractComplexFromRealArray(double[] real, int index) { + return new Complex(real[index]); + } + + /** + * Returns float from array {@code real[]} at entry {@code index} as a + * {@code Complex}. + * + * @param real + * Array of real numbers. + * @param index + * Location in the array. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex extractComplexFromRealArray(float[] real, int index) { + return new Complex(real[index]); + } + + /** + * Returns double from array {@code imaginary[]} at entry {@code index} as a + * {@code Complex}. + * + * @param imaginary + * Array of imaginary numbers. + * @param index + * Location in the array. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex extractComplexFromImaginaryArray(double[] imaginary, int index) { + return new Complex(0, imaginary[index]); + } + + /** + * Returns float from array {@code imaginary[]} at entry {@code index} as a + * {@code Complex}. + * + * @param imaginary + * Array of imaginary numbers. + * @param index + * Location in the array. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex extractComplexFromImaginaryArray(float[] imaginary, int index) { + return new Complex(0, imaginary[index]); + } + + /** + * Returns real component of Complex from array {@code Complex[]} at entry + * {@code index} as a {@code double}. + * + * @param complex + * Array of complex numbers. + * @param index + * Location in the array. + * @return {@code double}. + * + * @since 4.0 + */ + public static double extractRealFromComplexArray(Complex[] complex, int index) { + return complex[index].getReal(); + } + + /** + * Returns real component of array {@code Complex[]} at entry {@code index} + * as a {@code float}. + * + * @param complex + * Array of complex numbers. + * @param index + * Location in the array. + * @return {@code float}. + * + * @since 4.0 + */ + public static float extractRealFloatFromComplexArray(Complex[] complex, int index) { + return (float) complex[index].getReal(); + } + + /** + * Returns imaginary component of Complex from array {@code Complex[]} at + * entry {@code index} as a {@code double}. + * + * @param complex + * Array of complex numbers. + * @param index + * Location in the array. + * @return {@code double}. + * + * @since 4.0 + */ + public static double extractImaginaryFromComplexArray(Complex[] complex, int index) { + return complex[index].getImaginary(); + } + + /** + * Returns imaginary component of array {@code Complex[]} at entry + * {@code index} as a {@code float}. + * + * @param complex + * Array of complex numbers. + * @param index + * Location in the array. + * @return {@code float}. + * + * @since 4.0 + */ + public static float extractImaginaryFloatFromComplexArray(Complex[] complex, int index) { + return (float) complex[index].getImaginary(); + } + + /** + * Returns a Complex object from interleaved {@code double[]} array at entry + * {@code index}. + * + * @param d + * {@code double[]} of interleaved complex numbers alternating + * real and imaginary values + * @param index + * Location in the array. This is the location by complex number, + * e.g. index number 5 in the {@code double[]} array will return + * {@code new Complex(d[10], d[11])} + * @return {@code Complex[]}. + * + * @since 4.0 + */ + public static Complex extractComplexFromInterleavedArray(double[] d, int index) { + return new Complex(d[index * 2], d[index * 2 + 1]); + } + + /** + * Returns a Complex object from interleaved {@code float[]} array at entry + * {@code index}. + * + * @param f + * {@code float[]} of interleaved complex numbers alternating + * real and imaginary values + * @param index + * Location in the array. This is the location by complex number, + * e.g. index number 5 in the {@code float[]} array will return + * new {@code Complex(d[10], d[11])} + * @return {@code Complex[]}. + * + * @since 4.0 + */ + public static Complex extractComplexFromInterleavedArray(float[] f, int index) { + return new Complex(f[index * 2], f[index * 2 + 1]); + } + + /** + * Returns values of Complex object from array {@code Complex[]} at entry + * {@code index} as a size 2 {@code double} of the form {real, imag}. + * + * @param complex + * Array of complex numbers. + * @param index + * Location in the array. + * @return size 2 {@code double[]}. + * + * @since 4.0 + */ + public static double[] extractInterleavedFromComplexArray(Complex[] complex, int index) { + return new double[] { complex[index].getReal(), complex[index].getImaginary() }; + } + + /** + * Returns Complex object from array {@code Complex[]} at entry + * {@code index} as a size 2 {@code float} of the form {real, imag}. + * + * @param complex + * {@code Complex[]} array. + * @param index + * Location in the array. + * @return size 2 {@code float[]}. + * + * @since 4.0 + */ + public static float[] extractInterleavedFloatFromComplexArray(Complex[] complex, int index) { + return new float[] { (float) complex[index].getReal(), (float) complex[index].getImaginary() }; + } + + /** + * Converts a {@code double[]} array to a {@code Complex[]} array for the + * range {@code start} - {@code end}. + * + * @param real + * Array of real numbers to be converted to their {@code Complex} + * equivalent. + * @param start + * Start index. + * @param end + * End index. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] real2Complex(double[] real, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromRealArray(real, i); + index++; + } + return c; + } + + /** + * Converts a {@code float[]} array to a {@code Complex[]} array for the + * range {@code start} - {@code end}. + * + * @param real + * Array of real numbers to be converted to their {@code Complex} + * equivalent. + * @param start + * Start index. + * @param end + * End index. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] real2Complex(float[] real, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromRealArray(real, i); + index++; + } + return c; + } + + /** + * Converts a {@code double[]} array to a {@code Complex[]} array for the + * range {@code start} - {@code end} by {@code increment}. + * + * @param real + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] real2Complex(double[] real, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromRealArray(real, i); + index++; + } + return c; + } + + /** + * Converts a {@code float[]} array to a {@code Complex[]} array for the + * range {@code start} - {@code end} by {@code increment}. + * + * @param real + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] real2Complex(float[] real, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromRealArray(real, i); + index++; + } + return c; + } + + /** + * Converts a {@code double[]} array to a {@code Complex[]} array for the + * {@code IntegerSequence} range. + * + * @param real + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] real2Complex(double[] real, Range range) { + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromRealArray(real, i); + index++; + } + return c; + } + + /** + * Converts a {@code float[]} array to a {@code Complex[]} array for the + * {@code IntegerSequence} range. + * + * @param real + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] real2Complex(float[] real, Range range) { + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromRealArray(real, i); + index++; + } + return c; + } + + /** + * Converts a {@code double[]} array to a {@code Complex[]} array. + * + * @param real + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] real2Complex(double[] real) { + int index = 0; + final Complex c[] = new Complex[real.length]; + for (double d : real) { + c[index] = new Complex(d); + index++; + } + return c; + } + + /** + * Converts a {@code float[]} array to a {@code Complex[]} array. * - * @param real Array of numbers to be converted to their {@code Complex} - * equivalent. - * @return an array of {@code Complex} objects. + * @param real + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @return {@code Complex[]} array. * - * @since 3.1 + * @since 4.0 */ - public static Complex[] convertToComplex(double[] real) { + public static Complex[] real2Complex(float[] real) { + int index = 0; final Complex c[] = new Complex[real.length]; - for (int i = 0; i < real.length; i++) { - c[i] = new Complex(real[i], 0); + for (float d : real) { + c[index] = new Complex(d); + index++; + } + return c; + } + + /** + * Converts a 2D real {@code double[][]} array to a 2D {@code Complex[][]} + * array. + * + * @param d + * 2D {@code double[][]} + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] real2Complex(double[][] d) { + final int width = d.length; + final Complex[][] c = new Complex[width][]; + for (int n = 0; n < width; n++) { + c[n] = ComplexUtils.real2Complex(d[n]); + } + return c; + } + + /** + * Converts a 3D real {@code double[][][]} array to a {@code Complex [][][]} + * array. + * + * @param d + * 3D complex interleaved {@code double[][][]} + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] real2Complex(double[][][] d) { + final int width = d.length; + final Complex[][][] c = new Complex[width][][]; + for (int x = 0; x < width; x++) { + c[x] = ComplexUtils.real2Complex(d[x]); + } + return c; + } + + /** + * Converts a {@code Complex[]} array to a {@code double[]} array for the + * range {@code start} - {@code end}. + * + * @param c + * {@code Complex[]} array. + * @param start + * Start index. + * @param end + * End index. + * @return {@code double[]} array of the real component. + * + * @since 4.0 + */ + public static double[] complex2Real(Complex[] c, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final double d[] = new double[range.size()]; + for (Integer i : range) { + d[index] = extractRealFromComplexArray(c, i); + index++; + } + return d; + } + + /** + * Converts a {@code Complex[]} array to a {@code float[]} array for the + * range {@code start} - {@code end}. + * + * @param c + * Complex array + * @param start + * Start index. + * @param end + * End index. + * @return {@code float[]} array of the real component. + * + * @since 4.0 + */ + public static float[] complex2RealFloat(Complex[] c, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final float f[] = new float[range.size()]; + for (Integer i : range) { + f[index] = extractRealFloatFromComplexArray(c, i); + index++; + } + return f; + } + + /** + * Converts a {@code Complex[]} array to a {@code double[]} array for the + * range {@code start} - {@code end} by {@code increment}. + * + * @param c + * {@code Complex[]} array. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code double[]} array of the real component. + * + * @since 4.0 + */ + public static double[] complex2Real(Complex[] c, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final double d[] = new double[range.size()]; + for (Integer i : range) { + d[index] = extractRealFromComplexArray(c, i); + index++; + } + return d; + } + + /** + * Converts a {@code Complex[]} array to a {@code float[]} array for the + * range {@code start} - {@code end} by {@code increment}. + * + * @param c + * {@code Complex[]} array. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code float[]} array of the real component. + * + * @since 4.0 + */ + public static float[] complex2RealFloat(Complex[] c, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final float f[] = new float[range.size()]; + for (Integer i : range) { + f[index] = extractRealFloatFromComplexArray(c, i); + index++; + } + return f; + } + + /** + * Converts a {@code Complex[]} array to a {@code double[]} array for the + * {@code IntegerSequence} range. + * + * @param c + * {@code Complex[]} array. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code double[]} array of the real component. + * + * @since 4.0 + */ + public static double[] complex2Real(Complex[] c, Range range) { + int index = 0; + final double d[] = new double[range.size()]; + for (Integer i : range) { + d[index] = extractRealFromComplexArray(c, i); + index++; + } + return d; + } + + /** + * Converts a {@code Complex[]} array to a {@code float[]} array for the + * {@code IntegerSequence} range. + * + * @param c + * {@code Complex[]} array. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code float[]} array of the real component. + * + * @since 4.0 + */ + public static float[] complex2RealFloat(Complex[] c, Range range) { + int index = 0; + final float f[] = new float[range.size()]; + for (Integer i : range) { + f[index] = extractRealFloatFromComplexArray(c, i); + index++; + } + return f; + } + + /** + * Converts real component of {@code Complex[]} array to a {@code double[]} + * array. + * + * @param c + * {@code Complex[]} array. + * @return {@code double[]} array of the real component. + * + * @since 4.0 + */ + public static double[] complex2Real(Complex[] c) { + int index = 0; + final double d[] = new double[c.length]; + for (Complex cc : c) { + d[index] = cc.getReal(); + index++; + } + return d; + } + + /** + * Converts real component of {@code Complex[]} array to a {@code float[]} + * array. + * + * @param c + * {@code Complex[]} array. + * @return {@code float[]} array of the real component. + * + * @since 4.0 + */ + public static float[] complex2RealFloat(Complex[] c) { + int index = 0; + final float f[] = new float[c.length]; + for (Complex cc : c) { + f[index] = (float) cc.getReal(); + index++; + } + return f; + } + + /** + * Converts real component of a 2D {@code Complex[][]} array to a 2D + * {@code double[][]} array. + * + * @param c + * 2D {@code Complex[][]} array + * @return double[][] of real component + * @since 4.0 + */ + public static double[][] complex2Real(Complex[][] c) { + final int length = c.length; + double[][] d = new double[length][]; + for (int n = 0; n < length; n++) { + d[n] = complex2Real(c[n]); + } + return d; + } + + /** + * Converts real component of a 2D {@code Complex[][]} array to a 2D + * {@code float[][]} array. + * + * @param c + * 2D {@code Complex[][]} array + * @return float[][] of real component + * @since 4.0 + */ + public static float[][] complex2RealFloat(Complex[][] c) { + final int length = c.length; + float[][] f = new float[length][]; + for (int n = 0; n < length; n++) { + f[n] = complex2RealFloat(c[n]); + } + return f; + } + + /** + * Converts real component of a 3D {@code Complex[][][]} array to a 3D + * {@code double[][][]} array. + * + * @param c + * 3D complex interleaved {@code double[][][]} + * @return {@code double[][][]} array of real component + * + * @since 4.0 + */ + public static double[][][] complex2Real(Complex[][][] c) { + final int length = c.length; + double[][][] d = new double[length][][]; + for (int n = 0; n < length; n++) { + d[n] = complex2Real(c[n]); + } + return d; + } + + /** + * Converts real component of a 3D {@code Complex[][][]} array to a 3D + * {@code float[][][]} array. + * + * @param c + * 3D {@code Complex[][][]} array + * @return float[][][] of real component + * @since 4.0 + */ + public static float[][][] complex2RealFloat(Complex[][][] c) { + final int length = c.length; + float[][][] f = new float[length][][]; + for (int n = 0; n < length; n++) { + f[n] = complex2RealFloat(c[n]); } + return f; + } + /** + * Converts a {@code double[]} array to an imaginary {@code Complex[]} array + * for the range {@code start} - {@code end}. + * + * @param imaginary + * Array of imaginary numbers to be converted to their + * {@code Complex} equivalent. + * @param start + * Start index. + * @param end + * End index. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(double[] imaginary, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromImaginaryArray(imaginary, i); + index++; + } return c; } + + /** + * Converts a {@code float[]} array to an imaginary {@code Complex[]} array + * for the range {@code start} - {@code end}. + * + * @param imaginary + * Array of imaginary numbers to be converted to their + * {@code Complex} equivalent. + * @param start + * Start index. + * @param end + * End index. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(float[] imaginary, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromImaginaryArray(imaginary, i); + index++; + } + return c; + } + + /** + * Converts a {@code double[]} array to an imaginary {@code Complex[]} array + * for the range {@code start} - {@code end} by {@code increment}. + * + * @param imaginary + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(double[] imaginary, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromImaginaryArray(imaginary, i); + index++; + } + return c; + } + + /** + * Converts a {@code float[]} array to an imaginary {@code Complex[]} array + * for the range {@code start} - {@code end} by {@code increment}. + * + * @param imaginary + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(float[] imaginary, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromImaginaryArray(imaginary, i); + index++; + } + return c; + } + + /** + * Converts a {@code double[]} array to an imaginary {@code Complex[]} array + * for the {@code IntegerSequence} range. + * + * @param imaginary + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(double[] imaginary, Range range) { + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromImaginaryArray(imaginary, i); + index++; + } + return c; + } + + /** + * Converts a {@code float[]} array to an imaginary {@code Complex[]} array + * for the {@code IntegerSequence} range. + * + * @param imaginary + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(float[] imaginary, Range range) { + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromImaginaryArray(imaginary, i); + index++; + } + return c; + } + + /** + * Converts a {@code double[]} array to an imaginary {@code Complex[]} + * array. + * + * @param imaginary + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(double[] imaginary) { + int index = 0; + final Complex c[] = new Complex[imaginary.length]; + for (double d : imaginary) { + c[index] = new Complex(0, d); + index++; + } + return c; + } + + /** + * Converts a {@code float[]} array to an imaginary {@code Complex[]} array. + * + * @param imaginary + * Array of numbers to be converted to their {@code Complex} + * equivalent. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] imaginary2Complex(float[] imaginary) { + int index = 0; + final Complex c[] = new Complex[imaginary.length]; + for (float d : imaginary) { + c[index] = new Complex(0, d); + index++; + } + return c; + } + + /** + * Converts a 2D imaginary array {@code double[][]} to a 2D + * {@code Complex[][]} array. + * + * @param d + * 2D {@code double[][]} + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] imaginary2Complex(double[][] d) { + int width = d.length; + int height = d[0].length; + Complex[][] c = new Complex[width][height]; + for (int n = 0; n < width; n++) { + c[n] = ComplexUtils.imaginary2Complex(d[n]); + } + return c; + } + + /** + * Converts a 3D imaginary array {@code double[][][]} to a {@code Complex[]} + * array. + * + * @param d + * 3D complex imaginary {@code double[][][]} + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] imaginary2Complex(double[][][] d) { + int width = d.length; + int height = d[0].length; + int depth = d[0].length; + Complex[][][] c = new Complex[width][height][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + c[x][y] = ComplexUtils.imaginary2Complex(d[x][y]); + } + } + return c; + } + + /** + * Converts imaginary part of {@code Complex[]} array to a {@code double[]} + * array for the range {@code start} - {@code end}. + * + * @param c + * {@code Complex[]} array. + * @param start + * Start index. + * @param end + * End index. + * @return {@code double[]} array of the imaginary component. + * + * @since 4.0 + */ + public static double[] complex2Imaginary(Complex[] c, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final double d[] = new double[range.size()]; + for (Integer i : range) { + d[index] = extractImaginaryFromComplexArray(c, i); + index++; + } + return d; + } + + /** + * Converts imaginary part of a {@code Complex[]} array to a {@code float[]} + * array for the range {@code start} - {@code end}. + * + * @param c + * Complex array + * @param start + * Start index. + * @param end + * End index. + * @return {@code float[]} array of the imaginary component. + * + * @since 4.0 + */ + public static float[] complex2ImaginaryFloat(Complex[] c, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final float f[] = new float[range.size()]; + for (Integer i : range) { + f[index] = extractImaginaryFloatFromComplexArray(c, i); + index++; + } + return f; + } + + /** + * Converts imaginary part of a {@code Complex[]} array to a + * {@code double[]} array for the range {@code start} - {@code end} by + * {@code increment}. + * + * @param c + * {@code Complex[]} array. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code double[]} array of the imaginary component. + * + * @since 4.0 + */ + public static double[] complex2Imaginary(Complex[] c, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final double d[] = new double[range.size()]; + for (Integer i : range) { + d[index] = extractImaginaryFromComplexArray(c, i); + index++; + } + return d; + } + + /** + * Converts imaginary part of a {@code Complex[]} array to a {@code float[]} + * array for the range {@code start} - {@code end} by {@code increment}. + * + * @param c + * {@code Complex[]} array. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code float[]} array of the imaginary component. + * + * @since 4.0 + */ + public static float[] complex2ImaginaryFloat(Complex[] c, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final float f[] = new float[range.size()]; + for (Integer i : range) { + f[index] = extractImaginaryFloatFromComplexArray(c, i); + index++; + } + return f; + } + + /** + * Converts imaginary part of a {@code Complex[]} array to a + * {@code double[]} array for the {@code IntegerSequence} range. + * + * @param c + * {@code Complex[]} array. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code double[]} array of the imaginary component. + * + * @since 4.0 + */ + public static double[] complex2Imaginary(Complex[] c, Range range) { + int index = 0; + final double d[] = new double[range.size()]; + for (Integer i : range) { + d[index] = extractImaginaryFromComplexArray(c, i); + index++; + } + return d; + } + + /** + * Converts imaginary part of a {@code Complex[]} array to a {@code float[]} + * array for the {@code IntegerSequence} range. + * + * @param c + * {@code Complex[]} array. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code float[]} array of the imaginary component. + * + * @since 4.0 + */ + public static float[] complex2ImaginaryFloat(Complex[] c, Range range) { + int index = 0; + final float f[] = new float[range.size()]; + for (Integer i : range) { + f[index] = extractImaginaryFloatFromComplexArray(c, i); + index++; + } + return f; + } + + /** + * Converts imaginary part of a {@code Complex[]} array to a + * {@code double[]} array. + * + * @param c + * {@code Complex[]} array. + * @return {@code double[]} array of the imaginary component. + * + * @since 4.0 + */ + public static double[] complex2Imaginary(Complex[] c) { + int index = 0; + final double d[] = new double[c.length]; + for (Complex cc : c) { + d[index] = cc.getImaginary(); + index++; + } + return d; + } + + /** + * Converts imaginary component of a {@code Complex[]} array to a + * {@code float[]} array. + * + * @param c + * {@code Complex[]} array. + * @return {@code float[]} array of the imaginary component. + * + * @since 4.0 + */ + public static float[] complex2ImaginaryFloat(Complex[] c) { + int index = 0; + final float f[] = new float[c.length]; + for (Complex cc : c) { + f[index] = (float) cc.getImaginary(); + index++; + } + return f; + } + + /** + * Converts imaginary component of a 2D {@code Complex[][]} array to a 2D + * {@code double[][]} array. + * + * @param c + * 2D {@code Complex[][]} array + * @return double[][] of imaginary component + * @since 4.0 + */ + public static double[][] complex2Imaginary(Complex[][] c) { + final int length = c.length; + double[][] d = new double[length][]; + for (int n = 0; n < length; n++) { + d[n] = complex2Imaginary(c[n]); + } + return d; + } + + /** + * Converts imaginary component of a 2D {@code Complex[][]} array to a 2D + * {@code float[][]} array. + * + * @param c + * 2D {@code Complex[][]} array + * @return float[][] of imaginary component + * @since 4.0 + */ + public static float[][] complex2ImaginaryFloat(Complex[][] c) { + final int length = c.length; + float[][] f = new float[length][]; + for (int n = 0; n < length; n++) { + f[n] = complex2ImaginaryFloat(c[n]); + } + return f; + } + + /** + * Converts imaginary component of a 3D {@code Complex[][][]} array to a 3D + * {@code double[][][]} array. + * + * @param c + * 3D complex interleaved {@code double[][][]} + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static double[][][] complex2Imaginary(Complex[][][] c) { + final int length = c.length; + double[][][] d = new double[length][][]; + for (int n = 0; n < length; n++) { + d[n] = complex2Imaginary(c[n]); + } + return d; + } + + /** + * Converts imaginary component of a 3D {@code Complex[][][]} array to a 3D + * {@code float[][][]} array. + * + * @param c + * 3D {@code Complex[][][]} array + * @return float[][][] of imaginary component + * @since 4.0 + */ + public static float[][][] complex2ImaginaryFloat(Complex[][][] c) { + final int length = c.length; + float[][][] f = new float[length][][]; + for (int n = 0; n < length; n++) { + f[n] = complex2ImaginaryFloat(c[n]); + } + return f; + } + + // INTERLEAVED METHODS + + /** + * Converts a complex interleaved {@code double[]} array to a + * {@code Complex[]} array for the range {@code start} - {@code end}. + * + * @param interleaved + * {@code double[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @param start + * Start index. + * @param end + * End index. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(double[] interleaved, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromInterleavedArray(interleaved, i); + index++; + } + return c; + } + + /** + * Converts a complex interleaved {@code float[]} array to a + * {@code Complex[]} array for the range {@code start} - {@code end}. + * + * @param interleaved + * {@code float[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @param start + * Start index. + * @param end + * End index. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(float[] interleaved, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromInterleavedArray(interleaved, i); + index++; + } + return c; + } + + /** + * Converts a complex interleaved {@code double[]} array to a + * {@code Complex[]} array for the range {@code start} - {@code end} by + * {@code increment}. + * + * @param interleaved + * {@code double[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(double[] interleaved, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromInterleavedArray(interleaved, i); + index++; + } + return c; + } + + /** + * Converts a complex interleaved {@code float[]} array to a + * {@code Complex[]} array for the range {@code start} - {@code end} by + * {@code increment}. + * + * @param interleaved + * {@code float[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(float[] interleaved, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromInterleavedArray(interleaved, i); + index++; + } + return c; + } + + /** + * Converts a complex interleaved {@code double[]} array to a + * {@code Complex[]} array for the {@code IntegerSequence} range. + * + * @param interleaved + * {@code double[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(double[] interleaved, Range range) { + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromInterleavedArray(interleaved, i); + index++; + } + return c; + } + + /** + * Converts a complex interleaved {@code float[]} array to a + * {@code Complex[]} array for the {@code IntegerSequence} range. + * + * @param interleaved + * {@code float[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(float[] interleaved, Range range) { + int index = 0; + final Complex c[] = new Complex[range.size()]; + for (Integer i : range) { + c[index] = extractComplexFromInterleavedArray(interleaved, i); + index++; + } + return c; + } + + /** + * Converts a complex interleaved {@code double[]} array to a + * {@code Complex[]} array + * + * @param interleaved + * {@code double[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(double[] interleaved) { + final int length = interleaved.length / 2; + final Complex c[] = new Complex[length]; + for (int n = 0; n < length; n++) { + c[n] = new Complex(interleaved[n * 2], interleaved[n * 2 + 1]); + } + return c; + } + + /** + * Converts a complex interleaved {@code float[]} array to a + * {@code Complex[]} array + * + * @param interleaved + * {@code float[]} of numbers to be converted to their + * {@code Complex} equivalent. + * @return {@code Complex[]} array. + * + * @since 4.0 + */ + public static Complex[] interleaved2Complex(float[] interleaved) { + final int length = interleaved.length / 2; + final Complex c[] = new Complex[length]; + for (int n = 0; n < length; n++) { + c[n] = new Complex(interleaved[n * 2], interleaved[n * 2 + 1]); + } + return c; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code double[]} array for the range {@code start} - {@code end}. + * + * @param c + * Complex array. + * @param start + * Start index. + * @param end + * End index. + * @return complex interleaved {@code double[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[] complex2Interleaved(Complex[] c, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final double d[] = new double[range.size() * 2]; + for (Integer i : range) { + int real = index * 2; + int imag = index * 2 + 1; + d[real] = c[i].getReal(); + d[imag] = c[i].getImaginary(); + index++; + } + return d; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code float[]} array for the range {@code start} - {@code end}. + * + * @param c + * Complex array. + * @param start + * Start index. + * @param end + * End index. + * @return complex interleaved {@code float[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[] complex2InterleavedFloat(Complex[] c, int start, int end) { + final Range range = IntegerSequence.range(start, end); + int index = 0; + final float f[] = new float[range.size() * 2]; + for (Integer i : range) { + int real = index * 2; + int imag = index * 2 + 1; + f[real] = (float) c[i].getReal(); + f[imag] = (float) c[i].getImaginary(); + index++; + } + return f; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code double[]} array for the range {@code start} - {@code end} by + * {@code increment}. + * + * @param c + * Complex array. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return complex interleaved {@code double[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[] complex2Interleaved(Complex[] c, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final double d[] = new double[range.size() * 2]; + for (Integer i : range) { + int real = index * 2; + int imag = index * 2 + 1; + d[real] = c[i].getReal(); + d[imag] = c[i].getImaginary(); + index++; + } + return d; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code float[]} array for the range {@code start} - {@code end} by + * {@code increment}. + * + * @param c + * Complex array. + * @param start + * Start index. + * @param end + * End index. + * @param increment + * Range increment. + * @return complex interleaved {@code float[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[] complex2InterleavedFloat(Complex[] c, int start, int end, int increment) { + final Range range = IntegerSequence.range(start, end, increment); + int index = 0; + final float f[] = new float[range.size() * 2]; + for (Integer i : range) { + int real = index * 2; + int imag = index * 2 + 1; + f[real] = (float) c[i].getReal(); + f[imag] = (float) c[i].getImaginary(); + index++; + } + return f; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code double[]} array for the {@code IntegerSequence} range. + * + * @param c + * Complex array. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return complex interleaved {@code double[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[] complex2Interleaved(Complex[] c, Range range) { + int index = 0; + final double d[] = new double[range.size() * 2]; + for (Integer i : range) { + int real = index * 2; + int imag = index * 2 + 1; + d[real] = c[i].getReal(); + d[imag] = c[i].getImaginary(); + index++; + } + return d; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code float[]} array for the {@code IntegerSequence} range. + * + * @param c + * Complex array. + * @param range + * an {@code Iterable<Integer>} object returned by + * {@code IntegerSequence.range()} + * @return complex interleaved {@code float[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[] complex2InterleavedFloat(Complex[] c, Range range) { + int index = 0; + final float f[] = new float[range.size() * 2]; + for (Integer i : range) { + int real = index * 2; + int imag = index * 2 + 1; + f[real] = (float) c[i].getReal(); + f[imag] = (float) c[i].getImaginary(); + index++; + } + return f; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code double[]} array + * + * @param c + * Complex array. + * @return complex interleaved {@code double[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[] complex2Interleaved(Complex[] c) { + int index = 0; + final double d[] = new double[c.length * 2]; + for (Complex cc : c) { + int real = index * 2; + int imag = index * 2 + 1; + d[real] = cc.getReal(); + d[imag] = cc.getImaginary(); + index++; + } + return d; + } + + /** + * Converts a {@code Complex[]} array to an interleaved complex + * {@code float[]} array + * + * @param c + * Complex array. + * @return complex interleaved {@code float[]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[] complex2InterleavedFloat(Complex[] c) { + int index = 0; + final float f[] = new float[c.length * 2]; + for (Complex cc : c) { + int real = index * 2; + int imag = index * 2 + 1; + f[real] = (float) cc.getReal(); + f[imag] = (float) cc.getImaginary(); + index++; + } + return f; + } + + /** + * Converts a 2D {@code Complex[][]} array to an interleaved complex + * {@code double[][]} array. + * + * @param c + * 2D Complex array. + * @param interleavedDim + * Depth level of the array to interleave. + * @return complex interleaved {@code double[][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[][] complex2Interleaved(Complex[][] c, int interleavedDim) { + if (interleavedDim > 1 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 1); + } + final int width = c.length; + final int height = c[0].length; + double[][] d; + if (interleavedDim == 0) { + d = new double[2 * width][height]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + d[x * 2][y] = c[x][y].getReal(); + d[x * 2 + 1][y] = c[x][y].getImaginary(); + } + } + } else { + d = new double[width][2 * height]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + d[x][y * 2] = c[x][y].getReal(); + d[x][y * 2 + 1] = c[x][y].getImaginary(); + } + } + } + return d; + } + + /** + * Converts a 2D {@code Complex[][]} array to an interleaved complex + * {@code double[][]} array. The second depth level of the array is assumed + * to be interleaved. + * + * @param c + * 2D Complex array. + * @return complex interleaved {@code double[][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[][] complex2Interleaved(Complex[][] c) { + return complex2Interleaved(c, 1); + } + + /** + * Converts a 3D {@code Complex[][][]} array to an interleaved complex + * {@code double[][][]} array. + * + * @param c + * 3D Complex array. + * @param interleavedDim + * Depth level of the array to interleave. + * @return complex interleaved {@code double[][][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[][][] complex2Interleaved(Complex[][][] c, int interleavedDim) { + if (interleavedDim > 2 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 2); + } + int width = c.length; + int height = c[0].length; + int depth = c[0].length; + double[][][] d; + if (interleavedDim == 0) { + d = new double[2 * width][height][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + d[x * 2][y][z] = c[x][y][z].getReal(); + d[x * 2 + 1][y][z] = c[x][y][z].getImaginary(); + } + } + } + } else if (interleavedDim == 1) { + d = new double[width][2 * height][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + d[x][y][z] = c[x][y][z].getReal(); + d[x][y * 2][z] = c[x][y][z].getImaginary(); + } + } + } + } else { + d = new double[width][height][2 * depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + d[x][y][z * 2] = c[x][y][z].getReal(); + d[x][y][z * 2 + 1] = c[x][y][z].getImaginary(); + } + } + } + } + return d; + } + + /** + * Converts a 3D {@code Complex[][][]} array to an interleaved complex + * {@code double[][][]} array. The third depth level of the array is + * interleaved. + * + * @param c + * 3D Complex array. + * @return complex interleaved {@code double[][][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static double[][][] complex2Interleaved(Complex[][][] c) { + return complex2Interleaved(c, 2); + } + + /** + * Converts a 2D {@code Complex[][]} array to an interleaved complex + * {@code float[][]} array. + * + * @param c + * 2D Complex array. + * @param interleavedDim + * Depth level of the array to interleave. + * @return complex interleaved {@code float[][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[][] complex2InterleavedFloat(Complex[][] c, int interleavedDim) { + if (interleavedDim > 1 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 1); + } + final int width = c.length; + final int height = c[0].length; + float[][] d; + if (interleavedDim == 0) { + d = new float[2 * width][height]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + d[x * 2][y] = (float) c[x][y].getReal(); + d[x * 2 + 1][y] = (float) c[x][y].getImaginary(); + } + } + } else { + d = new float[width][2 * height]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + d[x][y * 2] = (float) c[x][y].getReal(); + d[x][y * 2 + 1] = (float) c[x][y].getImaginary(); + } + } + } + return d; + } + + /** + * Converts a 2D {@code Complex[][]} array to an interleaved complex + * {@code float[][]} array. The second depth level of the array is assumed + * to be interleaved. + * + * @param c + * 2D Complex array. + * + * @return complex interleaved {@code float[][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[][] complex2InterleavedFloat(Complex[][] c) { + return complex2InterleavedFloat(c, 1); + } + + /** + * Converts a 3D {@code Complex[][][]} array to an interleaved complex + * {@code float[][][]} array. + * + * @param c + * 3D Complex array. + * @param interleavedDim + * Depth level of the array to interleave. + * @return complex interleaved {@code float[][][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[][][] complex2InterleavedFloat(Complex[][][] c, int interleavedDim) { + if (interleavedDim > 2 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 2); + } + final int width = c.length; + final int height = c[0].length; + final int depth = c[0][0].length; + float[][][] d; + if (interleavedDim == 0) { + d = new float[2 * width][height][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + d[x * 2][y][z] = (float) c[x][y][z].getReal(); + d[x * 2 + 1][y][z] = (float) c[x][y][z].getImaginary(); + } + } + } + } else if (interleavedDim == 1) { + d = new float[width][2 * height][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + d[x][y * 2][z] = (float) c[x][y][z].getReal(); + d[x][y * 2 + 1][z] = (float) c[x][y][z].getImaginary(); + } + } + } + } else { + d = new float[width][height][2 * depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + d[x][y][z * 2] = (float) c[x][y][z].getReal(); + d[x][y][z * 2 + 1] = (float) c[x][y][z].getImaginary(); + } + } + } + } + return d; + } + + /** + * Converts a 3D {@code Complex[][][]} array to an interleaved complex + * {@code float[][][]} array. The third depth level of the array is + * interleaved. + * + * @param c + * 2D Complex array. + * + * @return complex interleaved {@code float[][][]} alternating real and + * imaginary values. + * + * @since 4.0 + */ + public static float[][][] complex2InterleavedFloat(Complex[][][] c) { + return complex2InterleavedFloat(c, 2); + } + + /** + * Converts a 2D interleaved complex {@code double[][]} array to a + * {@code Complex[][]} array. + * + * @param d + * 2D complex interleaved {@code double[][]} + * @param interleavedDim + * Depth level of the array to interleave. + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] interleaved2Complex(double[][] d, int interleavedDim) { + if (interleavedDim > 1 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 1); + } + final int width = d.length; + final int height = d[0].length; + Complex[][] c; + if (interleavedDim == 0) { + c = new Complex[width / 2][height]; + for (int x = 0; x < width / 2; x++) { + for (int y = 0; y < height; y++) { + c[x][y] = new Complex(d[x * 2][y], d[x * 2 + 1][y]); + } + } + } else { + c = new Complex[width][height / 2]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height / 2; y++) { + c[x][y] = new Complex(d[x][y * 2], d[x][y * 2 + 1]); + } + } + } + return c; + } + + /** + * Converts a 2D interleaved complex {@code double[][]} array to a + * {@code Complex[][]} array. The second depth level of the array is assumed + * to be interleaved. + * + * @param d + * 2D complex interleaved {@code double[][]} + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] interleaved2Complex(double[][] d) { + return interleaved2Complex(d, 1); + } + + /** + * Converts a 3D interleaved complex {@code double[][][]} array to a + * {@code Complex[][][]} array. + * + * @param d + * 3D complex interleaved {@code double[][][]} + * @param interleavedDim + * Depth level of the array to interleave. + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] interleaved2Complex(double[][][] d, int interleavedDim) { + if (interleavedDim > 2 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 2); + } + final int width = d.length; + final int height = d[0].length; + final int depth = d[0][0].length; + Complex[][][] c; + if (interleavedDim == 0) { + c = new Complex[width / 2][height][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + c[x][y][z] = new Complex(d[x * 2][y][z], d[x * 2 + 1][y][z]); + } + } + } + } else if (interleavedDim == 1) { + c = new Complex[width][height / 2][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + c[x][y][z] = new Complex(d[x][y * 2][z], d[x][y * 2 + 1][z]); + } + } + } + } else { + c = new Complex[width][height][depth / 2]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + c[x][y][z] = new Complex(d[x][y][z * 2], d[x][y][z * 2 + 1]); + } + } + } + } + return c; + } + + /** + * Converts a 3D interleaved complex {@code double[][][]} array to a + * {@code Complex[][][]} array. The third depth level is assumed to be + * interleaved. + * + * @param d + * 3D complex interleaved {@code double[][][]} + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] interleaved2Complex(double[][][] d) { + return interleaved2Complex(d, 2); + } + + /** + * Converts a 2D interleaved complex {@code float[][]} array to a + * {@code Complex[][]} array. + * + * @param d + * 2D complex interleaved {@code float[][]} + * @param interleavedDim + * Depth level of the array to interleave. + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] interleaved2Complex(float[][] d, int interleavedDim) { + if (interleavedDim > 1 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 1); + } + final int width = d.length; + final int height = d[0].length; + Complex[][] c; + if (interleavedDim == 0) { + c = new Complex[width / 2][height]; + for (int x = 0; x < width / 2; x++) { + for (int y = 0; y < height; y++) { + c[x][y] = new Complex(d[x * 2][y], d[x * 2 + 1][y]); + } + } + } else { + c = new Complex[width][height / 2]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height / 2; y++) { + c[x][y] = new Complex(d[x][y * 2], d[x][y * 2 + 1]); + } + } + } + return c; + } + + /** + * Converts a 2D interleaved complex {@code float[][]} array to a + * {@code Complex[][]} array. The second depth level of the array is assumed + * to be interleaved. + * + * @param d + * 2D complex interleaved {@code float[][]} + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] interleaved2Complex(float[][] d) { + return interleaved2Complex(d, 1); + } + + /** + * Converts a 3D interleaved complex {@code float[][][]} array to a + * {@code Complex[][][]} array. + * + * @param d + * 3D complex interleaved {@code float[][][]} + * @param interleavedDim + * Depth level of the array to interleave. + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] interleaved2Complex(float[][][] d, int interleavedDim) { + if (interleavedDim > 2 || interleavedDim < 0) { + throw new OutOfRangeException(interleavedDim, 0, 2); + } + final int width = d.length; + final int height = d[0].length; + final int depth = d[0][0].length; + Complex[][][] c; + if (interleavedDim == 0) { + c = new Complex[width / 2][height][depth]; + for (int x = 0; x < width; x += 2) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z++) { + c[x][y][z] = new Complex(d[x * 2][y][z], d[x * 2 + 1][y][z]); + } + } + } + } else if (interleavedDim == 1) { + c = new Complex[width][height / 2][depth]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y += 2) { + for (int z = 0; z < depth; z++) { + c[x][y][z] = new Complex(d[x][y * 2][z], d[x][y * 2 + 1][z]); + } + } + } + } else { + c = new Complex[width][height][depth / 2]; + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int z = 0; z < depth; z += 2) { + c[x][y][z] = new Complex(d[x][y][z * 2], d[x][y][z * 2 + 1]); + } + } + } + } + return c; + } + + /** + * Converts a 3D interleaved complex {@code float[][][]} array to a + * {@code Complex[]} array. The third depth level of the array is assumed to + * be interleaved. + * + * @param d + * 3D complex interleaved {@code float[][][]} + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] interleaved2Complex(float[][][] d) { + return interleaved2Complex(d, 2); + } + + // SPLIT METHODS + + /** + * Converts a split complex array {@code double[] r, double[] i} to a + * {@code Complex[]} array. + * + * @param real + * real component + * @param imag + * imaginary component + * @return {@code Complex[]} array + * + * @since 4.0 + */ + public static Complex[] split2Complex(double[] real, double[] imag) { + final int length = real.length; + final Complex[] c = new Complex[length]; + for (int n = 0; n < length; n++) { + c[n] = new Complex(real[n], imag[n]); + } + return c; + } + + /** + * Converts a 2D split complex array {@code double[][] r, double[][] i} to a + * 2D {@code Complex[][]} array. + * + * @param real + * real component + * @param imag + * imaginary component + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] split2Complex(double[][] real, double[][] imag) { + final int length = real.length; + Complex[][] c = new Complex[length][]; + for (int x = 0; x < length; x++) { + c[x] = split2Complex(real[x], imag[x]); + } + return c; + } + + /** + * Converts a 3D split complex array {@code double[][][] r, double[][][] i} + * to a 3D {@code Complex[][][]} array. + * + * @param real + * real component + * @param imag + * imaginary component + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] split2Complex(double[][][] real, double[][][] imag) { + final int length = real.length; + Complex[][][] c = new Complex[length][][]; + for (int x = 0; x < length; x++) { + c[x] = split2Complex(real[x], imag[x]); + } + return c; + } + + /** + * Converts a split complex array {@code float[] r, float[] i} to a + * {@code Complex[]} array. + * + * @param real + * real component + * @param imag + * imaginary component + * @return {@code Complex[]} array + * + * @since 4.0 + */ + public static Complex[] split2Complex(float[] real, float[] imag) { + final int length = real.length; + final Complex[] c = new Complex[length]; + for (int n = 0; n < length; n++) { + c[n] = new Complex(real[n], imag[n]); + } + return c; + } + + /** + * Converts a 2D split complex array {@code float[][] r, float[][] i} to a + * 2D {@code Complex[][]} array. + * + * @param real + * real component + * @param imag + * imaginary component + * @return 2D {@code Complex[][]} array + * + * @since 4.0 + */ + public static Complex[][] split2Complex(float[][] real, float[][] imag) { + final int length = real.length; + Complex[][] c = new Complex[length][]; + for (int x = 0; x < length; x++) { + c[x] = split2Complex(real[x], imag[x]); + } + return c; + } + + /** + * Converts a 3D split complex array {@code float[][][] r, float[][][] i} to + * a 3D {@code Complex[][][]} array. + * + * @param real + * real component + * @param imag + * imaginary component + * @return 3D {@code Complex[][][]} array + * + * @since 4.0 + */ + public static Complex[][][] split2Complex(float[][][] real, float[][][] imag) { + final int length = real.length; + Complex[][][] c = new Complex[length][][]; + for (int x = 0; x < length; x++) { + c[x] = split2Complex(real[x], imag[x]); + } + return c; + } + + // MISC + + /** + * Initializes a {@code Complex[]} array to zero, to avoid + * NullPointerExceptions. + * + * @param c + * Complex[] array + * @return c + * + * @since 4.0 + */ + public static Complex[] initialize(Complex[] c) { + final int length = c.length; + for (int x = 0; x < length; x++) { + c[x] = Complex.ZERO; + } + return c; + } + + /** + * Initializes a {@code Complex[][]} array to zero, to avoid + * NullPointerExceptions. + * + * @param c + * Complex[][] array + * @return c + * + * @since 4.0 + */ + public static Complex[][] initialize(Complex[][] c) { + final int length = c.length; + for (int x = 0; x < length; x++) { + c[x] = initialize(c[x]); + } + return c; + } + + /** + * Initializes a {@code Complex[][][]} array to zero, to avoid + * NullPointerExceptions. + * + * @param c + * Complex[][][] array + * @return c + * + * @since 4.0 + */ + public static Complex[][][] initialize(Complex[][][] c) { + final int length = c.length; + for (int x = 0; x < length; x++) { + c[x] = initialize(c[x]); + } + return c; + } + + /** + * Returns {@code double[]} containing absolute values (magnitudes) of a + * {@code Complex[]} array. + * + * @param c + * {@code Complex[]} array + * @return {@code double[]} array + * + * @since 4.0 + */ + public static double[] abs(Complex[] c) { + final int length = c.length; + final double[] d = new double[length]; + for (int x = 0; x < length; x++) { + d[x] = c[x].abs(); + } + return d; + } + + /** + * Returns {@code double[]} containing arguments (phase angles) of a + * {@code Complex[]} array. + * + * @param c + * {@code Complex[]} array + * @return {@code double[]} array + * + * @since 4.0 + */ + public static double[] arg(Complex[] c) { + final int length = c.length; + final double[] d = new double[length]; + for (int x = 0; x < length; x++) { + d[x] = c[x].getArgument(); + } + return d; + } + } http://git-wip-us.apache.org/repos/asf/commons-math/blob/3ab3653e/src/test/java/org/apache/commons/math4/TestUtils.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/TestUtils.java b/src/test/java/org/apache/commons/math4/TestUtils.java index 109e64d..68a0138 100644 --- a/src/test/java/org/apache/commons/math4/TestUtils.java +++ b/src/test/java/org/apache/commons/math4/TestUtils.java @@ -365,6 +365,74 @@ public class TestUtils { } } + /** verifies that two arrays are close (sup norm) */ + public static void assertEquals(String msg, float[] expected, float[] observed, float tolerance) { + StringBuilder out = new StringBuilder(msg); + if (expected.length != observed.length) { + out.append("\n Arrays not same length. \n"); + out.append("expected has length "); + out.append(expected.length); + out.append(" observed length = "); + out.append(observed.length); + Assert.fail(out.toString()); + } + boolean failure = false; + for (int i=0; i < expected.length; i++) { + if (!Precision.equalsIncludingNaN(expected[i], observed[i], tolerance)) { + failure = true; + out.append("\n Elements at index "); + out.append(i); + out.append(" differ. "); + out.append(" expected = "); + out.append(expected[i]); + out.append(" observed = "); + out.append(observed[i]); + } + } + if (failure) { + Assert.fail(out.toString()); + } + } + + /** verifies that two arrays are close (sup norm) */ + public static void assertEquals(String msg, Complex[] expected, Complex[] observed, double tolerance) { + StringBuilder out = new StringBuilder(msg); + if (expected.length != observed.length) { + out.append("\n Arrays not same length. \n"); + out.append("expected has length "); + out.append(expected.length); + out.append(" observed length = "); + out.append(observed.length); + Assert.fail(out.toString()); + } + boolean failure = false; + for (int i=0; i < expected.length; i++) { + if (!Precision.equalsIncludingNaN(expected[i].getReal(), observed[i].getReal(), tolerance)) { + failure = true; + out.append("\n Real elements at index "); + out.append(i); + out.append(" differ. "); + out.append(" expected = "); + out.append(expected[i].getReal()); + out.append(" observed = "); + out.append(observed[i].getReal()); + } + if (!Precision.equalsIncludingNaN(expected[i].getImaginary(), observed[i].getImaginary(), tolerance)) { + failure = true; + out.append("\n Imaginary elements at index "); + out.append(i); + out.append(" differ. "); + out.append(" expected = "); + out.append(expected[i].getImaginary()); + out.append(" observed = "); + out.append(observed[i].getImaginary()); + } + } + if (failure) { + Assert.fail(out.toString()); + } + } + /** verifies that two arrays are equal */ public static <T extends FieldElement<T>> void assertEquals(T[] m, T[] n) { if (m.length != n.length) {