You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2016/04/20 02:56:54 UTC

[1/3] [math] MATH-1290

Repository: commons-math
Updated Branches:
  refs/heads/feature-MATH-1290 [created] 02e4f6be9


http://git-wip-us.apache.org/repos/asf/commons-math/blob/3ab3653e/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java b/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
index a0e9c6f..1b9d96e 100644
--- a/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
+++ b/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
@@ -1,5 +1,5 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
+* Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
@@ -18,12 +18,12 @@
 package org.apache.commons.math4.complex;
 
 import org.apache.commons.math4.TestUtils;
-import org.apache.commons.math4.complex.Complex;
-import org.apache.commons.math4.complex.ComplexUtils;
 import org.apache.commons.math4.exception.MathIllegalArgumentException;
 import org.apache.commons.math4.util.FastMath;
-import org.junit.Test;
+import org.apache.commons.math4.util.IntegerSequence;
+import org.apache.commons.math4.util.IntegerSequence.Range;
 import org.junit.Assert;
+import org.junit.Test;
 
 /**
  */
@@ -40,33 +40,168 @@ public class ComplexUtilsTest {
     private final Complex negInfNegInf = new Complex(negInf, negInf);
     private final Complex infNaN = new Complex(inf, nan);
 
+    private static Complex c[]; // complex array with real values even and imag
+                                // values odd
+    private static Complex cr[]; // complex array with real values consecutive
+    private static Complex ci[]; // complex array with imag values consecutive
+    private static double d[]; // real array with consecutive vals
+    private static double di[]; // real array with consecutive vals,
+                                // 'interleaved' length
+    private static float f[]; // real array with consecutive vals
+    private static float fi[]; // real array with consec vals, interleaved
+                               // length
+    private static double sr[]; // real component of split array, evens
+    private static double si[]; // imag component of split array, odds
+    private static float sfr[]; // real component of split array, float, evens
+    private static float sfi[]; // imag component of split array, float, odds
+    static Complex ans1, ans2; // answers to single value extraction methods
+    static Range range1, range2; // ranges used to test with
+                                             // IntegerRange
+    static Complex[] ansArrayc1r, ansArrayc1i, ansArrayc2r, ansArrayc2i, ansArrayc3, ansArrayc4; // answers
+                                                                                                 // to
+                                                                                                 // range
+                                                                                                 // extraction
+                                                                                                 // methods
+    static double[] ansArrayd1r, ansArrayd2r, ansArrayd1i, ansArrayd2i, ansArraydi1, ansArraydi2;
+    static float[] ansArrayf1r, ansArrayf2r, ansArrayf1i, ansArrayf2i, ansArrayfi1, ansArrayfi2;
+    static String msg; // error message for AssertEquals
+    static Complex[][] c2d, cr2d, ci2d; // for 2d methods
+    static Complex[][][] c3d, cr3d, ci3d; // for 3d methods
+    static double[][] d2d, di2d, sr2d, si2d;
+    static double[][][] d3d, di3d, sr3d, si3d;
+    static float[][] f2d, fi2d, sfr2d, sfi2d;
+    static float[][][] f3d, fi3d, sfr3d, sfi3d;
+
+    private static void setArrays() { // initial setup method
+        c = new Complex[10];
+        cr = new Complex[10];
+        ci = new Complex[10];
+        d = new double[10];
+        f = new float[10];
+        di = new double[20];
+        fi = new float[20];
+        sr = new double[10];
+        si = new double[10];
+        sfr = new float[10];
+        sfi = new float[10];
+        c2d = new Complex[10][10];
+        cr2d = new Complex[10][10];
+        ci2d = new Complex[10][10];
+        c3d = new Complex[10][10][10];
+        cr3d = new Complex[10][10][10];
+        ci3d = new Complex[10][10][10];
+        d2d = new double[10][10];
+        d3d = new double[10][10][10];
+        f2d = new float[10][10];
+        f3d = new float[10][10][10];
+        sr2d = new double[10][10];
+        sr3d = new double[10][10][10];
+        si2d = new double[10][10];
+        si3d = new double[10][10][10];
+        sfr2d = new float[10][10];
+        sfr3d = new float[10][10][10];
+        sfi2d = new float[10][10];
+        sfi3d = new float[10][10][10];
+        di2d = new double[10][20];
+        di3d = new double[10][10][20];
+        fi2d = new float[10][20];
+        fi3d = new float[10][10][20];
+        range1 = IntegerSequence.range(3, 7);
+        range2 = IntegerSequence.range(3, 7, 2);
+        for (int i = 0; i < 20; i += 2) {
+            d[i / 2] = i / 2;
+            f[i / 2] = i / 2;
+            di[i] = i;
+            di[i + 1] = i + 1;
+            fi[i] = i;
+            fi[i + 1] = i + 1;
+            c[i / 2] = new Complex(i, i + 1);
+            cr[i / 2] = new Complex(i / 2);
+            ci[i / 2] = new Complex(0, i / 2);
+            sr[i / 2] = i;
+            si[i / 2] = i + 1;
+            sfr[i / 2] = i;
+            sfi[i / 2] = i + 1;
+        }
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 20; j += 2) {
+                d2d[i][j / 2] = 10 * i + j / 2;
+                f2d[i][j / 2] = 10 * i + j / 2;
+                sr2d[i][j / 2] = 10 * i + j;
+                si2d[i][j / 2] = 10 * i + j + 1;
+                sfr2d[i][j / 2] = 10 * i + j;
+                sfi2d[i][j / 2] = 10 * i + j + 1;
+                di2d[i][j] = 10 * i + j;
+                di2d[i][j + 1] = 10 * i + j + 1;
+                fi2d[i][j] = 10 * i + j;
+                fi2d[i][j + 1] = 10 * i + j + 1;
+                c2d[i][j / 2] = new Complex(10 * i + j, 10 * i + j + 1);
+                cr2d[i][j / 2] = new Complex(10 * i + j / 2);
+                ci2d[i][j / 2] = new Complex(0, 10 * i + j / 2);
+            }
+        }
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                for (int k = 0; k < 20; k += 2) {
+                    d3d[i][j][k / 2] = 100 * i + 10 * j + k / 2;
+                    f3d[i][j][k / 2] = 100 * i + 10 * j + k / 2;
+                    sr3d[i][j][k / 2] = 100 * i + 10 * j + k;
+                    si3d[i][j][k / 2] = 100 * i + 10 * j + k + 1;
+                    sfr3d[i][j][k / 2] = 100 * i + 10 * j + k;
+                    sfi3d[i][j][k / 2] = 100 * i + 10 * j + k + 1;
+                    di3d[i][j][k] = 100 * i + 10 * j + k;
+                    di3d[i][j][k + 1] = 100 * i + 10 * j + k + 1;
+                    fi3d[i][j][k] = 100 * i + 10 * j + k;
+                    fi3d[i][j][k + 1] = 100 * i + 10 * j + k + 1;
+                    c3d[i][j][k / 2] = new Complex(100 * i + 10 * j + k, 100 * i + 10 * j + k + 1);
+                    cr3d[i][j][k / 2] = new Complex(100 * i + 10 * j + k / 2);
+                    ci3d[i][j][k / 2] = new Complex(0, 100 * i + 10 * j + k / 2);
+                }
+            }
+        }
+        ansArrayc1r = new Complex[] { new Complex(3), new Complex(4), new Complex(5), new Complex(6), new Complex(7) };
+        ansArrayc2r = new Complex[] { new Complex(3), new Complex(5), new Complex(7) };
+        ansArrayc1i = new Complex[] { new Complex(0, 3), new Complex(0, 4), new Complex(0, 5), new Complex(0, 6),
+                new Complex(0, 7) };
+        ansArrayc2i = new Complex[] { new Complex(0, 3), new Complex(0, 5), new Complex(0, 7) };
+        ansArrayc3 = new Complex[] { new Complex(6, 7), new Complex(8, 9), new Complex(10, 11), new Complex(12, 13),
+                new Complex(14, 15) };
+        ansArrayc4 = new Complex[] { new Complex(6, 7), new Complex(10, 11), new Complex(14, 15) };
+        ansArrayd1r = new double[] { 6, 8, 10, 12, 14 };
+        ansArrayd1i = new double[] { 7, 9, 11, 13, 15 };
+        ansArrayd2r = new double[] { 6, 10, 14 };
+        ansArrayd2i = new double[] { 7, 11, 15 };
+        ansArrayf1r = new float[] { 6, 8, 10, 12, 14 };
+        ansArrayf1i = new float[] { 7, 9, 11, 13, 15 };
+        ansArrayf2r = new float[] { 6, 10, 14 };
+        ansArrayf2i = new float[] { 7, 11, 15 };
+        ansArraydi1 = new double[] { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+        ansArrayfi1 = new float[] { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+        ansArraydi2 = new double[] { 6, 7, 10, 11, 14, 15 };
+        ansArrayfi2 = new float[] { 6, 7, 10, 11, 14, 15 };
+        msg = "";
+    }
+
     @Test
     public void testPolar2Complex() {
-        TestUtils.assertEquals(Complex.ONE,
-                ComplexUtils.polar2Complex(1, 0), 10e-12);
-        TestUtils.assertEquals(Complex.ZERO,
-                ComplexUtils.polar2Complex(0, 1), 10e-12);
-        TestUtils.assertEquals(Complex.ZERO,
-                ComplexUtils.polar2Complex(0, -1), 10e-12);
-        TestUtils.assertEquals(Complex.I,
-                ComplexUtils.polar2Complex(1, pi/2), 10e-12);
-        TestUtils.assertEquals(Complex.I.negate(),
-                ComplexUtils.polar2Complex(1, -pi/2), 10e-12);
+        TestUtils.assertEquals(Complex.ONE, ComplexUtils.polar2Complex(1, 0), 10e-12);
+        TestUtils.assertEquals(Complex.ZERO, ComplexUtils.polar2Complex(0, 1), 10e-12);
+        TestUtils.assertEquals(Complex.ZERO, ComplexUtils.polar2Complex(0, -1), 10e-12);
+        TestUtils.assertEquals(Complex.I, ComplexUtils.polar2Complex(1, pi / 2), 10e-12);
+        TestUtils.assertEquals(Complex.I.negate(), ComplexUtils.polar2Complex(1, -pi / 2), 10e-12);
         double r = 0;
         for (int i = 0; i < 5; i++) {
-          r += i;
-          double theta = 0;
-          for (int j =0; j < 20; j++) {
-              theta += pi / 6;
-              TestUtils.assertEquals(altPolar(r, theta),
-                      ComplexUtils.polar2Complex(r, theta), 10e-12);
-          }
-          theta = -2 * pi;
-          for (int j =0; j < 20; j++) {
-              theta -= pi / 6;
-              TestUtils.assertEquals(altPolar(r, theta),
-                      ComplexUtils.polar2Complex(r, theta), 10e-12);
-          }
+            r += i;
+            double theta = 0;
+            for (int j = 0; j < 20; j++) {
+                theta += pi / 6;
+                TestUtils.assertEquals(altPolar(r, theta), ComplexUtils.polar2Complex(r, theta), 10e-12);
+            }
+            theta = -2 * pi;
+            for (int j = 0; j < 20; j++) {
+                theta -= pi / 6;
+                TestUtils.assertEquals(altPolar(r, theta), ComplexUtils.polar2Complex(r, theta), 10e-12);
+            }
         }
     }
 
@@ -74,7 +209,7 @@ public class ComplexUtilsTest {
         return Complex.I.multiply(new Complex(theta, 0)).exp().multiply(new Complex(r, 0));
     }
 
-    @Test(expected=MathIllegalArgumentException.class)
+    @Test(expected = MathIllegalArgumentException.class)
     public void testPolar2ComplexIllegalModulus() {
         ComplexUtils.polar2Complex(-1, 0);
     }
@@ -83,32 +218,382 @@ public class ComplexUtilsTest {
     public void testPolar2ComplexNaN() {
         TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(nan, 1));
         TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, nan));
