pl.edu.icm.jlargearrays.LargeArrayArithmetics Maven / Gradle / Ivy
Show all versions of JLargeArrays Show documentation
/* ***** BEGIN LICENSE BLOCK *****
* JLargeArrays
* Copyright (C) 2013 onward University of Warsaw, ICM
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
package pl.edu.icm.jlargearrays;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.commons.math3.util.FastMath;
/**
*
* Arithmetical operations on LargeArrays.
*
* @author Piotr Wendykier ([email protected])
*/
public class LargeArrayArithmetics
{
private LargeArrayArithmetics()
{
}
/**
* Complex sine.
*
* @param a complex number
*
* @return sin(a)
*/
public static float[] complexSin(float[] a)
{
float[] res = new float[2];
res[0] = (float) (FastMath.sin(a[0]) * FastMath.cosh(a[1]));
res[1] = (float) (FastMath.cos(a[0]) * FastMath.sinh(a[1]));
return res;
}
/**
* Complex sine.
*
* @param a complex number
*
* @return sin(a)
*/
public static double[] complexSin(double[] a)
{
double[] res = new double[2];
res[0] = FastMath.sin(a[0]) * FastMath.cosh(a[1]);
res[1] = FastMath.cos(a[0]) * FastMath.sinh(a[1]);
return res;
}
/**
* Complex cosine.
*
* @param a complex number
*
* @return cos(a)
*/
public static float[] complexCos(float[] a)
{
float[] res = new float[2];
res[0] = (float) (FastMath.cos(a[0]) * FastMath.cosh(a[1]));
res[1] = (float) (-FastMath.sin(a[0]) * FastMath.sinh(a[1]));
return res;
}
/**
* Complex cosine.
*
* @param a complex number
*
* @return cos(a)
*/
public static double[] complexCos(double[] a)
{
double[] res = new double[2];
res[0] = FastMath.cos(a[0]) * FastMath.cosh(a[1]);
res[1] = -FastMath.sin(a[0]) * FastMath.sinh(a[1]);
return res;
}
/**
* Complex tangent.
*
* @param a complex number
*
* @return tan(a)
*/
public static float[] complexTan(float[] a)
{
float[] s = complexSin(a);
float[] c = complexCos(a);
return complexDiv(s, c);
}
/**
* Complex tangent.
*
* @param a complex number
*
* @return tan(a)
*/
public static double[] complexTan(double[] a)
{
double[] s = complexSin(a);
double[] c = complexCos(a);
return complexDiv(s, c);
}
/**
* Complex addition.
*
* @param a complex number
* @param b complex number
*
* @return a+b
*/
public static float[] complexAdd(float[] a, float[] b)
{
float[] res = new float[2];
res[0] = a[0] + b[0];
res[1] = a[1] + b[1];
return res;
}
/**
* Complex addition.
*
* @param a complex number
* @param b complex number
*
* @return a+b
*/
public static double[] complexAdd(double[] a, double[] b)
{
double[] res = new double[2];
res[0] = a[0] + b[0];
res[1] = a[1] + b[1];
return res;
}
/**
* Complex subtraction.
*
* @param a complex number
* @param b complex number
*
* @return a-b
*/
public static float[] complexDiff(float[] a, float[] b)
{
float[] res = new float[2];
res[0] = a[0] - b[0];
res[1] = a[1] - b[1];
return res;
}
/**
* Complex subtraction.
*
* @param a complex number
* @param b complex number
*
* @return a-b
*/
public static double[] complexDiff(double[] a, double[] b)
{
double[] res = new double[2];
res[0] = a[0] - b[0];
res[1] = a[1] - b[1];
return res;
}
/**
* Complex multiplication.
*
* @param a complex number
* @param b complex number
*
* @return a*b
*/
public static float[] complexMult(float[] a, float[] b)
{
float[] res = new float[2];
res[0] = a[0] * b[0] - a[1] * b[1];
res[1] = a[1] * b[0] + a[0] * b[1];
return res;
}
/**
* Complex multiplication.
*
* @param a complex number
* @param b complex number
*
* @return a*b
*/
public static double[] complexMult(double[] a, double[] b)
{
double[] res = new double[2];
res[0] = a[0] * b[0] - a[1] * b[1];
res[1] = a[1] * b[0] + a[0] * b[1];
return res;
}
/**
* Complex division.
*
* @param a complex number
* @param b complex number
*
* @return a/b
*/
public static float[] complexDiv(float[] a, float[] b)
{
float r = b[0] * b[0] + b[1] * b[1];
float[] res = new float[2];
res[0] = (a[0] * b[0] + a[1] * b[1]) / r;
res[1] = (a[1] * b[0] - a[0] * b[1]) / r;
return res;
}
/**
* Complex division.
*
* @param a complex number
* @param b complex number
*
* @return a/b
*/
public static double[] complexDiv(double[] a, double[] b)
{
double r = b[0] * b[0] + b[1] * b[1];
double[] res = new double[2];
res[0] = (a[0] * b[0] + a[1] * b[1]) / r;
res[1] = (a[1] * b[0] - a[0] * b[1]) / r;
return res;
}
/**
* Complex power.
*
* @param a complex number
* @param n exponent
*
* @return a^n
*/
public static float[] complexPow(float[] a, double n)
{
float[] res = new float[2];
double mod = FastMath.pow(FastMath.sqrt(a[0] * a[0] + a[1] * a[1]), n);
double arg = FastMath.atan2(a[1], a[0]);
res[0] = (float) (mod * FastMath.cos(n * arg));
res[1] = (float) (mod * FastMath.sin(n * arg));
return res;
}
/**
* Complex power.
*
* @param a complex number
* @param n exponent
*
* @return a^n
*/
public static double[] complexPow(double[] a, double n)
{
double[] res = new double[2];
double mod = FastMath.pow(FastMath.sqrt(a[0] * a[0] + a[1] * a[1]), n);
double arg = FastMath.atan2(a[1], a[0]);
res[0] = mod * FastMath.cos(n * arg);
res[1] = mod * FastMath.sin(n * arg);
return res;
}
/**
* Complex power.
*
* @param a complex number
* @param n exponent
*
* @return a^n
*/
public static float[] complexPow(float[] a, float[] n)
{
return complexExp(complexMult(n, complexLog(a)));
}
/**
* Complex power.
*
* @param a complex number
* @param n exponent
*
* @return a^n
*/
public static double[] complexPow(double[] a, double[] n)
{
return complexExp(complexMult(n, complexLog(a)));
}
/**
* Complex square root.
*
* @param a complex number
*
* @return sqrt(a)
*/
public static float[] complexSqrt(float[] a)
{
float[] res = new float[2];
double mod = FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
res[0] = (float) FastMath.sqrt((a[0] + mod) / 2.0);
res[1] = (float) (FastMath.signum(a[1]) * FastMath.sqrt((-a[0] + mod) / 2.0));
return res;
}
/**
* Complex square root.
*
* @param a complex number
*
* @return sqrt(a)
*/
public static double[] complexSqrt(double[] a)
{
double[] res = new double[2];
double mod = FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
res[0] = FastMath.sqrt((a[0] + mod) / 2.0);
res[1] = FastMath.signum(a[1]) * FastMath.sqrt((-a[0] + mod) / 2.0);
return res;
}
/**
* Complex absolute value.
*
* @param a complex number
*
* @return abs(a)
*/
public static float complexAbs(float[] a)
{
return (float) FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
}
/**
* Complex absolute value.
*
* @param a complex number
*
* @return abs(a)
*/
public static double complexAbs(double[] a)
{
return FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
}
/**
* Complex natural logarithm.
*
* @param a complex number
*
* @return log(a)
*/
public static float[] complexLog(float[] a)
{
float[] res = new float[2];
double mod = FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
double arg = FastMath.atan2(a[1], a[0]);
res[0] = (float) FastMath.log(mod);
res[1] = (float) arg;
return res;
}
/**
* Complex natural logarithm.
*
* @param a complex number
*
* @return log(a)
*/
public static double[] complexLog(double[] a)
{
double[] res = new double[2];
double mod = FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
double arg = FastMath.atan2(a[1], a[0]);
res[0] = FastMath.log(mod);
res[1] = arg;
return res;
}
/**
* Complex base-10 logarithm.
*
* @param a complex number
*
* @return log10(a)
*/
public static float[] complexLog10(float[] a)
{
float[] res = new float[2];
final double scale = FastMath.log(10.0);
double mod = FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
double arg = FastMath.atan2(a[1], a[0]) / scale;
res[0] = (float) ((FastMath.log(mod) / scale));
res[1] = (float) arg;
return res;
}
/**
* Complex base-10 logarithm.
*
* @param a complex number
*
* @return log10(a)
*/
public static double[] complexLog10(double[] a)
{
double[] res = new double[2];
final double scale = FastMath.log(10.0);
double mod = FastMath.sqrt(a[0] * a[0] + a[1] * a[1]);
double arg = FastMath.atan2(a[1], a[0]) / scale;
res[0] = (FastMath.log(mod) / scale);
res[1] = arg;
return res;
}
/**
* Complex exponent.
*
* @param a complex number
*
* @return exp(a)
*/
public static float[] complexExp(float[] a)
{
float[] res = new float[2];
res[0] = (float) (FastMath.exp(a[0]) * FastMath.cos(a[1]));
res[1] = (float) (FastMath.exp(a[0]) * FastMath.sin(a[1]));
return res;
}
/**
* Complex exponent.
*
* @param a complex number
*
* @return exp(a)
*/
public static double[] complexExp(double[] a)
{
double[] res = new double[2];
res[0] = FastMath.exp(a[0]) * FastMath.cos(a[1]);
res[1] = FastMath.exp(a[0]) * FastMath.sin(a[1]);
return res;
}
/**
* Complex inverse sine.
*
* @param a complex number
*
* @return asin(a)
*/
public static float[] complexAsin(float[] a)
{
float[] res;
float[] i = new float[]{0, 1};
float[] mi = new float[]{0, -1};
res = complexMult(a, a);
res[0] = 1 - res[0];
res[1] = 1 - res[1];
res = complexLog(res);
i = complexMult(i, a);
res[0] += i[0];
res[1] += i[1];
return complexMult(mi, res);
}
/**
* Complex inverse sine.
*
* @param a complex number
*
* @return asin(a)
*/
public static double[] complexAsin(double[] a)
{
double[] res;
double[] i = new double[]{0, 1};
double[] mi = new double[]{0, -1};
res = complexMult(a, a);
res[0] = 1 - res[0];
res[1] = 1 - res[1];
res = complexLog(res);
i = complexMult(i, a);
res[0] += i[0];
res[1] += i[1];
return complexMult(mi, res);
}
/**
* Complex inverse cosine.
*
* @param a complex number
*
* @return acos(a)
*/
public static float[] complexAcos(float[] a)
{
float[] res;
float[] i = new float[]{0, 1};
float[] mi = new float[]{0, -1};
res = complexMult(a, a);
res[0] = 1 - res[0];
res[1] = 1 - res[1];
res = complexMult(i, res);
res[0] += a[0];
res[1] += a[1];
res = complexLog(res);
return complexMult(mi, res);
}
/**
* Complex inverse cosine.
*
* @param a complex number
*
* @return acos(a)
*/
public static double[] complexAcos(double[] a)
{
double[] res;
double[] i = new double[]{0, 1};
double[] mi = new double[]{0, -1};
res = complexMult(a, a);
res[0] = 1 - res[0];
res[1] = 1 - res[1];
res = complexMult(i, res);
res[0] += a[0];
res[1] += a[1];
res = complexLog(res);
return complexMult(mi, res);
}
/**
* Complex inverse tangent.
*
* @param a complex number
*
* @return atan(a)
*/
public static float[] complexAtan(float[] a)
{
float[] res = new float[2];
float[] tmp = new float[2];
float[] i = new float[]{0, 1};
res[0] = i[0] + a[0];
res[1] = i[1] + a[1];
tmp[0] = i[0] - a[0];
tmp[1] = i[1] - a[1];
res = complexLog(complexDiv(res, tmp));
i[1] /= 2.0;
return complexMult(i, res);
}
/**
* Complex inverse tangent.
*
* @param a complex number
*
* @return atan(a)
*/
public static double[] complexAtan(double[] a)
{
double[] res = new double[2];
double[] tmp = new double[2];
double[] i = new double[]{0, 1};
res[0] = i[0] + a[0];
res[1] = i[1] + a[1];
tmp[0] = i[0] - a[0];
tmp[1] = i[1] - a[1];
res = complexLog(complexDiv(res, tmp));
i[1] /= 2.0;
return complexMult(i, res);
}
/**
* Addition of two LargeArrays.
*
* @param a input array
* @param b input array
*
* @return a+b
*/
public static LargeArray add(final LargeArray a, final LargeArray b)
{
LargeArrayType out_type = a.getType().compareTo(b.getType()) >= 0 ? a.getType() : b.getType();
return add(a, b, out_type);
}
/**
* Addition of two LargeArrays.
*
* @param a input array
* @param b input array
* @param out_type output type
*
* @return a+b
*/
public static LargeArray add(final LargeArray a, final LargeArray b, final LargeArrayType out_type)
{
if (a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()) {
throw new IllegalArgumentException("a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant() && b.isConstant()) {
if (out_type.isIntegerNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getLong(0) + b.getLong(0));
} else if (out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getDouble(0) + b.getDouble(0));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
float[] elem_b = ((ComplexFloatLargeArray) b).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, new float[]{elem_a[0] + elem_b[0], elem_a[1] + elem_b[1]});
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
double[] elem_b = ((ComplexDoubleLargeArray) b).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, new double[]{elem_a[0] + elem_b[0], elem_a[1] + elem_b[1]});
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) + b.getLong(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setLong(k, a.getLong(k) + b.getLong(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) + b.getLong(i));
}
}
}
} else if (out_type.isRealNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) + b.getDouble(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, a.getDouble(k) + b.getDouble(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) + b.getDouble(i));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexFloatLargeArray _bc = (ComplexFloatLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
elem_res[0] = elem_a[0] + elem_b[0];
elem_res[1] = elem_a[1] + elem_b[1];
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
float[] elem_b = _bc.getComplexFloat(k);
elem_res[0] = elem_a[0] + elem_b[0];
elem_res[1] = elem_a[1] + elem_b[1];
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
elem_res[0] = elem_a[0] + elem_b[0];
elem_res[1] = elem_a[1] + elem_b[1];
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexDoubleLargeArray _bc = (ComplexDoubleLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
elem_res[0] = elem_a[0] + elem_b[0];
elem_res[1] = elem_a[1] + elem_b[1];
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double[] elem_b = _bc.getComplexDouble(k);
elem_res[0] = elem_a[0] + elem_b[0];
elem_res[1] = elem_a[1] + elem_b[1];
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
elem_res[0] = elem_a[0] + elem_b[0];
elem_res[1] = elem_a[1] + elem_b[1];
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Subtraction of two LargeArrays.
*
* @param a input array
* @param b input array
*
* @return a-b
*/
public static LargeArray diff(final LargeArray a, final LargeArray b)
{
LargeArrayType out_type = a.getType().compareTo(b.getType()) >= 0 ? a.getType() : b.getType();
return diff(a, b, out_type);
}
/**
* Subtraction of two LargeArrays.
*
* @param a input array
* @param b input array
* @param out_type output type
*
* @return a-b
*/
public static LargeArray diff(final LargeArray a, final LargeArray b, final LargeArrayType out_type)
{
if (a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()) {
throw new IllegalArgumentException("a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant() && b.isConstant()) {
if (out_type.isIntegerNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getLong(0) - b.getLong(0));
} else if (out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getDouble(0) - b.getDouble(0));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
float[] elem_b = ((ComplexFloatLargeArray) b).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, new float[]{elem_a[0] - elem_b[0], elem_a[1] - elem_b[1]});
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
double[] elem_b = ((ComplexDoubleLargeArray) b).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, new double[]{elem_a[0] - elem_b[0], elem_a[1] - elem_b[1]});
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) - b.getLong(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setLong(k, a.getLong(k) - b.getLong(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) - b.getLong(i));
}
}
}
} else if (out_type.isRealNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) - b.getDouble(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, a.getDouble(k) - b.getDouble(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) - b.getDouble(i));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexFloatLargeArray _bc = (ComplexFloatLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
elem_res[0] = elem_a[0] - elem_b[0];
elem_res[1] = elem_a[1] - elem_b[1];
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
float[] elem_b = _bc.getComplexFloat(k);
elem_res[0] = elem_a[0] - elem_b[0];
elem_res[1] = elem_a[1] - elem_b[1];
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
elem_res[0] = elem_a[0] - elem_b[0];
elem_res[1] = elem_a[1] - elem_b[1];
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexDoubleLargeArray _bc = (ComplexDoubleLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
elem_res[0] = elem_a[0] - elem_b[0];
elem_res[1] = elem_a[1] - elem_b[1];
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double[] elem_b = _bc.getComplexDouble(k);
elem_res[0] = elem_a[0] - elem_b[0];
elem_res[1] = elem_a[1] - elem_b[1];
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
elem_res[0] = elem_a[0] - elem_b[0];
elem_res[1] = elem_a[1] - elem_b[1];
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Multiplication of two LargeArrays.
*
* @param a input array
* @param b input array
*
* @return a*b
*/
public static LargeArray mult(final LargeArray a, final LargeArray b)
{
LargeArrayType out_type = a.getType().compareTo(b.getType()) >= 0 ? a.getType() : b.getType();
return mult(a, b, out_type);
}
/**
* Multiplication of two LargeArrays.
*
* @param a input array
* @param b input array
* @param out_type output type
*
* @return a*b
*/
public static LargeArray mult(final LargeArray a, final LargeArray b, final LargeArrayType out_type)
{
if (a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()) {
throw new IllegalArgumentException("a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant() && b.isConstant()) {
if (out_type.isIntegerNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getLong(0) * b.getLong(0));
} else if (out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getDouble(0) * b.getDouble(0));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
float[] elem_b = ((ComplexFloatLargeArray) b).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexMult(elem_a, elem_b));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
double[] elem_b = ((ComplexDoubleLargeArray) b).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexMult(elem_a, elem_b));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) * b.getLong(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setLong(k, a.getLong(k) * b.getLong(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) * b.getLong(i));
}
}
}
} else if (out_type.isRealNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) * b.getDouble(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, a.getDouble(k) * b.getDouble(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) * b.getDouble(i));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexFloatLargeArray _bc = (ComplexFloatLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
elem_res[0] = elem_a[0] * elem_b[0] - elem_a[1] * elem_b[1];
elem_res[1] = elem_a[1] * elem_b[0] + elem_a[0] * elem_b[1];
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
float[] elem_b = _bc.getComplexFloat(k);
elem_res[0] = elem_a[0] * elem_b[0] - elem_a[1] * elem_b[1];
elem_res[1] = elem_a[1] * elem_b[0] + elem_a[0] * elem_b[1];
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
elem_res[0] = elem_a[0] * elem_b[0] - elem_a[1] * elem_b[1];
elem_res[1] = elem_a[1] * elem_b[0] + elem_a[0] * elem_b[1];
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexDoubleLargeArray _bc = (ComplexDoubleLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
elem_res[0] = elem_a[0] * elem_b[0] - elem_a[1] * elem_b[1];
elem_res[1] = elem_a[1] * elem_b[0] + elem_a[0] * elem_b[1];
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double[] elem_b = _bc.getComplexDouble(k);
elem_res[0] = elem_a[0] * elem_b[0] - elem_a[1] * elem_b[1];
elem_res[1] = elem_a[1] * elem_b[0] + elem_a[0] * elem_b[1];
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
elem_res[0] = elem_a[0] * elem_b[0] - elem_a[1] * elem_b[1];
elem_res[1] = elem_a[1] * elem_b[0] + elem_a[0] * elem_b[1];
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Division of two LargeArrays.
*
* @param a input array
* @param b input array
*
* @return a/b
*/
public static LargeArray div(final LargeArray a, final LargeArray b)
{
LargeArrayType out_type = a.getType().compareTo(b.getType()) >= 0 ? a.getType() : b.getType();
return div(a, b, out_type);
}
/**
* Division of two LargeArrays.
*
* @param a input array
* @param b input array
* @param out_type output type
*
* @return a/b
*/
public static LargeArray div(final LargeArray a, final LargeArray b, final LargeArrayType out_type)
{
if (a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()) {
throw new IllegalArgumentException("a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant() && b.isConstant()) {
if (out_type.isIntegerNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getLong(0) / b.getLong(0));
} else if (out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, a.getDouble(0) / b.getDouble(0));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
float[] elem_b = ((ComplexFloatLargeArray) b).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexDiv(elem_a, elem_b));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
double[] elem_b = ((ComplexDoubleLargeArray) b).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexDiv(elem_a, elem_b));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) / b.getLong(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setLong(k, a.getLong(k) / b.getLong(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setLong(i, a.getLong(i) / b.getLong(i));
}
}
}
} else if (out_type.isRealNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) / b.getDouble(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, a.getDouble(k) / b.getDouble(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, a.getDouble(i) / b.getDouble(i));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexFloatLargeArray _bc = (ComplexFloatLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
float r = elem_b[0] * elem_b[0] + elem_b[1] * elem_b[1];
elem_res[0] = (elem_a[0] * elem_b[0] + elem_a[1] * elem_b[1]) / r;
elem_res[1] = (elem_a[1] * elem_b[0] - elem_a[0] * elem_b[1]) / r;
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
float[] elem_b = _bc.getComplexFloat(k);
float r = elem_b[0] * elem_b[0] + elem_b[1] * elem_b[1];
elem_res[0] = (elem_a[0] * elem_b[0] + elem_a[1] * elem_b[1]) / r;
elem_res[1] = (elem_a[1] * elem_b[0] - elem_a[0] * elem_b[1]) / r;
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
float r = elem_b[0] * elem_b[0] + elem_b[1] * elem_b[1];
elem_res[0] = (elem_a[0] * elem_b[0] + elem_a[1] * elem_b[1]) / r;
elem_res[1] = (elem_a[1] * elem_b[0] - elem_a[0] * elem_b[1]) / r;
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexDoubleLargeArray _bc = (ComplexDoubleLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
double r = elem_b[0] * elem_b[0] + elem_b[1] * elem_b[1];
elem_res[0] = (elem_a[0] * elem_b[0] + elem_a[1] * elem_b[1]) / r;
elem_res[1] = (elem_a[1] * elem_b[0] - elem_a[0] * elem_b[1]) / r;
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double[] elem_b = _bc.getComplexDouble(k);
double r = elem_b[0] * elem_b[0] + elem_b[1] * elem_b[1];
elem_res[0] = (elem_a[0] * elem_b[0] + elem_a[1] * elem_b[1]) / r;
elem_res[1] = (elem_a[1] * elem_b[0] - elem_a[0] * elem_b[1]) / r;
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
double r = elem_b[0] * elem_b[0] + elem_b[1] * elem_b[1];
elem_res[0] = (elem_a[0] * elem_b[0] + elem_a[1] * elem_b[1]) / r;
elem_res[1] = (elem_a[1] * elem_b[0] - elem_a[0] * elem_b[1]) / r;
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Power of LargeArray.
*
* @param a input array
* @param n exponent
*
* @return a^n
*/
public static LargeArray pow(final LargeArray a, final double n)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return pow(a, n, out_type);
}
/**
* Power of LargeArray.
*
* @param a input array
* @param n exponent
* @param out_type output type
*
* @return a^n
*/
public static LargeArray pow(final LargeArray a, final double n, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.pow(a.getDouble(0), n));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexPow(elem_a, n));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexPow(elem_a, n));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.pow(a.getDouble(i), n));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.pow(a.getDouble(k), n));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.pow(a.getDouble(i), n));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.pow(FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]), n);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = (float) (mod * FastMath.cos(n * arg));
elem_res[1] = (float) (mod * FastMath.sin(n * arg));
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
double mod = FastMath.pow(FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]), n);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = (float) (mod * FastMath.cos(n * arg));
elem_res[1] = (float) (mod * FastMath.sin(n * arg));
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.pow(FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]), n);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = (float) (mod * FastMath.cos(n * arg));
elem_res[1] = (float) (mod * FastMath.sin(n * arg));
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.pow(FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]), n);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = mod * FastMath.cos(n * arg);
elem_res[1] = mod * FastMath.sin(n * arg);
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double mod = FastMath.pow(FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]), n);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = mod * FastMath.cos(n * arg);
elem_res[1] = mod * FastMath.sin(n * arg);
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.pow(FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]), n);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = mod * FastMath.cos(n * arg);
elem_res[1] = mod * FastMath.sin(n * arg);
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Power of two LargeArrays.
*
* @param a input array
* @param b input array
*
* @return a^b
*/
public static LargeArray pow(final LargeArray a, final LargeArray b)
{
LargeArrayType out_type = a.getType().compareTo(b.getType()) >= 0 ? a.getType() : b.getType();
if (out_type.isIntegerNumericType()) {
out_type = LargeArrayType.FLOAT;
}
return pow(a, b, out_type);
}
/**
* Power of two LargeArrays.
*
* @param a input array
* @param b input array
* @param out_type output type
*
* @return a^b
*/
public static LargeArray pow(final LargeArray a, final LargeArray b, final LargeArrayType out_type)
{
if (a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()) {
throw new IllegalArgumentException("a == null || b == null || a.length() != b.length() || !a.isNumeric() || !b.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant() && b.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.pow(a.getDouble(0), b.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
float[] elem_b = ((ComplexFloatLargeArray) b).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexPow(elem_a, elem_b));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
double[] elem_b = ((ComplexDoubleLargeArray) b).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexPow(elem_a, elem_b));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
res = LargeArrayUtils.create(out_type, length, false);
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.pow(a.getDouble(i), b.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.pow(a.getDouble(k), b.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.pow(a.getDouble(i), b.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexFloatLargeArray _bc = (ComplexFloatLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
resc.setComplexFloat(i, complexPow(elem_a, elem_b));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
float[] elem_b = _bc.getComplexFloat(k);
resc.setComplexFloat(k, complexPow(elem_a, elem_b));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] elem_b = _bc.getComplexFloat(i);
resc.setComplexFloat(i, complexPow(elem_a, elem_b));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) LargeArrayUtils.convert(a, out_type);
final ComplexDoubleLargeArray _bc = (ComplexDoubleLargeArray) LargeArrayUtils.convert(b, out_type);
if (_ac.getType() == a.getType() && _bc.getType() == b.getType()) {
res = LargeArrayUtils.create(out_type, length, false);
} else if (_ac.getType() != a.getType()) {
res = _ac;
} else {
res = _bc;
}
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
resc.setComplexDouble(i, complexPow(elem_a, elem_b));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double[] elem_b = _bc.getComplexDouble(k);
resc.setComplexDouble(k, complexPow(elem_a, elem_b));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] elem_b = _bc.getComplexDouble(i);
resc.setComplexDouble(i, complexPow(elem_a, elem_b));
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Negation of LargeArray.
*
* @param a input array
*
* @return -a
*/
public static LargeArray neg(final LargeArray a)
{
LargeArrayType out_type = a.getType();
return neg(a, out_type);
}
/**
* Negation of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return -a
*/
public static LargeArray neg(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, -a.getLong(0));
} else if (out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, -a.getDouble(0));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, new float[]{-elem_a[0], -elem_a[1]});
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, new double[]{-elem_a[0], -elem_a[1]});
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setLong(i, -a.getLong(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setLong(k, -a.getLong(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setLong(i, -a.getLong(i));
}
}
}
} else if (out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, -a.getDouble(i));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, -a.getDouble(k));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, -a.getDouble(i));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = -elem_a[0];
elem_res[1] = -elem_a[1];
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
elem_res[0] = -elem_a[0];
elem_res[1] = -elem_a[1];
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = -elem_a[0];
elem_res[1] = -elem_a[1];
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = -elem_a[0];
elem_res[1] = -elem_a[1];
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
elem_res[0] = -elem_a[0];
elem_res[1] = -elem_a[1];
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = -elem_a[0];
elem_res[1] = -elem_a[1];
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Square root of LargeArray. For complex arrays the principal square root is returned.
*
* @param a input array
*
* @return sqrt(a)
*/
public static LargeArray sqrt(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return sqrt(a, out_type);
}
/**
* Square root of LargeArray. For complex arrays the principal square root is returned.
*
* @param a input array
* @param out_type output type
*
* @return sqrt(a)
*/
public static LargeArray sqrt(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.sqrt(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexSqrt(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexSqrt(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.sqrt(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.sqrt(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.sqrt(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
elem_res[0] = (float) (FastMath.sqrt((elem_a[0] + mod) / 2.0));
elem_res[1] = (float) (FastMath.signum(elem_a[1]) * FastMath.sqrt((-elem_a[0] + mod) / 2.0));
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
elem_res[0] = (float) (FastMath.sqrt((elem_a[0] + mod) / 2.0));
elem_res[1] = (float) (FastMath.signum(elem_a[1]) * FastMath.sqrt((-elem_a[0] + mod) / 2.0));
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
elem_res[0] = (float) (FastMath.sqrt((elem_a[0] + mod) / 2.0));
elem_res[1] = (float) (FastMath.signum(elem_a[1]) * FastMath.sqrt((-elem_a[0] + mod) / 2.0));
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
elem_res[0] = FastMath.sqrt((elem_a[0] + mod) / 2.0);
elem_res[1] = FastMath.signum(elem_a[1]) * FastMath.sqrt((-elem_a[0] + mod) / 2.0);
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
elem_res[0] = FastMath.sqrt((elem_a[0] + mod) / 2.0);
elem_res[1] = FastMath.signum(elem_a[1]) * FastMath.sqrt((-elem_a[0] + mod) / 2.0);
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
elem_res[0] = FastMath.sqrt((elem_a[0] + mod) / 2.0);
elem_res[1] = FastMath.signum(elem_a[1]) * FastMath.sqrt((-elem_a[0] + mod) / 2.0);
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Natural logarithm of LargeArray. For complex arrays the principal value logarithm is returned.
*
* @param a input array
*
* @return log(a)
*/
public static LargeArray log(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return log(a, out_type);
}
/**
* Natural logarithm of LargeArray. For complex arrays the principal value logarithm is returned.
*
* @param a input array
* @param out_type output type
*
* @return log(a)
*/
public static LargeArray log(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.log(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexLog(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexLog(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.log(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.log(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.log(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = (float) (FastMath.log(mod));
elem_res[1] = (float) arg;
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = (float) (FastMath.log(mod));
elem_res[1] = (float) arg;
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = (float) (FastMath.log(mod));
elem_res[1] = (float) arg;
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = FastMath.log(mod);
elem_res[1] = arg;
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = FastMath.log(mod);
elem_res[1] = arg;
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]);
elem_res[0] = FastMath.log(mod);
elem_res[1] = arg;
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Base-10 logarithm of LargeArray. For complex arrays the principal value logarithm is returned.
*
* @param a input array
*
* @return log10(a)
*/
public static LargeArray log10(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return log10(a, out_type);
}
/**
* Base-10 logarithm of LargeArray. For complex arrays the principal value logarithm is returned.
*
* @param a input array
*
* @param out_type output type
*
* @return log10(a)
*/
public static LargeArray log10(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.log10(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexLog10(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexLog10(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.log10(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.log10(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.log10(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final double scale = FastMath.log(10.0);
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]) / scale;
elem_res[0] = (float) (FastMath.log(mod) / scale);
elem_res[1] = (float) arg;
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]) / scale;
elem_res[0] = (float) (FastMath.log(mod) / scale);
elem_res[1] = (float) arg;
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]) / scale;
elem_res[0] = (float) (FastMath.log(mod) / scale);
elem_res[1] = (float) arg;
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final double scale = FastMath.log(10.0);
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]) / scale;
elem_res[0] = (FastMath.log(mod) / scale);
elem_res[1] = arg;
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]) / scale;
elem_res[0] = (FastMath.log(mod) / scale);
elem_res[1] = arg;
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double mod = FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]);
double arg = FastMath.atan2(elem_a[1], elem_a[0]) / scale;
elem_res[0] = (FastMath.log(mod) / scale);
elem_res[1] = arg;
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Exponent of LargeArray.
*
* @param a input array
*
* @return exp(a)
*/
public static LargeArray exp(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return exp(a, out_type);
}
/**
* Exponent of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return exp(a)
*/
public static LargeArray exp(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.exp(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexExp(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexExp(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.exp(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.exp(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.exp(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = (float) (FastMath.exp(elem_a[0]) * FastMath.cos(elem_a[1]));
elem_res[1] = (float) (FastMath.exp(elem_a[0]) * FastMath.sin(elem_a[1]));
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
elem_res[0] = (float) (FastMath.exp(elem_a[0]) * FastMath.cos(elem_a[1]));
elem_res[1] = (float) (FastMath.exp(elem_a[0]) * FastMath.sin(elem_a[1]));
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = (float) (FastMath.exp(elem_a[0]) * FastMath.cos(elem_a[1]));
elem_res[1] = (float) (FastMath.exp(elem_a[0]) * FastMath.sin(elem_a[1]));
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = FastMath.exp(elem_a[0]) * FastMath.cos(elem_a[1]);
elem_res[1] = FastMath.exp(elem_a[0]) * FastMath.sin(elem_a[1]);
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
elem_res[0] = FastMath.exp(elem_a[0]) * FastMath.cos(elem_a[1]);
elem_res[1] = FastMath.exp(elem_a[0]) * FastMath.sin(elem_a[1]);
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = FastMath.exp(elem_a[0]) * FastMath.cos(elem_a[1]);
elem_res[1] = FastMath.exp(elem_a[0]) * FastMath.sin(elem_a[1]);
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Absolute value of LargeArray.
*
* @param a input array
*
* @return |a|
*/
public static LargeArray abs(final LargeArray a)
{
LargeArrayType out_type = a.getType() == LargeArrayType.COMPLEX_FLOAT ? LargeArrayType.FLOAT : a.getType() == LargeArrayType.COMPLEX_DOUBLE ? LargeArrayType.DOUBLE : a.getType();
return abs(a, out_type);
}
/**
* Absolute value of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return |a|
*/
public static LargeArray abs(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() ) {
if (a.getType().isComplexNumericType()) {
double[] elem;
if (a.getType() == LargeArrayType.COMPLEX_FLOAT) {
elem = ((ComplexFloatLargeArray) a).getComplexDouble(0);
} else {
elem = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
}
return LargeArrayUtils.createConstant(out_type, length, FastMath.sqrt(elem[0] * elem[0] + elem[1] * elem[1]));
} else {
return LargeArrayUtils.createConstant(out_type, length, FastMath.abs(a.getLong(0)));
}
} else if (out_type.isRealNumericType()) {
if (a.getType().isComplexNumericType()) {
double[] elem;
if (a.getType() == LargeArrayType.COMPLEX_FLOAT) {
elem = ((ComplexFloatLargeArray) a).getComplexDouble(0);
} else {
elem = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
}
return LargeArrayUtils.createConstant(out_type, length, FastMath.sqrt(elem[0] * elem[0] + elem[1] * elem[1]));
} else {
return LargeArrayUtils.createConstant(out_type, length, FastMath.abs(a.getDouble(0)));
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (a.getType().isIntegerNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.abs(a.getLong(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setLong(k, FastMath.abs(a.getLong(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.abs(a.getDouble(i)));
}
}
}
} else if (a.getType().isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.abs(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.abs(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.abs(a.getDouble(i)));
}
}
}
} else if (a.getType() == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
res.setDouble(i, FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
res.setDouble(k, FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
res.setDouble(i, FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]));
}
}
}
} else if (a.getType() == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
res.setDouble(i, FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
res.setDouble(k, FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
res.setDouble(i, FastMath.sqrt(elem_a[0] * elem_a[0] + elem_a[1] * elem_a[1]));
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Sine of LargeArray.
*
* @param a input array
*
* @return sin(a)
*/
public static LargeArray sin(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return sin(a, out_type);
}
/**
* Sine of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return sin(a)
*/
public static LargeArray sin(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.sin(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexSin(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexSin(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.sin(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.sin(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.sin(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = (float) (FastMath.sin(elem_a[0]) * FastMath.cosh(elem_a[1]));
elem_res[1] = (float) (FastMath.cos(elem_a[0]) * FastMath.sinh(elem_a[1]));
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
elem_res[0] = (float) (FastMath.sin(elem_a[0]) * FastMath.cosh(elem_a[1]));
elem_res[1] = (float) (FastMath.cos(elem_a[0]) * FastMath.sinh(elem_a[1]));
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = (float) (FastMath.sin(elem_a[0]) * FastMath.cosh(elem_a[1]));
elem_res[1] = (float) (FastMath.cos(elem_a[0]) * FastMath.sinh(elem_a[1]));
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = FastMath.sin(elem_a[0]) * FastMath.cosh(elem_a[1]);
elem_res[1] = FastMath.cos(elem_a[0]) * FastMath.sinh(elem_a[1]);
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
elem_res[0] = FastMath.sin(elem_a[0]) * FastMath.cosh(elem_a[1]);
elem_res[1] = FastMath.cos(elem_a[0]) * FastMath.sinh(elem_a[1]);
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = FastMath.sin(elem_a[0]) * FastMath.cosh(elem_a[1]);
elem_res[1] = FastMath.cos(elem_a[0]) * FastMath.sinh(elem_a[1]);
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Cosine of LargeArray.
*
* @param a input array
*
* @return cos(a)
*/
public static LargeArray cos(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return cos(a, out_type);
}
/**
* Cosine of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return cos(a)
*/
public static LargeArray cos(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.cos(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexCos(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexCos(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.cos(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.cos(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.cos(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = (float) (FastMath.cos(elem_a[0]) * FastMath.cosh(elem_a[1]));
elem_res[1] = (float) (-FastMath.sin(elem_a[0]) * FastMath.sinh(elem_a[1]));
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
float[] elem_res = new float[2];
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
elem_res[0] = (float) (FastMath.cos(elem_a[0]) * FastMath.cosh(elem_a[1]));
elem_res[1] = (float) (-FastMath.sin(elem_a[0]) * FastMath.sinh(elem_a[1]));
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
float[] elem_res = new float[2];
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
elem_res[0] = (float) (FastMath.cos(elem_a[0]) * FastMath.cosh(elem_a[1]));
elem_res[1] = (float) (-FastMath.sin(elem_a[0]) * FastMath.sinh(elem_a[1]));
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = FastMath.cos(elem_a[0]) * FastMath.cosh(elem_a[1]);
elem_res[1] = -FastMath.sin(elem_a[0]) * FastMath.sinh(elem_a[1]);
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
double[] elem_res = new double[2];
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
elem_res[0] = FastMath.cos(elem_a[0]) * FastMath.cosh(elem_a[1]);
elem_res[1] = -FastMath.sin(elem_a[0]) * FastMath.sinh(elem_a[1]);
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
double[] elem_res = new double[2];
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
elem_res[0] = FastMath.cos(elem_a[0]) * FastMath.cosh(elem_a[1]);
elem_res[1] = -FastMath.sin(elem_a[0]) * FastMath.sinh(elem_a[1]);
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Tangent of LargeArray.
*
* @param a input array
*
* @return tan(a)
*/
public static LargeArray tan(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return tan(a, out_type);
}
/**
* Tangent of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return tan(a)
*/
public static LargeArray tan(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.tan(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexTan(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexTan(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.tan(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.tan(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.tan(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] s = complexSin(elem_a);
float[] c = complexCos(elem_a);
float[] elem_res = complexDiv(s, c);
resc.setComplexFloat(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
float[] s = complexSin(elem_a);
float[] c = complexCos(elem_a);
float[] elem_res = complexDiv(s, c);
resc.setComplexFloat(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
float[] s = complexSin(elem_a);
float[] c = complexCos(elem_a);
float[] elem_res = complexDiv(s, c);
resc.setComplexFloat(i, elem_res);
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] s = complexSin(elem_a);
double[] c = complexCos(elem_a);
double[] elem_res = complexDiv(s, c);
resc.setComplexDouble(i, elem_res);
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
double[] s = complexSin(elem_a);
double[] c = complexCos(elem_a);
double[] elem_res = complexDiv(s, c);
resc.setComplexDouble(k, elem_res);
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
double[] s = complexSin(elem_a);
double[] c = complexCos(elem_a);
double[] elem_res = complexDiv(s, c);
resc.setComplexDouble(i, elem_res);
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Inverse sine of LargeArray.
*
* @param a input array
*
* @return asin(a)
*/
public static LargeArray asin(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return asin(a, out_type);
}
/**
* Inverse sine of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return asin(a)
*/
public static LargeArray asin(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.asin(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexAsin(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexAsin(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.asin(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.asin(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.asin(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
resc.setComplexFloat(i, complexAsin(elem_a));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
resc.setComplexFloat(k, complexAsin(elem_a));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
resc.setComplexFloat(i, complexAsin(elem_a));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
resc.setComplexDouble(i, complexAsin(elem_a));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
resc.setComplexDouble(k, complexAsin(elem_a));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
resc.setComplexDouble(i, complexAsin(elem_a));
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Inverse cosine of LargeArray.
*
* @param a input array
*
* @return acos(a)
*/
public static LargeArray acos(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return acos(a, out_type);
}
/**
* Inverse cosine of LargeArray.
*
* @param a input array
*
* @param out_type output type
*
* @return acos(a)
*/
public static LargeArray acos(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.acos(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexAcos(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexAcos(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.acos(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.acos(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.acos(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
resc.setComplexFloat(i, complexAcos(elem_a));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
resc.setComplexFloat(k, complexAcos(elem_a));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
resc.setComplexFloat(i, complexAcos(elem_a));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
resc.setComplexDouble(i, complexAcos(elem_a));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
resc.setComplexDouble(k, complexAcos(elem_a));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
resc.setComplexDouble(i, complexAcos(elem_a));
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Inverse tangent of LargeArray.
*
* @param a input array
*
* @return atan(a)
*/
public static LargeArray atan(final LargeArray a)
{
LargeArrayType out_type = a.getType().isIntegerNumericType() ? LargeArrayType.FLOAT : a.getType();
return atan(a, out_type);
}
/**
* Inverse tangent of LargeArray.
*
* @param a input array
* @param out_type output type
*
* @return atan(a)
*/
public static LargeArray atan(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric()) {
throw new IllegalArgumentException("a == null || !a.isNumeric()");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
return LargeArrayUtils.createConstant(out_type, length, FastMath.atan(a.getDouble(0)));
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
float[] elem_a = ((ComplexFloatLargeArray) a).getComplexFloat(0);
return LargeArrayUtils.createConstant(out_type, length, complexAtan(elem_a));
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
double[] elem_a = ((ComplexDoubleLargeArray) a).getComplexDouble(0);
return LargeArrayUtils.createConstant(out_type, length, complexAtan(elem_a));
} else {
throw new IllegalArgumentException("Invalid array type.");
}
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (out_type.isIntegerNumericType() || out_type.isRealNumericType()) {
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.atan(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setDouble(k, FastMath.atan(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setDouble(i, FastMath.atan(a.getDouble(i)));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_FLOAT) {
final ComplexFloatLargeArray _ac = (ComplexFloatLargeArray) a;
final ComplexFloatLargeArray resc = (ComplexFloatLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
resc.setComplexFloat(i, complexAtan(elem_a));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
float[] elem_a = _ac.getComplexFloat(k);
resc.setComplexFloat(k, complexAtan(elem_a));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
float[] elem_a = _ac.getComplexFloat(i);
resc.setComplexFloat(i, complexAtan(elem_a));
}
}
}
} else if (out_type == LargeArrayType.COMPLEX_DOUBLE) {
final ComplexDoubleLargeArray _ac = (ComplexDoubleLargeArray) a;
final ComplexDoubleLargeArray resc = (ComplexDoubleLargeArray) res;
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
resc.setComplexDouble(i, complexAtan(elem_a));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
double[] elem_a = _ac.getComplexDouble(k);
resc.setComplexDouble(k, complexAtan(elem_a));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
double[] elem_a = _ac.getComplexDouble(i);
resc.setComplexDouble(i, complexAtan(elem_a));
}
}
}
} else {
throw new IllegalArgumentException("Invalid array type.");
}
return res;
}
}
/**
* Signum of LargeArray.
*
* @param a input array
*
* @return signum(a)
*/
public static LargeArray signum(final LargeArray a)
{
LargeArrayType out_type = LargeArrayType.BYTE;
return signum(a, out_type);
}
/**
* Signum of LargeArray.
*
* @param a input array
*
* @param out_type output type
*
* @return signum(a)
*/
public static LargeArray signum(final LargeArray a, final LargeArrayType out_type)
{
if (a == null || !a.isNumeric() || a.getType() == LargeArrayType.COMPLEX_FLOAT || a.getType() == LargeArrayType.COMPLEX_DOUBLE) {
throw new IllegalArgumentException("a == null || !a.isNumeric() || a.getType() == LargeArrayType.COMPLEX_FLOAT || a.getType() == LargeArrayType.COMPLEX_DOUBLE");
}
if (!out_type.isNumericType()) throw new IllegalArgumentException("Output type must be numeric.");
final LargeArray res;
long length = a.length();
if (a.isConstant()) {
return LargeArrayUtils.createConstant(out_type, length, (byte) FastMath.signum(a.getDouble(0)));
} else {
res = LargeArrayUtils.create(out_type, length, false);
int nthreads = (int) FastMath.min(length, ConcurrencyUtils.getNumberOfThreads());
if (nthreads < 2 || length < ConcurrencyUtils.getConcurrentThreshold()) {
for (long i = 0; i < length; i++) {
res.setByte(i, (byte) FastMath.signum(a.getDouble(i)));
}
} else {
long k = length / nthreads;
Future[] threads = new Future[nthreads];
for (int j = 0; j < nthreads; j++) {
final long firstIdx = j * k;
final long lastIdx = (j == nthreads - 1) ? length : firstIdx + k;
threads[j] = ConcurrencyUtils.submit(new Runnable()
{
@Override
public void run()
{
for (long k = firstIdx; k < lastIdx; k++) {
res.setByte(k, (byte) FastMath.signum(a.getDouble(k)));
}
}
});
}
try {
ConcurrencyUtils.waitForCompletion(threads);
} catch (InterruptedException | ExecutionException ex) {
for (long i = 0; i < length; i++) {
res.setByte(i, (byte) FastMath.signum(a.getDouble(i)));
}
}
}
return res;
}
}
}