All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mikera.arrayz.impl.SliceArray Maven / Gradle / Ivy

Go to download

Fast double-precision vector and matrix maths library for Java, supporting N-dimensional numeric arrays.

There is a newer version: 0.67.0
Show newest version
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 al=new ArrayList(n);
		if (dimensionality()==1) {
			for (int i=0; i