-        TestUtils.assertSame(Complex.NaN,
-                ComplexUtils.polar2Complex(nan, nan));
+        TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(nan, nan));
     }
 
     @Test
     public void testPolar2ComplexInf() {
         TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, inf));
-        TestUtils.assertSame(Complex.NaN,
-                ComplexUtils.polar2Complex(1, negInf));
+        TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(1, negInf));
         TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(inf, inf));
-        TestUtils.assertSame(Complex.NaN,
-                ComplexUtils.polar2Complex(inf, negInf));
-        TestUtils.assertSame(infInf, ComplexUtils.polar2Complex(inf, pi/4));
+        TestUtils.assertSame(Complex.NaN, ComplexUtils.polar2Complex(inf, negInf));
+        TestUtils.assertSame(infInf, ComplexUtils.polar2Complex(inf, pi / 4));
         TestUtils.assertSame(infNaN, ComplexUtils.polar2Complex(inf, 0));
-        TestUtils.assertSame(infNegInf, ComplexUtils.polar2Complex(inf, -pi/4));
-        TestUtils.assertSame(negInfInf, ComplexUtils.polar2Complex(inf, 3*pi/4));
-        TestUtils.assertSame(negInfNegInf, ComplexUtils.polar2Complex(inf, 5*pi/4));
+        TestUtils.assertSame(infNegInf, ComplexUtils.polar2Complex(inf, -pi / 4));
+        TestUtils.assertSame(negInfInf, ComplexUtils.polar2Complex(inf, 3 * pi / 4));
+        TestUtils.assertSame(negInfNegInf, ComplexUtils.polar2Complex(inf, 5 * pi / 4));
     }
 
     @Test
