mikera.matrixx.Matrixx 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.matrixx;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import mikera.arrayz.INDArray;
import mikera.indexz.Index;
import mikera.matrixx.impl.ADiagonalMatrix;
import mikera.matrixx.impl.AStridedMatrix;
import mikera.matrixx.impl.ColumnMatrix;
import mikera.matrixx.impl.DenseColumnMatrix;
import mikera.matrixx.impl.DiagonalMatrix;
import mikera.matrixx.impl.IdentityMatrix;
import mikera.matrixx.impl.ScalarMatrix;
import mikera.matrixx.impl.SparseColumnMatrix;
import mikera.matrixx.impl.SparseRowMatrix;
import mikera.matrixx.impl.StridedMatrix;
import mikera.matrixx.impl.StridedRowMatrix;
import mikera.matrixx.impl.ZeroMatrix;
import mikera.vectorz.AVector;
import mikera.vectorz.Tools;
import mikera.vectorz.Vector3;
import mikera.vectorz.Vectorz;
import mikera.vectorz.impl.SparseIndexedVector;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.VectorzException;
import us.bpsm.edn.parser.Parseable;
import us.bpsm.edn.parser.Parser;
import us.bpsm.edn.parser.Parsers;
/**
* Static method class for matrices
*
* @author Mike
*/
public class Matrixx {
private static final long SPARSE_ELEMENT_THRESHOLD = 100000;
private final static Random rand=new Random();
/**
* Creates an identity matrix
*/
public static AMatrix createIdentityMatrix(int dimensions) {
return createImmutableIdentityMatrix(dimensions);
}
/**
* Creates a sparse, immutable identity matrix. This is the most efficient format for identity matrices
*/
public static IdentityMatrix createImmutableIdentityMatrix(int dimensions) {
return IdentityMatrix.create(dimensions);
}
/**
* Creates a fully mutable identity matrix
*/
public static AMatrix createMutableIdentityMatrix(int dimensions) {
AMatrix m = newMatrix(dimensions, dimensions);
for (int i = 0; i < dimensions; i++) {
m.unsafeSet(i, i, 1.0);
}
return m;
}
/**
* Coerce an object to a matrix format, on a best effort basis.
*
* Can handle:
* - Existing matrices
*/
@SuppressWarnings("unchecked")
public static AMatrix toMatrix(Object o) {
if (o instanceof AMatrix) {
return (AMatrix) o;
} else if (o instanceof AVector) {
return ColumnMatrix.wrap((AVector) o);
} else if (o instanceof Iterable>) {
List al = Tools.toList((Iterable) o);
return createFromVectors(al);
}
throw new UnsupportedOperationException("Can't convert to matrix: "
+ o.getClass());
}
/**
* Creates a sparse matrix from the given matrix, ignoring zeros
*/
public static AMatrix createSparse(AMatrix m) {
int rc=m.rowCount();
int cc=m.columnCount();
if ((rc==0)||(cc==0)) return ZeroMatrix.create(rc, cc);
return SparseRowMatrix.create(m);
}
/**
* Creates a sparse matrix of the given size, initially zero-filled. Uses row-based storage by default
*/
public static SparseRowMatrix createSparse(int rowCount, int columnCount) {
return SparseRowMatrix.create(rowCount,columnCount);
}
/**
* Creates a sparse matrix from the given matrix, ignoring zeros. Uses row-based storage by default
*/
public static SparseRowMatrix createSparseRows(Iterable rows) {
Iterator rowIterator=rows.iterator();
return createSparseRows(rowIterator);
}
/**
* Creates a sparse matrix from the given iterator. Each vector in the iterator will be copied to
* a row in the new sparse matrix
*/
public static ArrayList createSparseArray(Iterator vecIterator) {
AVector v0=vecIterator.next();
int len = v0.length();
ArrayList vecList = new ArrayList();
vecList.add(v0);
while (vecIterator.hasNext()) {
AVector v = vecIterator.next();
if ((v == null) || (v.isZero()))
v = Vectorz.createZeroVector(len);
else
v = v.sparseClone();
vecList.add(v.sparseClone());
}
return vecList;
}
public static SparseRowMatrix createSparseRows(Iterator rowIterator) {
return SparseRowMatrix.wrap(createSparseArray(rowIterator));
}
public static SparseColumnMatrix createSparseColumns(Iterator colIterator) {
return SparseColumnMatrix.wrap(createSparseArray(colIterator));
}
/**
* Create a sparse array, given an Index of column positions and AVector of corresponding values for each row in the sparse array
* Performs a defensive copy of underlying data.
*/
public static AMatrix createSparse(int columnCount, Index[] indexes,
AVector[] weights) {
int rowCount = indexes.length;
if (rowCount != weights.length)
throw new IllegalArgumentException("Length of indexes array must match length of weights array");
SparseRowMatrix sm=SparseRowMatrix.create(rowCount, columnCount);
for (int i = 0; i < rowCount; i++) {
sm.replaceRow(i, SparseIndexedVector.wrap(columnCount, indexes[i].clone(), weights[i].toDoubleArray()));
}
return sm;
}
/**
* Creates a SparseColumnMatrix from the given matrix, ignoring zeros
*/
public static SparseColumnMatrix createSparseColumns(AMatrix m) {
int cc = m.columnCount();
AVector[] cols = new AVector[cc];
for (int i = 0; i < cc; i++) {
cols[i] = Vectorz.createSparse(m.getColumn(i));
}
return SparseColumnMatrix.wrap(cols);
}
/**
* Creates a SparseRowMatrix matrix from the given matrix, ignoring zeros
*/
public static AMatrix createSparseRows(AMatrix m) {
if (m.rowCount()==0) return ZeroMatrix.create(0, m.columnCount());
return SparseRowMatrix.create(m);
}
/**
* Creates a SparseRowMatrix matrix from the given INDArray, ignoring zeros
*/
public static SparseRowMatrix createSparseRows(INDArray a) {
if (!(a.dimensionality()==2)) throw new IllegalArgumentException(ErrorMessages.incompatibleShape(a));
int rc=a.getShape(0);
int cc=a.getShape(1);
SparseRowMatrix m=SparseRowMatrix.create(rc,cc);
for (int i=0; iSPARSE_ELEMENT_THRESHOLD) return createSparse(rows,columns);
return Matrix.create(rows, columns);
}
/**
* Creates a new matrix using the elements in the specified vector.
* Truncates or zero-pads the data as required to fill the new matrix
* @param data
* @param rows
* @param columns
* @return
*/
public static Matrix createFromVector(AVector source, int rows, int columns) {
int length=source.length();
Matrix m = Matrix.create(rows, columns);
int n=Math.min(rows*columns, length);
source.copyTo(0, m.data, 0, n);
return m;
}
/**
* Computes the inverse of a matrix. Returns null if the matrix is singular.
*
* Throws an Exception is the matrix is not square
* @param m
* @return
*/
public AMatrix createInverse(AMatrix m) {
return m.inverse();
}
/**
* Creates a zero-filled matrix with the specified number of dimensions for both rows and columns
* @param dimensions
* @return
*/
private static Matrix createSquareMatrix(int dimensions) {
return Matrix.create(dimensions, dimensions);
}
/**
* Extracts a lower triangular matrix from a matrix
*/
public static AMatrix extractLowerTriangular(AMatrix a) {
int rc=a.rowCount();
if (rc>a.columnCount()) throw new IllegalArgumentException("Too few columns in matrix");
AMatrix r=Matrixx.newMatrix(rc,rc);
for (int i=0; ia.rowCount()) throw new IllegalArgumentException("Too few rows in matrix");
AMatrix r=Matrixx.newMatrix(cc,cc);
for (int i=0; i rows) {
int rc = rows.size();
AVector firstRow = Vectorz.create(rows.get(0));
int cc = firstRow.length();
Matrix m = Matrix.create(rc, cc);
m.setRow(0, firstRow);
for (int i = 1; i < rc; i++) {
m.setRow(i, Vectorz.create(rows.get(i)));
}
return m;
}
/**
* Creates a mutable copy of a matrix
*/
public static AMatrix create(IMatrix m) {
int rows = m.rowCount();
int columns = m.columnCount();
AMatrix result = newMatrix(rows, columns);
result.set(m);
return result;
}
/**
* Fills a matrix with uniform random numbers
* @param m
*/
public static void fillRandomValues(AMatrix m) {
int rows = m.rowCount();
int columns = m.columnCount();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
m.unsafeSet(i, j, rand.nextDouble());
}
}
}
/**
* Fills a matrix with uniform random numbers, using the specified Random instance
* @param m
*/
public static void fillRandomValues(AMatrix m, Random rand) {
int rows = m.rowCount();
int columns = m.columnCount();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
m.unsafeSet(i, j, rand.nextDouble());
}
}
}
/**
* Create a matrix using as array of vectors which represent the data for each row
* @param data
* @return
*/
public static AMatrix createFromVectors(INDArray... data) {
int rc = data.length;
int cc = (rc == 0) ? 0 : data[0].sliceCount();
AMatrix m = newMatrix(rc, cc);
for (int i = 0; i < rc; i++) {
m.setRow(i, data[i].asVector());
}
return m;
}
/**
* Create a matrix using a list of vectors as the data for each row
* @param data
* @return
*/
public static AMatrix createFromVectors(List data) {
int rc = data.size();
int cc = (rc == 0) ? 0 : data.get(0).sliceCount();
AMatrix m = newMatrix(rc, cc);
for (int i = 0; i < rc; i++) {
m.setRow(i,data.get(i).asVector());
}
return m;
}
// ====================================
// Edn formatting and parsing functions
private static Parser.Config getMatrixParserConfig() {
return Parsers.defaultConfiguration();
}
/**
* Parse a matrix in edn format
*
* @param ednString
* @return
*/
public static AMatrix parse(String ednString) {
Parser p = Parsers.newParser(getMatrixParserConfig());
Parseable ps = Parsers.newParseable(ednString);
@SuppressWarnings("unchecked")
List> data = (List>) p.nextValue(ps);
int rc = data.size();
int cc = (rc == 0) ? 0 : data.get(0).size();
AMatrix m = newMatrix(rc, cc);
for (int i = 0; i < rc; i++) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy