http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/40418955/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/ComplexUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/ComplexUtilsTest.java
 
b/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/ComplexUtilsTest.java
new file mode 100644
index 0000000..d348571
--- /dev/null
+++ 
b/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/ComplexUtilsTest.java
@@ -0,0 +1,476 @@
+/*
+ * 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
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.streams;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ */
+public class ComplexUtilsTest {
+
+    private static final double inf = Double.POSITIVE_INFINITY;
+    private static final double negInf = Double.NEGATIVE_INFINITY;
+    private static final double nan = Double.NaN;
+    private static final double pi = Math.PI;
+
+    private static final Complex negInfInf = Complex.ofCartesian(negInf, inf);
+    private static final Complex infNegInf = Complex.ofCartesian(inf, negInf);
+    private static final Complex infInf = Complex.ofCartesian(inf, inf);
+    private static final Complex negInfNegInf = Complex.ofCartesian(negInf, 
negInf);
+    private static final Complex infNaN = Complex.ofCartesian(inf, nan);
+    private static final Complex NAN = Complex.ofCartesian(nan, 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 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];
+        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] = Complex.ofCartesian(i, i + 1);
+            cr[i / 2] = Complex.ofReal(i / 2);
+            ci[i / 2] = Complex.ofCartesian(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] = Complex.ofCartesian(10 * i + j, 10 * i + j + 
1);
+                cr2d[i][j / 2] = Complex.ofReal(10 * i + j / 2);
+                ci2d[i][j / 2] = Complex.ofCartesian(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] = Complex.ofCartesian(100 * i + 10 * j + 
k, 100 * i + 10 * j + k + 1);
+                    cr3d[i][j][k / 2] = Complex.ofReal(100 * i + 10 * j + k / 
2);
+                    ci3d[i][j][k / 2] = Complex.ofCartesian(0, 100 * i + 10 * 
j + k / 2);
+                }
+            }
+        }
+        ansArrayc1r = new Complex[] { Complex.ofReal(3), Complex.ofReal(4), 
Complex.ofReal(5), Complex.ofReal(6), Complex.ofReal(7) };
+        ansArrayc2r = new Complex[] { Complex.ofReal(3), Complex.ofReal(5), 
Complex.ofReal(7) };
+        ansArrayc1i = new Complex[] { Complex.ofCartesian(0, 3), 
Complex.ofCartesian(0, 4), Complex.ofCartesian(0, 5), Complex.ofCartesian(0, 6),
+                Complex.ofCartesian(0, 7) };
+        ansArrayc2i = new Complex[] { Complex.ofCartesian(0, 3), 
Complex.ofCartesian(0, 5), Complex.ofCartesian(0, 7) };
+        ansArrayc3 = new Complex[] { Complex.ofCartesian(6, 7), 
Complex.ofCartesian(8, 9), Complex.ofCartesian(10, 11), Complex.ofCartesian(12, 
13),
+                Complex.ofCartesian(14, 15) };
+        ansArrayc4 = new Complex[] { Complex.ofCartesian(6, 7), 
Complex.ofCartesian(10, 11), Complex.ofCartesian(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);
+        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);
+            }
+        }
+    }
+
+    protected Complex altPolar(double r, double theta) {
+        return Complex.I.multiply(Complex.ofCartesian(theta, 
0)).exp().multiply(Complex.ofCartesian(r, 0));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testPolar2ComplexIllegalModulus() {
+        ComplexUtils.polar2Complex(-1, 0);
+    }
+
+    @Test
+    public void testPolar2ComplexNaN() {
+        TestUtils.assertSame(NAN, ComplexUtils.polar2Complex(nan, 1));
+        TestUtils.assertSame(NAN, ComplexUtils.polar2Complex(1, nan));
+        TestUtils.assertSame(NAN, ComplexUtils.polar2Complex(nan, nan));
+    }
+
+    @Test
+    public void testPolar2ComplexInf() {
+        TestUtils.assertSame(NAN, ComplexUtils.polar2Complex(1, inf));
+        TestUtils.assertSame(NAN, ComplexUtils.polar2Complex(1, negInf));
+        TestUtils.assertSame(NAN, ComplexUtils.polar2Complex(inf, inf));
+        TestUtils.assertSame(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));
+    }
+
+    @Test
+    public void testCExtract() {
+        final double[] real = new double[] { negInf, -123.45, 0, 1, 234.56, 
pi, inf };
+        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(Complex.ofReal(3), 
ComplexUtils.extractComplexFromRealArray(d, 3));
+        // Extract complex from real float array, index 3
+        TestUtils.assertSame(Complex.ofReal(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(Complex.ofCartesian(6, 7), 
ComplexUtils.extractComplexFromInterleavedArray(d, 3));
+        // Extract complex from interleaved float array, index 3
+        TestUtils.assertSame(Complex.ofCartesian(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
+        // Real double to complex, whole array
+        TestUtils.assertEquals(msg, cr, 
ComplexUtils.real2Complex(d),Math.ulp(1.0));
+        // Real float to complex, whole array
+        TestUtils.assertEquals(msg, cr, 
ComplexUtils.real2Complex(f),Math.ulp(1.0));
+        // 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.0));
+            // Real float to complex, 2d
+            TestUtils.assertEquals(msg, cr2d[i], 
ComplexUtils.real2Complex(f2d[i]),Math.ulp(1.0));
+        }
+        // 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.0));
+                // Real float to complex, 3d
+                TestUtils.assertEquals(msg, cr3d[i][j], 
ComplexUtils.real2Complex(f3d[i][j]),Math.ulp(1.0));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    @Test
+    public void testComplexToReal() {
+        setArrays();
+        // Real complex to double, whole array
+        TestUtils.assertEquals(msg, sr, 
ComplexUtils.complex2Real(c),Math.ulp(1.0));
+        // Real complex to float, whole array
+        TestUtils.assertEquals(msg, sfr, 
ComplexUtils.complex2RealFloat(c),Math.ulp(1.0f));
+        // 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.0));
+            // Real complex to float, 2d
+            TestUtils.assertEquals(msg, sfr2d[i], 
ComplexUtils.complex2RealFloat(c2d[i]),Math.ulp(1.0f));
+        }
+        // 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.0));
+                // Real complex to float, 3d
+                TestUtils.assertEquals(msg, sfr3d[i][j], 
ComplexUtils.complex2RealFloat(c3d[i][j]),Math.ulp(1.0f));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    // IMAGINARY <-> COMPLEX
+
+    @Test
+    public void testImaginaryToComplex() {
+        setArrays();
+        // Imaginary double to complex, whole array
+        TestUtils.assertEquals(msg, ci, 
ComplexUtils.imaginary2Complex(d),Math.ulp(1.0));
+        // Imaginary float to complex, whole array
+        TestUtils.assertEquals(msg, ci, 
ComplexUtils.imaginary2Complex(f),Math.ulp(1.0));
+        // 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.0));
+            // Imaginary float to complex, 2d
+            TestUtils.assertEquals(msg, ci2d[i], 
ComplexUtils.imaginary2Complex(f2d[i]),Math.ulp(1.0));
+        }
+        // 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.0));
+                // Imaginary float to complex, 3d
+                TestUtils.assertEquals(msg, ci3d[i][j], 
ComplexUtils.imaginary2Complex(f3d[i][j]),Math.ulp(1.0));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    @Test
+    public void testComplexToImaginary() {
+        setArrays();
+        // Imaginary complex to double, whole array
+        TestUtils.assertEquals(msg, si, 
ComplexUtils.complex2Imaginary(c),Math.ulp(1.0));
+        // Imaginary complex to float, whole array
+        TestUtils.assertEquals(msg, sfi, 
ComplexUtils.complex2ImaginaryFloat(c),Math.ulp(1.0f));
+        // 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.0));
+            // Imaginary complex to float, 2d
+            TestUtils.assertEquals(msg, sfi2d[i], 
ComplexUtils.complex2ImaginaryFloat(c2d[i]),Math.ulp(1.0f));
+        }
+        // 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.0));
+                // Imaginary complex to float, 3d
+                TestUtils.assertEquals(msg, sfi3d[i][j], 
ComplexUtils.complex2ImaginaryFloat(c3d[i][j]),Math.ulp(1.0f));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    // INTERLEAVED <-> COMPLEX
+
+    @Test
+    public void testInterleavedToComplex() {
+        setArrays();
+        // Interleaved double to complex, whole array
+        TestUtils.assertEquals(msg, c, 
ComplexUtils.interleaved2Complex(di),Math.ulp(1.0));
+        // Interleaved float to complex, whole array
+        TestUtils.assertEquals(msg, c, 
ComplexUtils.interleaved2Complex(fi),Math.ulp(1.0));
+        // 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.0));
+            // Interleaved float to complex, 2d
+            TestUtils.assertEquals(msg, c2d[i], 
ComplexUtils.interleaved2Complex(fi2d[i]),Math.ulp(1.0));
+        }
+        // 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.0));
+                // Interleaved float to complex, 3d
+                TestUtils.assertEquals(msg, c3d[i][j], 
ComplexUtils.interleaved2Complex(fi3d[i][j]),Math.ulp(1.0));
+            }
+        }
+        if (!msg.equals("")) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    @Test
+    public void testComplexToInterleaved() {
+        setArrays();
+        TestUtils.assertEquals(msg, di, 
ComplexUtils.complex2Interleaved(c),Math.ulp(1.0));
+        // Interleaved complex to float, whole array
+        TestUtils.assertEquals(msg, fi, 
ComplexUtils.complex2InterleavedFloat(c),Math.ulp(1.0f));
+        // 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.0));
+            // Interleaved complex to float, 2d
+            TestUtils.assertEquals(msg, fi2d[i], 
ComplexUtils.complex2InterleavedFloat(c2d[i]),Math.ulp(1.0f));
+        }
+        // 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.0));
+                // Interleaved complex to float, 3d
+                TestUtils.assertEquals(msg, fi3d[i][j], 
ComplexUtils.complex2InterleavedFloat(c3d[i][j]),Math.ulp(1.0f));
+            }
+        }
+        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.0));
+
+        // 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.0));
+        }
+        // 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.0));
+            }
+        }
+        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(Complex.ofCartesian(0, 0), cc, Math.ulp(0));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-numbers/blob/40418955/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/TestUtils.java
----------------------------------------------------------------------
diff --git 
a/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/TestUtils.java
 
