blob: 1298587afbdc7e99f030290033ed23a53c71c48a [file] [log] [blame]
/*
* 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;
/**
* Static implementations of common {@link Complex} utilities functions.
*/
public class ComplexUtils {
/**
* Utility class.
*/
private ComplexUtils() {}
/**
* Creates a complex number from the given polar representation.
* <p>
* If either {@code r} or {@code theta} is NaN, or {@code theta} is
* infinite, {@link Complex#NaN} is returned.
* <p>
* 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
* polar2Complex(INFINITY, \(\pi\)) = INFINITY + INFINITY i
* polar2Complex(INFINITY, 0) = INFINITY + NaN i
* polar2Complex(INFINITY, \(-\frac{\pi}{4}\)) = INFINITY - INFINITY i
* polar2Complex(INFINITY, \(5\frac{\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 Complex}
* @since 1.1
*/
public static Complex polar2Complex(double r, double theta) {
if (r < 0) {
throw new NegativeModulusException(r);
}
return new Complex(r * Math.cos(theta), r * Math.sin(theta));
}
/**
* 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[]}
* @since 4.0
*/
public static Complex[] polar2Complex(double[] r, double[] theta) {
final int length = r.length;
final Complex[] c = new Complex[length];
for (int x = 0; x < length; x++) {
if (r[x] < 0) {
throw new NegativeModulusException(r[x]);
}
c[x] = new Complex(r[x] * Math.cos(theta[x]), r[x] * Math.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[][]}
* @since 4.0
*/
public static Complex[][] polar2Complex(double[][] r, double[][] theta) {
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 array of moduli
* @param theta array of arguments
* @return {@code Complex}
* @since 4.0
*/
public static Complex[][][] polar2Complex(double[][][] r, double[][][] theta) {
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 array 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 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 float array 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 array.
*
* @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.
*
* @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 {@code Complex} array
*
* @since 4.0
*/
public static Complex[] real2Complex(float[] real) {
int index = 0;
final Complex c[] = new Complex[real.length];
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 array
* @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 array
* @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 real component of {@code Complex[]} array to a {@code double[]}
* array.
*
* @param c {@code Complex} array
* @return 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 {@code 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 {@code 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 array
* @return 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 {@code 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.
*
* @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 array
* @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 array
* @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 a {@code Complex[]} array to a
* {@code double[]} array.
*
* @param c {@code Complex} array.
* @return 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 {@code 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 {@code 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 array
* @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 {@code 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
*
* @param interleaved array 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 float[] array 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
*
* @param c Complex array
* @return complex interleaved array 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 array alternating real and
* imaginary values
*
* @since 4.0
*/
public static double[][] complex2Interleaved(Complex[][] c, int interleavedDim) {
if (interleavedDim > 1 || interleavedDim < 0) {
new IndexOutOfRangeException(interleavedDim);
}
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 array 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 array alternating real and
* imaginary values
*
* @since 4.0
*/
public static double[][][] complex2Interleaved(Complex[][][] c, int interleavedDim) {
if (interleavedDim > 2 || interleavedDim < 0) {
new IndexOutOfRangeException(interleavedDim);
}
int width = c.length;
int height = c[0].length;
int depth = c[0][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 * 2][z] = c[x][y][z].getReal();
d[x][y * 2 + 1][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 array 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) {
new IndexOutOfRangeException(interleavedDim);
}
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) {
new IndexOutOfRangeException(interleavedDim);
}
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 array
* @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) {
new IndexOutOfRangeException(interleavedDim);
}
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 array
* @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 array
* @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) {
new IndexOutOfRangeException(interleavedDim);
}
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 / 2; 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 / 2; 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 / 2; 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 array
* @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 float array
* @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) {
new IndexOutOfRangeException(interleavedDim);
}
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 float array
* @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 float array
* @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) {
new IndexOutOfRangeException(interleavedDim);
}
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/2; 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/2; 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/2; 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 float[][][]} array to a
* {@code Complex[]} array. The third depth level of the array is assumed to
* be interleaved.
*
* @param d 3D complex interleaved float array
* @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 {@code 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 {@code 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[]}
*
* @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;
}
/**
* Exception to be throw when a negative value is passed as the modulus.
*/
private static class NegativeModulusException extends IllegalArgumentException {
/**
* @param r Wrong modulus.
*/
NegativeModulusException(double r) {
super("Modulus is negative: " + r);
}
}
/**
* Exception to be throw when an out-of-range index value is passed.
*/
private static class IndexOutOfRangeException extends IllegalArgumentException {
/**
* @param i Wrong index.
*/
IndexOutOfRangeException(int i) {
super("Out of range: " + i);
}
}
}