-    public void testConvertToComplex() {
+    public void testCExtract() {
         final double[] real = new double[] { negInf, -123.45, 0, 1, 234.56, pi, inf };
-        final Complex[] complex = ComplexUtils.convertToComplex(real);
+        final Complex[] complex = ComplexUtils.real2Complex(real);
 
         for (int i = 0; i < real.length; i++) {
             Assert.assertEquals(real[i], complex[i].getReal(), 0d);
         }
     }
+
+    // EXTRACTION METHODS
+
+    @Test
+    public void testExtractionMethods() {
+        setArrays();
+        // Extract complex from real double array, index 3
+        TestUtils.assertSame(new Complex(3), ComplexUtils.extractComplexFromRealArray(d, 3));
+        // Extract complex from real float array, index 3
+        TestUtils.assertSame(new Complex(3), ComplexUtils.extractComplexFromRealArray(f, 3));
+        // Extract real double from complex array, index 3
+        TestUtils.assertSame(6, ComplexUtils.extractRealFromComplexArray(c, 3));
+        // Extract real float from complex array, index 3
+        TestUtils.assertSame(6, ComplexUtils.extractRealFloatFromComplexArray(c, 3));
+        // Extract complex from interleaved double array, index 3
+        TestUtils.assertSame(new Complex(6, 7), ComplexUtils.extractComplexFromInterleavedArray(d, 3));
+        // Extract complex from interleaved float array, index 3
+        TestUtils.assertSame(new Complex(6, 7), ComplexUtils.extractComplexFromInterleavedArray(f, 3));
+        // Extract interleaved double from complex array, index 3
+        TestUtils.assertEquals(msg, new double[] { 6, 7 }, ComplexUtils.extractInterleavedFromComplexArray(c, 3),
+                Math.ulp(1));
+        // Extract interleaved float from complex array, index 3
+        TestUtils.assertEquals(msg, new double[] { 6, 7 }, ComplexUtils.extractInterleavedFromComplexArray(c, 3),
+                Math.ulp(1));
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+    // REAL <-> COMPLEX
+
+    @Test
+    public void testRealToComplex() {
+        setArrays();
+        // Real double to complex, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc1r, ComplexUtils.real2Complex(d, 3, 7), Math.ulp(1));
+        // Real float to complex, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc1r, ComplexUtils.real2Complex(f, 3, 7), Math.ulp(1));
+        // Real double to complex, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc2r, ComplexUtils.real2Complex(d, 3, 7, 2), Math.ulp(1));
+        // Real float to complex, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc2r, ComplexUtils.real2Complex(f, 3, 7, 2), Math.ulp(1));
+        // Real double to complex, range 3-7, increment 1, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc1r, ComplexUtils.real2Complex(d, range1), Math.ulp(1));
+        // Real float to complex, range 3-7, increment 1, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc1r, ComplexUtils.real2Complex(f, range1), Math.ulp(1));
+        // Real double to complex, range 3-7, increment 2, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc2r, ComplexUtils.real2Complex(d, 3, 7, 2), Math.ulp(1));
+        // Real float to complex, range 3-7, increment 2, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc2r, ComplexUtils.real2Complex(f, 3, 7, 2), Math.ulp(1));
+        // Real double to complex, whole array
+        TestUtils.assertEquals(msg, cr, ComplexUtils.real2Complex(d), Math.ulp(1));
+        // Real float to complex, whole array
+        TestUtils.assertEquals(msg, cr, ComplexUtils.real2Complex(f), Math.ulp(1));
+        // 2d
+        for (int i = 0; i < 10; i++) {
+            // Real double to complex, 2d
+            TestUtils.assertEquals(msg, cr2d[i], ComplexUtils.real2Complex(d2d[i]), Math.ulp(1));
+            // Real float to complex, 2d
+            TestUtils.assertEquals(msg, cr2d[i], ComplexUtils.real2Complex(f2d[i]), Math.ulp(1));
+        }
+        // 3d
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                // Real double to complex, 3d
+                TestUtils.assertEquals(msg, cr3d[i][j], ComplexUtils.real2Complex(d3d[i][j]), Math.ulp(1));
+                // Real float to complex, 3d
+                TestUtils.assertEquals(msg, cr3d[i][j], ComplexUtils.real2Complex(f3d[i][j]), Math.ulp(1));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    @Test
+    public void testComplexToReal() {
+        setArrays();
+        // Real complex to double, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayd1r, ComplexUtils.complex2Real(c, 3, 7), Math.ulp(1));
+        // Real complex to float, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayf1r, ComplexUtils.complex2RealFloat(c, 3, 7), Math.ulp(1));
+        // Real complex to double, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayd2r, ComplexUtils.complex2Real(c, 3, 7, 2), Math.ulp(1));
+        // Real complex to float, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayf2r, ComplexUtils.complex2RealFloat(c, 3, 7, 2), Math.ulp(1));
+        // Real complex to double, range 3-7, increment 1, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayd1r, ComplexUtils.complex2Real(c, range1), Math.ulp(1));
+        // Real complex to float, range 3-7, increment 1, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayf1r, ComplexUtils.complex2RealFloat(c, range1), Math.ulp(1));
+        // Real complex to double, range 3-7, increment 2, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayd2r, ComplexUtils.complex2Real(c, 3, 7, 2), Math.ulp(1));
+        // Real complex to float, range 3-7, increment 2, using IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayf2r, ComplexUtils.complex2RealFloat(c, 3, 7, 2), Math.ulp(1));
+        // Real complex to double, whole array
+        TestUtils.assertEquals(msg, sr, ComplexUtils.complex2Real(c), Math.ulp(1));
+        // Real complex to float, whole array
+        TestUtils.assertEquals(msg, sfr, ComplexUtils.complex2RealFloat(c), Math.ulp(1));
+        // 2d
+        for (int i = 0; i < 10; i++) {
+            // Real complex to double, 2d
+            TestUtils.assertEquals(msg, sr2d[i], ComplexUtils.complex2Real(c2d[i]), Math.ulp(1));
+            // Real complex to float, 2d
+            TestUtils.assertEquals(msg, sfr2d[i], ComplexUtils.complex2RealFloat(c2d[i]), Math.ulp(1));
+        }
+        // 3d
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                // Real complex to double, 3d
+                TestUtils.assertEquals(msg, sr3d[i][j], ComplexUtils.complex2Real(c3d[i][j]), Math.ulp(1));
+                // Real complex to float, 3d
+                TestUtils.assertEquals(msg, sfr3d[i][j], ComplexUtils.complex2RealFloat(c3d[i][j]), Math.ulp(1));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    // IMAGINARY <-> COMPLEX
+
+    @Test
+    public void testImaginaryToComplex() {
+        setArrays();
+        // Imaginary double to complex, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc1i, ComplexUtils.imaginary2Complex(d, 3, 7), Math.ulp(1));
+        // Imaginary float to complex, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc1i, ComplexUtils.imaginary2Complex(f, 3, 7), Math.ulp(1));
+        // Imaginary double to complex, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc2i, ComplexUtils.imaginary2Complex(d, 3, 7, 2), Math.ulp(1));
+        // Imaginary float to complex, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc2i, ComplexUtils.imaginary2Complex(f, 3, 7, 2), Math.ulp(1));
+        // Imaginary double to complex, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc1i, ComplexUtils.imaginary2Complex(d, range1), Math.ulp(1));
+        // Imaginary float to complex, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc1i, ComplexUtils.imaginary2Complex(f, range1), Math.ulp(1));
+        // Imaginary double to complex, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc2i, ComplexUtils.imaginary2Complex(d, 3, 7, 2), Math.ulp(1));
+        // Imaginary float to complex, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc2i, ComplexUtils.imaginary2Complex(f, 3, 7, 2), Math.ulp(1));
+        // Imaginary double to complex, whole array
+        TestUtils.assertEquals(msg, ci, ComplexUtils.imaginary2Complex(d), Math.ulp(1));
+        // Imaginary float to complex, whole array
+        TestUtils.assertEquals(msg, ci, ComplexUtils.imaginary2Complex(f), Math.ulp(1));
+        // 2d
+        for (int i = 0; i < 10; i++) {
+            // Imaginary double to complex, 2d
+            TestUtils.assertEquals(msg, ci2d[i], ComplexUtils.imaginary2Complex(d2d[i]), Math.ulp(1));
+            // Imaginary float to complex, 2d
+            TestUtils.assertEquals(msg, ci2d[i], ComplexUtils.imaginary2Complex(f2d[i]), Math.ulp(1));
+        }
+        // 3d
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                // Imaginary double to complex, 3d
+                TestUtils.assertEquals(msg, ci3d[i][j], ComplexUtils.imaginary2Complex(d3d[i][j]), Math.ulp(1));
+                // Imaginary float to complex, 3d
+                TestUtils.assertEquals(msg, ci3d[i][j], ComplexUtils.imaginary2Complex(f3d[i][j]), Math.ulp(1));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    @Test
+    public void testComplexToImaginary() {
+        setArrays();
+        // Imaginary complex to double, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayd1i, ComplexUtils.complex2Imaginary(c, 3, 7), Math.ulp(1));
+        // Imaginary complex to float, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayf1i, ComplexUtils.complex2ImaginaryFloat(c, 3, 7), Math.ulp(1));
+        // Imaginary complex to double, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayd2i, ComplexUtils.complex2Imaginary(c, 3, 7, 2), Math.ulp(1));
+        // Imaginary complex to float, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayf2i, ComplexUtils.complex2ImaginaryFloat(c, 3, 7, 2), Math.ulp(1));
+        // Imaginary complex to double, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayd1i, ComplexUtils.complex2Imaginary(c, range1), Math.ulp(1));
+        // Imaginary complex to float, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayf1i, ComplexUtils.complex2ImaginaryFloat(c, range1), Math.ulp(1));
+        // Imaginary complex to double, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayd2i, ComplexUtils.complex2Imaginary(c, 3, 7, 2), Math.ulp(1));
+        // Imaginary complex to float, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayf2i, ComplexUtils.complex2ImaginaryFloat(c, 3, 7, 2), Math.ulp(1));
+        // Imaginary complex to double, whole array
+        TestUtils.assertEquals(msg, si, ComplexUtils.complex2Imaginary(c), Math.ulp(1));
+        // Imaginary complex to float, whole array
+        TestUtils.assertEquals(msg, sfi, ComplexUtils.complex2ImaginaryFloat(c), Math.ulp(1));
+        // 2d
+        for (int i = 0; i < 10; i++) {
+            // Imaginary complex to double, 2d
+            TestUtils.assertEquals(msg, si2d[i], ComplexUtils.complex2Imaginary(c2d[i]), Math.ulp(1));
+            // Imaginary complex to float, 2d
+            TestUtils.assertEquals(msg, sfi2d[i], ComplexUtils.complex2ImaginaryFloat(c2d[i]), Math.ulp(1));
+        }
+        // 3d
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                // Imaginary complex to double, 3d
+                TestUtils.assertEquals(msg, si3d[i][j], ComplexUtils.complex2Imaginary(c3d[i][j]), Math.ulp(1));
+                // Imaginary complex to float, 3d
+                TestUtils.assertEquals(msg, sfi3d[i][j], ComplexUtils.complex2ImaginaryFloat(c3d[i][j]), Math.ulp(1));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    // INTERLEAVED <-> COMPLEX
+
+    @Test
+    public void testInterleavedToComplex() {
+        setArrays();
+        // Interleaved double to complex, range 3-7, increment 1, entered as
+        // ints
+        TestUtils.assertEquals(msg, ansArrayc3, ComplexUtils.interleaved2Complex(di, 3, 7), Math.ulp(1));
+        // Interleaved float to complex, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc3, ComplexUtils.interleaved2Complex(fi, 3, 7), Math.ulp(1));
+        // Interleaved double to complex, range 3-7, increment 2, entered as
+        // ints
+        TestUtils.assertEquals(msg, ansArrayc4, ComplexUtils.interleaved2Complex(di, 3, 7, 2), Math.ulp(1));
+        // Interleaved float to complex, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayc4, ComplexUtils.interleaved2Complex(fi, 3, 7, 2), Math.ulp(1));
+        // Interleaved double to complex, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc3, ComplexUtils.interleaved2Complex(di, range1), Math.ulp(1));
+        // Interleaved float to complex, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc3, ComplexUtils.interleaved2Complex(fi, range1), Math.ulp(1));
+        // Interleaved double to complex, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc4, ComplexUtils.interleaved2Complex(di, 3, 7, 2), Math.ulp(1));
+        // Interleaved float to complex, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayc4, ComplexUtils.interleaved2Complex(fi, 3, 7, 2), Math.ulp(1));
+        // Interleaved double to complex, whole array
+        TestUtils.assertEquals(msg, c, ComplexUtils.interleaved2Complex(di), Math.ulp(1));
+        // Interleaved float to complex, whole array
+        TestUtils.assertEquals(msg, c, ComplexUtils.interleaved2Complex(fi), Math.ulp(1));
+        // 2d
+        for (int i = 0; i < 10; i++) {
+            // Interleaved double to complex, 2d
+            TestUtils.assertEquals(msg, c2d[i], ComplexUtils.interleaved2Complex(di2d[i]), Math.ulp(1));
+            // Interleaved float to complex, 2d
+            TestUtils.assertEquals(msg, c2d[i], ComplexUtils.interleaved2Complex(fi2d[i]), Math.ulp(1));
+        }
+        // 3d
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                // Interleaved double to complex, 3d
+                TestUtils.assertEquals(msg, c3d[i][j], ComplexUtils.interleaved2Complex(di3d[i][j]), Math.ulp(1));
+                // Interleaved float to complex, 3d
+                TestUtils.assertEquals(msg, c3d[i][j], ComplexUtils.interleaved2Complex(fi3d[i][j]), Math.ulp(1));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    @Test
+    public void testComplexToInterleaved() {
+        setArrays();
+        // Interleaved complex to double, range 3-7, increment 1, entered as
+        // ints
+        TestUtils.assertEquals(msg, ansArraydi1, ComplexUtils.complex2Interleaved(c, 3, 7), Math.ulp(1));
+        // Interleaved complex to float, range 3-7, increment 1, entered as ints
+        TestUtils.assertEquals(msg, ansArrayfi1, ComplexUtils.complex2InterleavedFloat(c, 3, 7), Math.ulp(1));
+        // Interleaved complex to double, range 3-7, increment 2, entered as
+        // ints
+        TestUtils.assertEquals(msg, ansArraydi2, ComplexUtils.complex2Interleaved(c, 3, 7, 2), Math.ulp(1));
+        // Interleaved complex to float, range 3-7, increment 2, entered as ints
+        TestUtils.assertEquals(msg, ansArrayfi2, ComplexUtils.complex2InterleavedFloat(c, 3, 7, 2), Math.ulp(1));
+        // Interleaved complex to double, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArraydi1, ComplexUtils.complex2Interleaved(c, range1), Math.ulp(1));
+        // Interleaved complex to float, range 3-7, increment 1, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayfi1, ComplexUtils.complex2InterleavedFloat(c, range1), Math.ulp(1));
+        // Interleaved complex to double, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArraydi2, ComplexUtils.complex2Interleaved(c, 3, 7, 2), Math.ulp(1));
+        // Interleaved complex to float, range 3-7, increment 2, using
+        // IntegerSequence
+        TestUtils.assertEquals(msg, ansArrayfi2, ComplexUtils.complex2InterleavedFloat(c, 3, 7, 2), Math.ulp(1));
+        // Interleaved complex to double, whole array
+        TestUtils.assertEquals(msg, di, ComplexUtils.complex2Interleaved(c), Math.ulp(1));
+        // Interleaved complex to float, whole array
+        TestUtils.assertEquals(msg, fi, ComplexUtils.complex2InterleavedFloat(c), Math.ulp(1));
+        // 2d
+        for (int i = 0; i < 10; i++) {
+            // Interleaved complex to double, 2d
+            TestUtils.assertEquals(msg, di2d[i], ComplexUtils.complex2Interleaved(c2d[i]), Math.ulp(1));
+            // Interleaved complex to float, 2d
+            TestUtils.assertEquals(msg, fi2d[i], ComplexUtils.complex2InterleavedFloat(c2d[i]), Math.ulp(1));
+        }
+        // 3d
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                // Interleaved complex to double, 3d
+                TestUtils.assertEquals(msg, di3d[i][j], ComplexUtils.complex2Interleaved(c3d[i][j]), Math.ulp(1));
+                // Interleaved complex to float, 3d
+                TestUtils.assertEquals(msg, fi3d[i][j], ComplexUtils.complex2InterleavedFloat(c3d[i][j]), Math.ulp(1));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    // SPLIT TO COMPLEX
+    @Test
+    public void testSplit2Complex() {
+        setArrays();
+        // Split double to complex, whole array
+        TestUtils.assertEquals(msg, c, ComplexUtils.split2Complex(sr, si), Math.ulp(1));
+
+        // 2d
+        for (int i = 0; i < 10; i++) {
+            // Split double to complex, 2d
+            TestUtils.assertEquals(msg, c2d[i], ComplexUtils.split2Complex(sr2d[i], si2d[i]), Math.ulp(1));
+        }
+        // 3d
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 10; j++) {
+                // Split double to complex, 3d
+                TestUtils.assertEquals(msg, c3d[i][j], ComplexUtils.split2Complex(sr3d[i][j], si3d[i][j]), Math.ulp(1));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    // INITIALIZATION METHODS
+
+    @Test
+    public void testInitialize() {
+        Complex[] c = new Complex[10];
+        ComplexUtils.initialize(c);
+        for (Complex cc : c) {
+            TestUtils.assertEquals(new Complex(0, 0), cc, Math.ulp(0));
+        }
+    }
+
 }


[3/3] [math] Formatting.

Posted by er...@apache.org.
Formatting.


Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/02e4f6be
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/02e4f6be
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/02e4f6be

Branch: refs/heads/feature-MATH-1290
Commit: 02e4f6be9f5c7b6a3e6e0e83d8f038bdcd9ef287
Parents: 3ab3653
Author: Gilles <er...@apache.org>
Authored: Sun Mar 27 01:29:21 2016 +0100
Committer: Gilles <er...@apache.org>
Committed: Sun Mar 27 01:29:21 2016 +0100

----------------------------------------------------------------------
 .../java/org/apache/commons/math4/complex/ComplexUtilsTest.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/02e4f6be/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java b/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
index 1b9d96e..aadeb1a 100644
--- a/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
+++ b/src/test/java/org/apache/commons/math4/complex/ComplexUtilsTest.java
@@ -1,5 +1,5 @@
 /*
-* Licensed to the Apache Software Foundation (ASF) under one or more
+ * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
@@ -26,6 +26,7 @@ import org.junit.Assert;
 import org.junit.Test;
 
 /**
+ * Test cases for {@link ComplexUtils}.
  */
 public class ComplexUtilsTest {
 
@@ -595,5 +596,4 @@ public class ComplexUtilsTest {
             TestUtils.assertEquals(new Complex(0, 0), cc, Math.ulp(0));
         }
     }
-
 }


[2/3] [math] MATH-1290

Posted by er...@apache.org.
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/feature-MATH-1290
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&middot;e<sup>i&middot;theta</sup></code>,
-     * computed as <code>r&middot;cos(theta) + r&middot;sin(theta)i</code></p>
+     * The value returned is {@code r&middot;e<sup>i&middot;theta</sup>},
+     * computed as {@code r&middot;cos(theta) + r&middot;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, &pi;/4) = INFINITY + INFINITY i
      * polar2Complex(INFINITY, 0) = INFINITY + NaN i
      * polar2Complex(INFINITY, -&pi;/4) = INFINITY - INFINITY i
-     * polar2Complex(INFINITY, 5&pi;/4) = -INFINITY - INFINITY i </code></pre></p>
+     * polar2Complex(INFINITY, 5&pi;/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&middot;e<sup>i&middot;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) {