package mikera.vectorz.util;
import mikera.vectorz.Tools;
import mikera.vectorz.ops.Logistic;
public final class DoubleArrays {
public static final double[] EMPTY = new double[0];
public static final double elementSum(double[] data) {
double result = 0.0;
for (int i=0; i<data.length; i++) {
result+=data[i];
}
return result;
}
public static final double elementSum(double[] data, int offset, int length) {
double result = 0.0;
for (int i=0; i<length; i++) {
result+=data[offset+i];
}
return result;
}
public static final double elementProduct(double[] data, int offset, int length) {
double result = 1.0;
for (int i=0; i<length; i++) {
result*=data[offset+i];
}
return result;
}
public static final double elementMin(double[] data, int offset, int length) {
double result = Double.MAX_VALUE;
for (int i=0; i<length; i++) {
double v=data[offset+i];
if (v<result) result=v;
}
return result;
}
public static final double elementMax(double[] data, int offset, int length) {
double result = -Double.MAX_VALUE;
for (int i=0; i<length; i++) {
double v=data[offset+i];
if (v>result) result=v;
}
return result;
}
public static double elementMaxAbs(double[] data, int offset, int length) {
double result = 0.0;
for (int i=0; i<length; i++) {
double v=Math.abs(data[offset+i]);
if (v>result) {
result=v;
}
}
return result;
}
public static final double elementMin(double[] data) {
return elementMin(data,0,data.length);
}
public static final double elementMax(double[] data) {
return elementMax(data,0,data.length);
}
public static final double elementMaxAbs(double[] data) {
return elementMaxAbs(data,0,data.length);
}
public static int elementMaxIndex(double[] data, int offset, int length) {
if (length==0) throw new IllegalArgumentException("Can't get max index for length 0 array");
double result = data[offset];
int ind=0;
for (int i=1; i<length; i++) {
double v=data[offset+i];
if (v>result) {
ind=i;
result=v;
}
}
return ind;
}
public static int elementMinIndex(double[] data, int offset, int length) {
if (length==0) throw new IllegalArgumentException("Can't get min index for length 0 array");
double result = data[offset];
int ind=0;
for (int i=1; i<length; i++) {
double v=data[offset+i];
if (v<result) {
ind=i;
result=v;
}
}
return ind;
}
public static int elementMaxAbsIndex(double[] data, int offset, int length) {
if (length==0) throw new IllegalArgumentException("Can't get max abs index for length 0 array");
double result = Math.abs(data[offset]);
int ind=0;
for (int i=1; i<length; i++) {
double v=Math.abs(data[offset+i]);
if (v>result) {
ind=i;
result=v;
}
}
return ind;
}
public static double elementSquaredSum(double[] data) {
double result = 0.0;
for (int i=0; i<data.length; i++) {
double x=data[i];
result+=x*x;
}
return result;
}
public static double elementSquaredSum(double[] data, int offset, int length) {
double result = 0.0;
for (int i=0; i<length; i++) {
double x=data[offset+i];
result+=x*x;
}
return result;
}
public static double elementPowSum(double[] data, int offset,
int length, double exponent) {
double result = 0.0;
for (int i=0; i<length; i++) {
double x=data[offset+i];
result+=Math.pow(x, exponent);
}
return result;
}
public static double elementAbsPowSum(double[] data, int offset,
int length, double exponent) {
double result = 0.0;
for (int i=0; i<length; i++) {
double x=Math.abs(data[offset+i]);
result+=Math.pow(x, exponent);
}
return result;
}
public static int nonZeroCount(double[] data) {
int result = 0;
for (int i=0; i<data.length; i++) {
if (data[i]!=0.0) result++;
}
return result;
}
public static int nonZeroCount(double[] data, int offset, int length) {
int result = 0;
for (int i=0; i<length; i++) {
if (data[offset+i]==0.0) continue;
result++;
}
return result;
}
public static void multiply(double[] data, int offset, int length, double value) {
for (int i=0; i<length; i++) {
data[offset+i]*=value;
}
}
public static void multiply(double[] data, double value) {
for (int i=0; i<data.length; i++) {
data[i]*=value;
}
}
public static void multiply(double[] dest, double[] src) {
for (int i=0; i<dest.length; i++) {
dest[i]*=src[i];
}
}
public static void square(double[] ds) {
for (int i=0; i<ds.length; i++) {
ds[i]*=ds[i];
}
}
public static void square(double[] ds, int offset, int length) {
for (int i=0; i<length; i++) {
ds[offset+i]*=ds[offset+i];
}
}
public static void tanh(double[] ds) {
for (int i=0; i<ds.length; i++) {
ds[i]=Math.tanh(ds[i]);
}
}
public static void tanh(double[] ds, int offset, int length) {
for (int i=0; i<length; i++) {
ds[offset+i]=Math.tanh(ds[offset+i]);
}
}
public static void logistic(double[] ds) {
for (int i=0; i<ds.length; i++) {
ds[i]=Logistic.logisticFunction(ds[i]);
}
}
public static void logistic(double[] ds, int offset, int length) {
for (int i=0; i<length; i++) {
ds[offset+i]=Logistic.logisticFunction(ds[offset+i]);
}
}
public static void signum(double[] ds) {
for (int i=0; i<ds.length; i++) {
ds[i]=Math.signum(ds[i]);
}
}
public static void signum(double[] ds, int offset, int length) {
for (int i=0; i<length; i++) {
ds[offset+i]=Math.signum(ds[offset+i]);
}
}
public static void divide(double[] data, int offset, int length, double value) {
for (int i=0; i<length; i++) {
data[offset+i]/=value;
}
}
public static void add(double[] data, int offset, int length, double value) {
for (int i=0; i<length; i++) {
data[offset+i]+=value;
}
}
public static void add(double[] data, double value) {
for (int i=0; i<data.length; i++) {
data[i]+=value;
}
}
public static void addMultiple(double[] dest, int offset, double[] src, int srcOffset, int length, double factor) {
for (int i=0; i<length; i++) {
dest[offset+i]+=factor*src[srcOffset+i];
}
}
public static void addProduct(double[] dest, int offset, double[] src1, int src1Offset, double[] src2, int src2Offset, int length, double factor) {
for (int i=0; i<length; i++) {
dest[offset+i]+=factor*src1[src1Offset+i]*src2[src2Offset+i];
}
}
public static void sub(double[] data, double value) {
for (int i=0; i<data.length; i++) {
data[i]-=value;
}
}
public static void sub(double[] data, int offset, int length, double value) {
for (int i=0; i<length; i++) {
data[offset+i]-=value;
}
}
public static void arraymultiply(double[] src, int srcOffset, double[] dest, int destOffset, int length) {
for (int i=0; i<length; i++) {
dest[destOffset+i]*=src[srcOffset+i];
}
}
public static void arraydivide(double[] src, int srcOffset, double[] dest, int destOffset, int length) {
for (int i=0; i<length; i++) {
dest[destOffset+i]/=src[srcOffset+i];
}
}
public static double dotProduct(double[] a, int aOffset, double[] b, int bOffset, int length) {
double result=0.0;
for (int i=0; i<length; i++) {
double bval=b[bOffset+i];
result+=a[aOffset+i]*bval;
}
return result;
}
public static void add(double[] src, int srcOffset, double[] dest, int destOffset, int length) {
for (int i=0; i<length; i++) {
dest[destOffset+i]+=src[srcOffset+i];
}
}
public static void clamp(double[] data, double min,double max) {
for (int i=0; i<data.length; i++) {
double v=data[i];
if (v<min) {
data[i]=min;
} else if (v>max) {
data[i]=max;
}
}
}
public static void clamp(double[] data, int offset, int length, double min,double max) {
for (int i=0; i<length; i++) {
double v=data[offset+i];
if (v<min) {
data[offset+i]=min;
} else if (v>max) {
data[offset+i]=max;
}
}
}
public static void pow(double[] data, double exponent) {
for (int i=0; i<data.length; i++) {
data[i]=Math.pow(data[i],exponent);
}
}
public static void pow(double[] data, int offset, int length, double exponent) {
for (int i=0; i<length; i++) {
data[i+offset]=Math.pow(data[i+offset],exponent);
}
}
public static void reciprocal(double[] data) {
for (int i=0; i<data.length; i++) {
data[i]=1.0/data[i];
}
}
public static void reciprocal(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
data[i+offset]=1.0/data[i+offset];
}
}
public static void scaleAdd(double[] data,double factor, double constant) {
for (int i=0; i<data.length; i++) {
data[i]=(factor*data[i])+constant;
}
}
public static void scaleAdd(double[] data, int offset, int length,
double factor, double constant) {
for (int i=0; i<length; i++) {
data[i+offset]=(factor*data[i+offset])+constant;
}
}
public static void abs(double[] data) {
for (int i=0; i<data.length; i++) {
double val=data[i];
if (val<0) data[i]=-val;
}
}
public static void abs(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
double val=data[i+offset];
if (val<0) data[i+offset]=-val;
}
}
public static void exp(double[] data) {
for (int i=0; i<data.length; i++) {
double val=data[i];
data[i]=Math.exp(val);
}
}
public static void exp(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
double val=data[i+offset];
data[i+offset]=Math.exp(val);
}
}
public static void log(double[] data) {
for (int i=0; i<data.length; i++) {
double val=data[i];
data[i]=Math.log(val);
}
}
public static void log(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
double val=data[i+offset];
data[i+offset]=Math.log(val);
}
}
public static void sqrt(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
double val=data[i+offset];
data[i+offset]=Math.sqrt(val);
}
}
public static void negate(double[] data) {
for (int i=0; i<data.length; i++) {
double val=data[i];
data[i]=-val;
}
}
public static void negate(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
double val=data[i+offset];
data[i+offset]=-val;
}
}
public static boolean equals(double[] as, double[] bs) {
if (as==bs) return true;
int n=as.length;
if (n!=bs.length) return false;
for (int i=0; i<n; i++) {
if (as[i]!=bs[i]) return false;
}
return true;
}
public static boolean equals(double[] as, double[] bs, int length) {
if (as==bs) return true;
int n=length;
for (int i=0; i<n; i++) {
if (as[i]!=bs[i]) return false;
}
return true;
}
public static void add(double[] dest, double[] src) {
int n=src.length;
for (int i=0; i<n; i++) {
dest[i]+=src[i];
}
}
public static boolean equals(double[] as, int aOffset, double[] bs, int bOffset, int length) {
if ((as==bs)&&(aOffset==bOffset)) return true;
for (int i=0; i<length; i++) {
if (as[i+aOffset]!=bs[i+bOffset]) return false;
}
return true;
}
public static boolean isBoolean(double[] data) {
for (int i=0; i<data.length; i++) {
if (!Tools.isBoolean(data[i])) return false;
}
return true;
}
public static boolean isBoolean(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
if (!Tools.isBoolean(data[offset+i])) return false;
}
return true;
}
public static boolean isZero(double[] data) {
for (int i=0; i<data.length; i++) {
if (data[i]!=0) return false;
}
return true;
}
public static boolean isZero(double[] data, int offset, int length) {
for (int i=0; i<length; i++) {
if (data[offset+i]!=0.0) return false;
}
return true;
}
public static boolean isZero(double[] data, int offset, int length, int stride) {
for (int i=0; i<length; i++) {
if (data[offset]!=0.0) return false;
offset+=stride;
}
return true;
}
public static boolean elementsEqual(double[] data, int offset, int length,
double value) {
for (int i=0; i<length; i++) {
if (data[offset+i]!=value) return false;
}
return true;
}
public static double[] insert(double[] data, int position, double value) {
int len=data.length;
double[] nas=new double[len+1];
System.arraycopy(data, 0, nas, 0, position);
nas[position]=value;
System.arraycopy(data, position, nas, position+1, len-position);
return nas;
}
/**
* Fast double array copy operation.
*
* Appears to be faster than data.clone()
* ?? this is debatable, needs more rigorous benchmarking
*
* @param data
* @return
*/
public static final double[] copyOf(double[] data) {
return data.clone();
//return Arrays.copyOf(data, data.length);
}
public static double[] copyOf(double[] data, int start, int length) {
double[] rs=new double[length];
System.arraycopy(data, start, rs, 0, length);
return rs;
}
public static int[] nonZeroIndices(double[] data, int offset, int length) {
int n=DoubleArrays.nonZeroCount(data, offset, length);
int[] rs=new int[n];
int di=0;
for (int i=0; i<length; i++) {
if (data[offset+i]!=0.0) rs[di++]=i;
}
return rs;
}
public static void add2(double[] dest, double[] aData, double[] bData) {
int len=dest.length;
for (int i=0; i<len; i++) {
dest[i]+=aData[i]+bData[i];
}
}
/**
* Simultaneously adds two arrays to a target array
*/
public static void add2(double[] dest, int destOffset, double[] aData, int aOffset, double[] bData, int bOffset, int len) {
for (int i=0; i<len; i++) {
dest[i+destOffset]+=aData[i+aOffset]+bData[i+bOffset];
}
}
public static void addMultiple(double[] dest, double[] src, double factor) {
int len=dest.length;
for (int i=0; i<len; i++) {
dest[i]+=src[i]*factor;
}
}
/**
* Performs addition of two double arrays and stores the result in the desination array
*/
public static void addResult(double[] dest, double[] as, double[] bs) {
int len=dest.length;
for (int i=0; i<len; i++) {
dest[i]=as[i]+bs[i];
}
}
public static void scaleCopy(double[] dest, double[] src, double factor) {
int len=dest.length;
for (int i=0; i<len; i++) {
dest[i]=src[i]*factor;
}
}
}