mikera.arrayz.impl.AbstractArray Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vectorz Show documentation
Show all versions of vectorz Show documentation
Fast double-precision vector and matrix maths library for Java, supporting N-dimensional numeric arrays.
package mikera.arrayz.impl;
import java.nio.DoubleBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import mikera.arrayz.Array;
import mikera.arrayz.Arrayz;
import mikera.arrayz.INDArray;
import mikera.arrayz.ISparse;
import mikera.indexz.AIndex;
import mikera.indexz.Index;
import mikera.matrixx.AMatrix;
import mikera.matrixx.Matrix;
import mikera.matrixx.Matrixx;
import mikera.matrixx.impl.SparseRowMatrix;
import mikera.util.Maths;
import mikera.vectorz.AScalar;
import mikera.vectorz.AVector;
import mikera.vectorz.IOperator;
import mikera.vectorz.Op;
import mikera.vectorz.Op2;
import mikera.vectorz.Ops;
import mikera.vectorz.Scalar;
import mikera.vectorz.Tools;
import mikera.vectorz.Vector;
import mikera.vectorz.Vectorz;
import mikera.vectorz.impl.SingleDoubleIterator;
import mikera.vectorz.util.Constants;
import mikera.vectorz.util.DoubleArrays;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.IntArrays;
import mikera.vectorz.util.LongArrays;
import mikera.vectorz.util.VectorzException;
/**
* Abstract base class for INDArray implementations
*
* Contains generic implementations for most INDArray operations, enabling new INDArray implementations
* to inherit these (at least until more optimised implementations can be written).
*
* Default implementations assume dimensionality of 1 or above
*
* Most INDArray instances should ultimately inherit from AbstractArray
*
* @author Mike
* @param The type of array slices
*/
public abstract class AbstractArray implements INDArray, Iterable {
private static final long serialVersionUID = -958234961396539071L;
@Override
public abstract double get();
@Override
public abstract double get(int i);
@Override
public double get(long i) {
return get(Tools.toInt(i));
}
@Override
public abstract double get(int i, int j);
@Override
public double get(long x,long y) {
return get(Tools.toInt(x),Tools.toInt(y));
}
@Override
public double get(long[] xs) {
int n=xs.length;
int[] ixs=new int[n];
for (int i=0; i0) {
int sc = sliceCount();
for (int i = 0; i < sc; i++) {
slice(i).applyOp(op,(dims==b.dimensionality())?b.slice(i):b);
}
} else {
set(op.apply(get(),b.get()));
}
}
@Override
public void applyOp(Op2 op, double b) {
if (dimensionality()>0) {
int rc = sliceCount();
for (int i = 0; i < rc; i++) {
slice(i).applyOp(op,b);
}
} else {
set(op.apply(get(),b));
}
}
@Override
public void multiply(double d) {
if (d==1.0) return;
int n=sliceCount();
for (int i=0; i0) {
slice(s1).setElements(pos-s1*ss, values, si, l1);
si+=l1;
}
for (int i=s1+1; i0) {
slice(s2).setElements(0,values,si,l2);
}
}
@Override
public boolean isZero() {
if (dimensionality()==0) return (get()==0.0);
int sc=sliceCount();
for (int i=0; i sliceInnerProducts=new ArrayList(sc);
for (int i=0; i al=new ArrayList(sliceCount());
for (Object s:this) {
if (s instanceof INDArray) {
al.add(((INDArray)s).outerProduct(a));
} else {
double x=Tools.toDouble(s);
INDArray sa=a.clone();
sa.scale(x);
al.add(sa);
}
}
return Arrayz.create(al);
}
@Override
public INDArray getTranspose() {
return getTransposeCopy();
}
@Override
public INDArray getTransposeView() {
throw new UnsupportedOperationException();
}
@Override
public INDArray getTransposeCopy() {
Array nd=Array.create(this);
return nd.getTransposeView();
}
@Override
public final void scale(double d) {
multiply(d);
}
@Override
public void scaleAdd(double factor, double constant) {
if (factor==0.0) {
set(constant);
} else {
if (factor!=1.0) multiply(factor);
if (constant!=0.0) add(constant);
}
}
@Override
public void scaleAdd(double factor, INDArray b, double bfactor, double constant) {
scaleAdd(factor,constant);
addMultiple(b,bfactor);
}
@Override
public void addMultiple(INDArray src, double factor) {
if (factor==0.0) return;
if (factor==1.0) {
add(src);
} else {
add(src.multiplyCopy(factor));
}
}
@Override
public void addMultipleSparse(INDArray src, double factor) {
INDArray res=src.multiplyCopy(factor);
res=res.mutable();
res.add(this);
setSparse(res);
}
@Override
public void addPower(INDArray src, double exponent) {
INDArray tmp=src.clone();
tmp.pow(exponent);
add(tmp);
}
@Override
public void addPower(INDArray src, double exponent, double factor) {
INDArray tmp=src.clone();
tmp.pow(exponent);
addMultiple(tmp,factor);
}
@Override
public void addInnerProduct(INDArray a, INDArray b) {
if (a.dimensionality()==0) {
addMultiple(b,a.get());
} else if (a instanceof AMatrix) {
addInnerProduct((AMatrix) a,b);
} else if (a instanceof AVector) {
addInnerProduct((AVector) a,b);
} else {
add(a.innerProduct(b));
}
}
@Override
public void addInnerProduct(INDArray a, INDArray b, double d) {
if (a.elementCount()adims){
INDArray sl=slice(0);
int sc=sliceCount();
sl.setApplyOp(op, a);
for (int i=1; i) {
int i=0;
for (Object ob: ((Iterable>)o)) {
slice(i).set(ob);
}
return;
}
if (o instanceof double[]) {
setElements((double[])o);
return;
}
throw new UnsupportedOperationException("Can't set to value for "+o.getClass().toString());
}
@Override
public void setElements(double... values) {
int vl=values.length;
if (vl!=elementCount()) throw new IllegalArgumentException("Wrong array length: "+vl);
setElements(0,values,0,vl);
}
@Override
public void square() {
applyOp(Ops.SQUARE);
}
@Override
public INDArray squareCopy() {
INDArray r=clone();
r.square();
return r;
}
@Override
public INDArray absCopy() {
INDArray r=clone();
r.abs();
return r;
}
@Override
public INDArray reciprocalCopy() {
INDArray r=clone();
r.reciprocal();
return r;
}
@Override
public INDArray signumCopy() {
INDArray r=clone();
r.signum();
return r;
}
@Override
public Iterator iterator() {
return new SliceIterator(this);
}
@Override
public Iterator elementIterator() {
if (dimensionality()==0) {
return new SingleDoubleIterator(get());
} else {
return new SliceElementIterator(this);
}
}
@Override
public boolean equals(Object o) {
if (!(o instanceof INDArray)) return false;
return equals((INDArray)o);
}
@Override
public boolean equalsArray(double[] data) {
if (data.length!=elementCount()) return false;
return equalsArray(data,0);
}
@Override
public int hashCode() {
return asVector().hashCode();
}
@Override
public String toString() {
if (elementCount()>Constants.PRINT_THRESHOLD) {
Index shape=Index.create(getShape());
return "Large array with shape: "+shape.toString();
}
return toStringFull();
}
public String toStringFull() {
if (dimensionality()==0) {
return Double.toString(get());
}
StringBuilder sb=new StringBuilder();
int length=sliceCount();
sb.append('[');
if (length>0) {
sb.append(slice(0).toString());
for (int i = 1; i < length; i++) {
sb.append(',');
sb.append(slice(i).toString());
}
}
sb.append(']');
return sb.toString();
}
@Override
public INDArray clone() {
return Arrayz.create(this);
}
@Override
public INDArray copy() {
if (!isMutable()) return this;
return clone();
}
@Override
public INDArray scaleCopy(double d) {
INDArray r=clone();
r.scale(d);
return r;
}
@Override
public INDArray negateCopy() {
INDArray r=clone();
r.negate();
return r;
}
@Override
public boolean equals(INDArray a) {
int dims=dimensionality();
if (a.dimensionality()!=dims) return false;
if (dims==0) {
return Tools.equals(get(),a.get());
} else if (dims==1) {
return equals(a.asVector());
} else {
int sc=sliceCount();
if (a.sliceCount()!=sc) return false;
for (int i=0; iresult) result=v;
}
return result;
}
@Override
public boolean elementsEqual(double value) {
if (dimensionality()==0) {
return get()==value;
}
int n=sliceCount();
for (int i=0; i=dims)) throw new IndexOutOfBoundsException(ErrorMessages.invalidDimension(this, dim));
ArrayList newSlices=new ArrayList(n);
for (int si : order) {
newSlices.add(slice(dim,si));
}
int[] shp=this.getShapeClone();
shp[dim]=n;
if (dims==2) {
if (dim==0) {
return SparseRowMatrix.create(newSlices, shp[0], shp[1]);
}
}
if (dim==0) {
return SliceArray.create(newSlices,shp);
} else {
Array a=Array.newArray(shp);
for (int di=0; di getSlices(int dimension) {
int l=getShape(dimension);
ArrayList al=new ArrayList(l);
for (int i=0; i getSlices() {
int n=sliceCount();
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy