package mikera.arrayz.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mikera.arrayz.Arrayz;
import mikera.arrayz.INDArray;
import mikera.matrixx.Matrix;
import mikera.vectorz.AVector;
import mikera.vectorz.IOperator;
import mikera.vectorz.Op;
import mikera.vectorz.impl.Vector0;
import mikera.vectorz.util.DoubleArrays;
import mikera.vectorz.util.IntArrays;
import mikera.vectorz.util.VectorzException;
/**
* A general N-dimensional double array implemented as a collection of (n-1) dimensional slices
*
* Must have dimensionality 1 or above, and contain at least one slice
*
* @author Mike
*
* @param
*/
public final class SliceArray extends BaseShapedArray {
private static final long serialVersionUID = -2343678749417219155L;
private final long[] longShape;
private final T[] slices;
private SliceArray(int[] shape, T[] slices) {
super(shape);
this.slices=slices;
if (slices.length==0) throw new IllegalArgumentException("Can't create SliceArray with zero slices");
int dims=shape.length;
this.longShape=new long[dims];
for (int i=0; i SliceArray create(INDArray a) {
return new SliceArray(a.getShape(),(T[]) a.toSliceArray());
}
/**
* Create a SliceArray by wrapping a set of slices.
* @param slices
* @return
*/
@SafeVarargs
public static SliceArray of(T... slices) {
return new SliceArray(IntArrays.consArray(slices.length,slices[0].getShape()),slices.clone());
}
/**
* Create a SliceArray by repeating the same slice instance a given number of times
* @param slice
* @param n
* @return
*/
public static SliceArray repeat(INDArray slice, int n) {
ArrayList al=new ArrayList(n);
for (int i=0; i create(List slices) {
int slen=slices.size();
if (slen==0) throw new IllegalArgumentException("Can't create SliceArray with zero slices");
INDArray[] arr=new INDArray[slen];
return new SliceArray(IntArrays.consArray(slen,slices.get(0).getShape()),slices.toArray(arr));
}
public static SliceArray create(List slices, int[] shape) {
int slen=slices.size();
INDArray[] arr=new INDArray[slen];
return new SliceArray(shape,slices.toArray(arr));
}
@Override
public int dimensionality() {
return shape.length;
}
@Override
public long[] getLongShape() {
return longShape;
}
@Override
public double get(int... indexes) {
int d=indexes.length;
T slice=slices[indexes[0]];
switch (d) {
case 0: throw new VectorzException("Can't do 0D get on SliceArray!");
case 1: return slice.get();
case 2: return slice.get(indexes[1]);
case 3: return slice.get(indexes[1],indexes[2]);
default: return slice.get(Arrays.copyOfRange(indexes,1,d));
}
}
@Override
public void set(double value) {
for (T s:slices) {
s.set(value);
}
}
@Override
public void fill(double value) {
for (T s:slices) {
s.fill(value);
}
}
@Override
public void set(int[] indexes, double value) {
int d=indexes.length;
if (d==0) {
set(value);
}
T slice=slices[indexes[0]];
switch (d) {
case 0: throw new VectorzException("Can't do 0D set on SliceArray!");
case 1: slice.set(value); return;
case 2: slice.set(indexes[1],value); return;
case 3: slice.set(indexes[1],indexes[2],value); return;
default: slice.set(Arrays.copyOfRange(indexes,1,d),value); return;
}
}
@Override
public AVector asVector() {
AVector v=Vector0.INSTANCE;
for (INDArray a:slices) {
v=v.join(a.asVector());
}
return v;
}
@Override
public INDArray reshape(int... dimensions) {
return Arrayz.createFromVector(asVector(), dimensions);
}
@Override
public T slice(int majorSlice) {
return slices[majorSlice];
}
@Override
public int componentCount() {
return sliceCount();
}
@Override
public T getComponent(int k) {
return slices[k];
}
@Override
public INDArray slice(int dimension, int index) {
checkDimension(dimension);
if (dimension==0) return slice(index);
ArrayList al=new ArrayList(sliceCount());
for (INDArray s:this) {
al.add(s.slice(dimension-1,index));
}
return SliceArray.create(al);
}
@Override
public long elementCount() {
return IntArrays.arrayProduct(shape);
}
@Override
public INDArray innerProduct(INDArray a) {
int dims=dimensionality();
switch (dims) {
case 0: {
a=a.clone();
a.scale(get());
return a;
}
case 1: {
return this.toVector().innerProduct(a);
}
case 2: {
return Matrix.create(this).innerProduct(a);
}
}
int n=sliceCount();
ArrayList al=new ArrayList(n);
for (INDArray s:this) {
al.add(s.innerProduct(a));
}
return Arrayz.create(al);
}
@Override
public INDArray outerProduct(INDArray a) {
int n=sliceCount();
ArrayList al=new ArrayList(n);
for (INDArray s:this) {
al.add(s.outerProduct(a));
}
return Arrayz.create(al);
}
@Override
public boolean isMutable() {
for (INDArray a:slices) {
if (a.isMutable()) return true;
}
return false;
}
@Override
public boolean isFullyMutable() {
for (INDArray a:slices) {
if (!a.isFullyMutable()) return false;
}
return true;
}
@Override
public boolean isZero() {
for (INDArray a:slices) {
if (!a.isZero()) return false;
}
return true;
}
@Override
public boolean isBoolean() {
for (INDArray a:slices) {
if (!a.isBoolean()) return false;
}
return true;
}
@Override
public boolean isElementConstrained() {
for (INDArray a:slices) {
if (a.isElementConstrained()) return true;
}
return false;
}
@Override
public boolean isView() {
return true;
}
@Override
public void applyOp(Op op) {
for (INDArray a:slices) {
a.applyOp(op);
}
}
@Override
public void applyOp(IOperator op) {
for (INDArray a:slices) {
a.applyOp(op);
}
}
@Override
public void multiply(double d) {
for (INDArray a:slices) {
a.scale(d);
}
}
@Override
public boolean equals(INDArray a) {
if (!Arrays.equals(a.getShape(), this.getShape())) return false;
for (int i=0; i exactClone() {
T[] newSlices=slices.clone();
for (int i=0; i(shape,newSlices);
}
@Override
public List> getSlices() {
int n=sliceCount();
ArrayList
Ads help maintain this website.