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

mikera.arrayz.Arrayz 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;

import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

import mikera.arrayz.impl.SliceArray;
import mikera.arrayz.impl.ZeroArray;
import mikera.matrixx.Matrix;
import mikera.matrixx.Matrixx;
import mikera.matrixx.impl.StridedMatrix;
import mikera.matrixx.impl.ZeroMatrix;
import mikera.vectorz.AScalar;
import mikera.vectorz.AVector;
import mikera.vectorz.Scalar;
import mikera.vectorz.Vector;
import mikera.vectorz.Vectorz;
import mikera.vectorz.impl.ArrayIndexScalar;
import mikera.vectorz.impl.ArraySubVector;
import mikera.vectorz.impl.ImmutableScalar;
import mikera.vectorz.impl.SparseIndexedVector;
import mikera.vectorz.impl.Vector0;
import mikera.vectorz.impl.ZeroVector;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.IntArrays;
import mikera.vectorz.util.VectorzException;
import us.bpsm.edn.parser.Parseable;
import us.bpsm.edn.parser.Parser;
import us.bpsm.edn.parser.Parsers;

/**
 * Static function class for array operations
 * 
 * @author Mike
 */
public class Arrayz {

	private Arrayz(){}

	/**
	 * Creates an array from the given data. Makes a copy of underlying data as necessary.
	 * 
	 * Handles double arrays, Java arrays, INDArray instances, and lists
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static INDArray create(Object object) {
		if (object instanceof INDArray) return create((INDArray)object);
		
		if (object instanceof double[]) return Vector.of((double[])object);
		if (object instanceof List) {
			List list=(List) object;
			int n=list.size();
			if (n==0) return Vector0.INSTANCE;
			Object o1=list.get(0);
			if ((o1 instanceof AScalar)||(o1 instanceof Number)) {
				return Vectorz.create((List)object);
			} else if (o1 instanceof AVector) {
				return Matrixx.create((List)object);
			} else if (o1 instanceof INDArray) {
				return SliceArray.create((List)object);				
			} else {
				ArrayList al=new ArrayList(n);
				for (Object o: list) {
					al.add(create(o));
				}
				return Arrayz.create(al);
			}
		}
		
		if (object instanceof Number) return Scalar.create(((Number)object).doubleValue());
		
		if (object.getClass().isArray()) {
			return create(Arrays.asList((Object[])object));
		}
		
		throw new VectorzException("Don't know how to create array from: "+object.getClass());
	}
	
	/**
	 * Creates an array from the given List of slices.
	 * 
	 * Calls create recursively on underlying slices if needed, so that nested structures can be used
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static INDArray create(List slices) {
		int n=slices.size();
		if (n==0) return Vector0.INSTANCE;
		Object o1=slices.get(0);
		if ((o1 instanceof AScalar)||(o1 instanceof Number)) {
			return Vectorz.create((List)slices);
		} else if (o1 instanceof AVector) {
			return Matrixx.create((List)slices);
		} else {
			ArrayList al=new ArrayList(n);
			for (Object o: slices) {
				al.add(create(o));
			}
			return SliceArray.create(al);
		}
	}
	
	/**
	 * Create a new mutable array instance with the given shape. New array will be filled with zeros.
	 * 
	 * Uses the most efficient densely packed format where possible.
	 *
	 * @param shape
	 * @return
	 */
	public static INDArray newArray(int... shape) {
		int dims=shape.length;
		
		switch (dims) {
			case 0: return Scalar.create(0.0);
			case 1: return Vector.createLength(shape[0]);
			case 2: return Matrix.create(shape[0], shape[1]);
			default: return Array.newArray(shape);
		}
	}
	
	/**
	 * Create a new mutable array instance with the given source data.
	 * 
	 * Uses the most efficient densely packed format where possible.
	 * 
	 * @param shape
	 * @return
	 */
	public static INDArray create(INDArray a) {
		int dims=a.dimensionality();
		switch (dims) {
		case 0:
			return Scalar.create(a.get());
		case 1:
			return Vector.wrap(a.toDoubleArray());
		case 2:
			return Matrix.wrap(a.getShape(0), a.getShape(1), a.toDoubleArray());
		default:
			return Array.wrap(a.toDoubleArray(),a.getShape());
		}
	}
	
	/**
	 * Creates an array using the given data as slices.
	 * 
	 * @param data
	 * @return
	 */
	public static  INDArray create(T[] data) {
		return create((Object)data);
	}
	