b/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/TestUtils.java
new file mode 100644
index 0000000..ec370ff
--- /dev/null
+++ 
b/commons-numbers-complex-streams/src/test/java/org/apache/commons/numbers/complex/streams/TestUtils.java
@@ -0,0 +1,410 @@
+/*
+ * 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
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.streams;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.apache.commons.numbers.core.Precision;
+
+import org.junit.Assert;
+
+/**
+ * Test utilities.
+ * TODO: Cleanup (remove unused and obsolete methods).
+ */
+class TestUtils {
+    /**
+     * Collection of static methods used in math unit tests.
+     */
+    private TestUtils() {
+        super();
+    }
+
+    /**
+     * Verifies that expected and actual are within delta, or are both NaN or
+     * infinities of the same sign.
+     */
+    public static void assertEquals(double expected, double actual, double 
delta) {
+        Assert.assertEquals(null, expected, actual, delta);
+    }
+
+    /**
+     * Verifies that expected and actual are within delta, or are both NaN or
+     * infinities of the same sign.
+     */
+    public static void assertEquals(String msg, double expected, double 
actual, double delta) {
+        // check for NaN
+        if(Double.isNaN(expected)){
+            Assert.assertTrue("" + actual + " is not NaN.",
+                Double.isNaN(actual));
+        } else {
+            Assert.assertEquals(msg, expected, actual, delta);
+        }
+    }
+
+    /**
+     * Verifies that the two arguments are exactly the same, either
+     * both NaN or infinities of same sign, or identical floating point values.
+     */
+    public static void assertSame(double expected, double actual) {
+     Assert.assertEquals(expected, actual, 0);
+    }
+
+    /**
+     * Verifies that real and imaginary parts of the two complex arguments
+     * are exactly the same.  Also ensures that NaN / infinite components 
match.
+     */
+    public static void assertSame(Complex expected, Complex actual) {
+        assertSame(expected.getReal(), actual.getReal());
+        assertSame(expected.getImaginary(), actual.getImaginary());
+    }
+
+    /**
+     * Verifies that real and imaginary parts of the two complex arguments
+     * differ by at most delta.  Also ensures that NaN / infinite components 
match.
+     */
+    public static void assertEquals(Complex expected, Complex actual, double 
delta) {
+        Assert.assertEquals(expected.getReal(), actual.getReal(), delta);
+        Assert.assertEquals(expected.getImaginary(), actual.getImaginary(), 
delta);
+    }
+
+    /**
+     * Verifies that two double arrays have equal entries, up to tolerance
+     */
+    public static void assertEquals(double expected[], double observed[], 
double tolerance) {
+        assertEquals("Array comparison failure", expected, observed, 
tolerance);
+    }
+
+    /**
+     * Serializes an object to a bytes array and then recovers the object from 
the bytes array.
+     * Returns the deserialized object.
+     *
+     * @param o  object to serialize and recover
+     * @return  the recovered, deserialized object
+     */
+    public static Object serializeAndRecover(Object o) {
+        try {
+            // serialize the Object
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream so = new ObjectOutputStream(bos);
+            so.writeObject(o);
+
+            // deserialize the Object
+            ByteArrayInputStream bis = new 
ByteArrayInputStream(bos.toByteArray());
+            ObjectInputStream si = new ObjectInputStream(bis);
+            return si.readObject();
+        } catch (IOException ioe) {
+            return null;
+        } catch (ClassNotFoundException cnfe) {
+            return null;
+        }
+    }
+
+    /**
+     * Verifies that serialization preserves equals and hashCode.
+     * Serializes the object, then recovers it and checks equals and hash code.
+     *
+     * @param object  the object to serialize and recover
+     */
+    public static void checkSerializedEquality(Object object) {
+        Object object2 = serializeAndRecover(object);
+        Assert.assertEquals("Equals check", object, object2);
+        Assert.assertEquals("HashCode check", object.hashCode(), 
object2.hashCode());
+    }
+
+    /**
+     * Verifies that the relative error in actual vs. expected is less than or
+     * equal to relativeError.  If expected is infinite or NaN, actual must be
+     * the same (NaN or infinity of the same sign).
+     *
+     * @param expected expected value
+     * @param actual  observed value
+     * @param relativeError  maximum allowable relative error
+     */
+    public static void assertRelativelyEquals(double expected, double actual,
+            double relativeError) {
+        assertRelativelyEquals(null, expected, actual, relativeError);
+    }
+
+    /**
+     * Verifies that the relative error in actual vs. expected is less than or
+     * equal to relativeError.  If expected is infinite or NaN, actual must be
+     * the same (NaN or infinity of the same sign).
+     *
+     * @param msg  message to return with failure
+     * @param expected expected value
+     * @param actual  observed value
+     * @param relativeError  maximum allowable relative error
+     */
+    public static void assertRelativelyEquals(String msg, double expected,
+            double actual, double relativeError) {
+        if (Double.isNaN(expected)) {
+            Assert.assertTrue(msg, Double.isNaN(actual));
+        } else if (Double.isNaN(actual)) {
+            Assert.assertTrue(msg, Double.isNaN(expected));
+        } else if (Double.isInfinite(actual) || Double.isInfinite(expected)) {
+            Assert.assertEquals(expected, actual, relativeError);
+        } else if (expected == 0.0) {
+            Assert.assertEquals(msg, actual, expected, relativeError);
+        } else {
+            double absError = Math.abs(expected) * relativeError;
+            Assert.assertEquals(msg, expected, actual, absError);
+        }
+    }
+
+    /**
+     * Fails iff values does not contain a number within epsilon of z.
+     *
+     * @param msg  message to return with failure
+     * @param values complex array to search
+     * @param z  value sought
+     * @param epsilon  tolerance
+     */
+    public static void assertContains(String msg, Complex[] values,
+                                      Complex z, double epsilon) {
+        for (Complex value : values) {
+            if (Precision.equals(value.getReal(), z.getReal(), epsilon) &&
+                Precision.equals(value.getImaginary(), z.getImaginary(), 
epsilon)) {
+                return;
+            }
+        }
+        Assert.fail(msg + " Unable to find " + z);
+    }
+
+    /**
+     * Fails iff values does not contain a number within epsilon of z.
+     *
+     * @param values complex array to search
+     * @param z  value sought
+     * @param epsilon  tolerance
+     */
+    public static void assertContains(Complex[] values,
+            Complex z, double epsilon) {
+        assertContains(null, values, z, epsilon);
+    }
+
+    /**
+     * Fails iff values does not contain a number within epsilon of x.
+     *
+     * @param msg  message to return with failure
+     * @param values double array to search
+     * @param x value sought
+     * @param epsilon  tolerance
+     */
+    public static void assertContains(String msg, double[] values,
+            double x, double epsilon) {
+        for (double value : values) {
+            if (Precision.equals(value, x, epsilon)) {
+                return;
+            }
+        }
+        Assert.fail(msg + " Unable to find " + x);
+    }
+
+    /**
+     * Fails iff values does not contain a number within epsilon of x.
+     *
+     * @param values double array to search
+     * @param x value sought
+     * @param epsilon  tolerance
+     */
+    public static void assertContains(double[] values, double x,
+            double epsilon) {
+       assertContains(null, values, x, epsilon);
+    }
+
+    /** verifies that two arrays are close (sup norm) */
+    public static void assertEquals(String msg, double[] expected, double[] 
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 (!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, 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 (!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 (!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 (!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());
+        }
+    }
+
+    /**
+     * Updates observed counts of values in quartiles.
+     * counts[0] <-> 1st quartile ... counts[3] <-> top quartile
+     */
+    public static void updateCounts(double value, long[] counts, double[] 
quartiles) {
+        if (value < quartiles[0]) {
+            counts[0]++;
+        } else if (value > quartiles[2]) {
+            counts[3]++;
+        } else if (value > quartiles[1]) {
+            counts[2]++;
+        } else {
+            counts[1]++;
+        }
+    }
+
+    /**
+     * Eliminates points with zero mass from densityPoints and densityValues 
parallel
+     * arrays.  Returns the number of positive mass points and collapses the 
arrays so
+     * that the first <returned value> elements of the input arrays represent 
the positive
+     * mass points.
+     */
+    public static int eliminateZeroMassPoints(int[] densityPoints, double[] 
densityValues) {
+        int positiveMassCount = 0;
+        for (int i = 0; i < densityValues.length; i++) {
+            if (densityValues[i] > 0) {
+                positiveMassCount++;
+            }
+        }
+        if (positiveMassCount < densityValues.length) {
+            int[] newPoints = new int[positiveMassCount];
+            double[] newValues = new double[positiveMassCount];
+            int j = 0;
+            for (int i = 0; i < densityValues.length; i++) {
+                if (densityValues[i] > 0) {
+                    newPoints[j] = densityPoints[i];
+                    newValues[j] = densityValues[i];
+                    j++;
+                }
+            }
+            System.arraycopy(newPoints,0,densityPoints,0,positiveMassCount);
+            System.arraycopy(newValues,0,densityValues,0,positiveMassCount);
+        }
+        return positiveMassCount;
+    }
+
+    /**
+     * Returns true if the arguments are both NaN, are equal or are within the 
range
+     * of allowed error (inclusive).
+     *
+     * @param x first value
+     * @param y second value
+     * @param eps the amount of absolute error to allow.
+     * @return {@code true} if the values are equal or within range of each 
other,
+     * or both are NaN.
+     * @since 2.2
+     */
+    private static boolean equalsIncludingNaN(double x, double y, double eps) {
+        return equalsIncludingNaN(x, y) || (Math.abs(y - x) <= eps);
+    }
+
+    /**
+     * Returns true if the arguments are both NaN or they are
+     * equal as defined by {@link #equals(double,double) equals(x, y, 1)}.
+     *
+     * @param x first value
+     * @param y second value
+     * @return {@code true} if the values are equal or both are NaN.
+     * @since 2.2
+     */
+    private static boolean equalsIncludingNaN(double x, double y) {
+        return (x != x || y != y) ? !(x != x ^ y != y) : Precision.equals(x, 
y, 1);
+    }
+
+
+}
+
+

Reply via email to