	/**
	 * Creates an INDArray instance wrapping the given double data, with the provided shape.
	 * 
	 * @param data
	 * @param shape
	 * @return
	 */
	public static INDArray wrap(double[] data, int[] shape) {
		int dlength=data.length;
		switch (shape.length) {
			case 0:
				return ArrayIndexScalar.wrap(data,0);
				
			case 1:
				int n=shape[0];
				if (dlength=0; i--) {
			if (strides[i]!=st) return false;
			st*=shape[i];
		}
		return (st==data.length);
	}

	/**
	 * Checks if the given set of strides represents a fully packed, row major layout for the given shape
	 * @param shape
	 * @param strides
	 * @return
	 */
	public static boolean isPackedStrides(int[] shape, int[] strides) {
		int dims=shape.length;
		int st=1;
		for (int i=dims-1; i>=0; i--) {
			if (strides[i]!=st) return false;
			st*=shape[i];
		}
		return true;
	}

	/**
	 * Creates a sparse copy of the given array. May or may not be mutable.
	 * @param a
	 * @return
	 */
	public static INDArray createSparse(INDArray a) {
		int dims=a.dimensionality();
		if (dims==0) {
			return Scalar.create(a.get());
		} else if (dims==1) {
			return Vectorz.createSparse(a.asVector());
		} else if (dims==2) {
			return Matrixx.createSparse(Matrixx.toMatrix(a));
		} else {
			int n=a.sliceCount();
			List slices=a.getSliceViews();
			for (int i=0; i INDArray createSparse(T... slices) {
		int sc=slices.length;
		INDArray a0=Arrayz.createSparse(slices[0]);
		int sliceDims=a0.dimensionality();
		if (sliceDims==0) {
			return Vectorz.createSparse(slices);
		} else if (sliceDims==1) {
			return Matrixx.createSparse(slices);
		} else {
			INDArray[] arrs=new INDArray[sc];
			arrs[0]=a0;
			for (int i=1; i it=(Iterable)o;
			List target = new ArrayList();
			for (Object slice:it) {
				target.add(slice);
			}
			return createSparse(target);
		} 
		Class klass=o.getClass();
		if (klass.isArray()) {
			if (klass.getComponentType()==Object.class) return createSparse((Object[])o);
			if (klass==double[].class) return SparseIndexedVector.create((double[])o);
			int n=java.lang.reflect.Array.getLength(o);
			Object[] os=new Object[n];
			for (int i=0; i INDArray createSparse(List o) {
		return createSparse(o.toArray());
	}
	
	/**
	 * Creates a fully mutable sparse clone of the given array
	 * @param a
	 * @return
	 */
	public static INDArray createSparseMutable(INDArray a) {
		int dims=a.dimensionality();
		if (dims==0) {
			return Scalar.create(a.get());
		} else if (dims==1) {
			return Vectorz.createSparseMutable(a.asVector());
		} else if (dims==2) {
			return Matrixx.createSparse(Matrixx.toMatrix(a));
		} else {
			int n=a.sliceCount();
			List slices=a.getSliceViews();
			for (int i=0; i slices=new ArrayList(sliceCount);
		INDArray sa=createSparseArray(subshape);
		slices.add(sa);
		for (int i=1; i m=SliceArray.create(slices);
		return m;
	}

	public static void fillRandom(INDArray a, long seed) {
		Vectorz.fillRandom(a.asVector(),seed);
	}
	
	public static void fillRandom(INDArray a, Random random) {
		Vectorz.fillRandom(a.asVector(),random);
	}

	public static void fillNormal(INDArray a, long seed) {
		Vectorz.fillNormal(a.asVector(),seed);
	}
	
	public static void fillNormal(INDArray a, Random random) {
		Vectorz.fillNormal(a.asVector(),random);
	}

	/**
	 * Checks that a specified index exists along a specified dimension. Throws an exception if the index does not exist.
	 * @param array
	 * @param dimension
	 * @param index
	 * @throws IndexOutOfBoundsException if the specified index or dimension does not exist.
	 */
	public static void checkShape(INDArray array, int dimension, int index) {
		int size=array.getShape(dimension);
		if ((index<0)||(index>=size)) throw new IndexOutOfBoundsException(ErrorMessages.invalidSlice(array, dimension, index));
	}
}