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

mikera.matrixx.impl.SparseColumnMatrix 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.matrixx.impl;

import java.util.List;

import mikera.arrayz.ISparse;
import mikera.matrixx.AMatrix;
import mikera.matrixx.Matrix;
import mikera.matrixx.Matrixx;
import mikera.vectorz.AVector;
import mikera.vectorz.IOperator;
import mikera.vectorz.Op;
import mikera.vectorz.Op2;
import mikera.vectorz.Vector;
import mikera.vectorz.Vectorz;
import mikera.vectorz.impl.SingleElementVector;
import mikera.vectorz.impl.SparseIndexedVector;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.VectorzException;

/**
 * Matrix stored as a collection of normally sparse column vectors
 * 
 * This format is especially efficient for:
 * - transposeInnerProduct() with another matrix
 * - access via getColumn() operation
 * - transpose into SparseRowMatrix
 * 
 * @author Mike
 *
 */
public class SparseColumnMatrix extends ASparseRCMatrix implements ISparse, IFastColumns {
	private static final long serialVersionUID = -5994473197711276621L;

	private static final long SPARSE_ELEMENT_THRESHOLD = 1000L;
	
	private final AVector emptyColumn;

	protected SparseColumnMatrix(int rowCount, int columnCount) {
		this(new AVector[columnCount],rowCount,columnCount);
	}
	
	protected SparseColumnMatrix(AVector[] data, int rowCount, int columnCount) {
		super(rowCount,columnCount,data);
        if (data.length != columnCount)
            throw new IllegalArgumentException(ErrorMessages.incompatibleShapes(columnCount, data.length));
		emptyColumn=Vectorz.createZeroVector(rowCount);
	}

	protected SparseColumnMatrix(List data, int rowCount, int columnCount) {
		this(data.toArray(new AVector[0]),rowCount,columnCount);
	}

//  	protected SparseColumnMatrix(HashMap data, int rowCount, int columnCount) {
//  		super(rowCount,columnCount,data);
//  		emptyColumn=Vectorz.createZeroVector(rowCount);
//  	}

	public static SparseColumnMatrix create(int rows, int cols) {
		return new SparseColumnMatrix(rows, cols);
	}

	public static SparseColumnMatrix create(AVector[] data, int rows, int cols) {
		return new SparseColumnMatrix(data, rows, cols);
	}

	/**
	 * Create a SparseColumnMatrix wrapping a specified array of columns
	 * null may be provided after first row
	 * @param vecs
	 * @return
	 */
	public static SparseColumnMatrix create(AVector... vecs) {
		int rows=vecs[0].length();
		int cols=vecs.length;
		for (int i=1; i columns) {
		return create(columns.toArray(new AVector[columns.size()]));
	}
	
	public static SparseColumnMatrix wrap(AVector[] vecs, int rows, int cols) {
		return create(vecs, rows, cols);
	}
	
	public static SparseColumnMatrix wrap(AVector... vecs) {
		return create(vecs);
	}
	
	public static SparseColumnMatrix create(AMatrix source) {
		if (source instanceof SparseRowMatrix) return ((SparseRowMatrix)source).toSparseColumnMatrix();
		int cc=source.columnCount();
		int rc=source.rowCount();
		AVector[] data = new AVector[cc];
		for (int i=0; i vecs) {
		return create(vecs);
	}
	
//	public static SparseColumnMatrix wrap(HashMap cols, int rowCount, int columnCount) {
//		return new SparseColumnMatrix(cols,rowCount,columnCount);
//	}
	
	@Override
	public int componentCount() {
		return cols;
	}
	
	@Override
	public AVector getComponent(int k) {
		AVector v=data[k];
		if (v==null) return emptyColumn;
		return v;
	}

	@Override
	protected int lineLength() {
		return rows;
	}

	@Override
	public double get(int i, int j) {
		return getColumn(j).get(i);
	}

	@Override
	public void set(int i, int j, double value) {
		checkIndex(i,j);
		unsafeSet(i,j,value);
	}
	
	@Override
	public double unsafeGet(int row, int column) {
		return getColumn(column).unsafeGet(row);
	}

	@Override
	public void unsafeSet(int i, int j, double value) {
		AVector v = unsafeGetVector(j);
		if (v==null) {
			if (value == 0.0)
                return;
			v = SingleElementVector.create(value, i, rows);
		} else if (v.isFullyMutable()) {
			v.unsafeSet(i,value);
			return;
		} else {
			v = v.sparseClone();
			v.unsafeSet(i, value);
		}
		unsafeSetVec(j, v);
	}
	
	@Override
	public void set(AMatrix a) {
		checkSameShape(a);
		List scols=a.getColumns();
		for (int i=0; i bcols=b.getColumns();
		for (int i = 0; i < cc; i++) {
			getColumnView(i).applyOp(op,bcols.get(i));
		}
	}

	@Override
	public void applyOp(Op2 op, double b) {
		int cc = columnCount();
		for (int i = 0; i < cc; i++) {
			getColumnView(i).applyOp(op,b);
		}
	}
	
	@Override
	public void applyOp(IOperator op) {
		if (op instanceof Op) {applyOp((Op)op); return;}
		int cc = columnCount();
		for (int i = 0; i < cc; i++) {
			getColumnView(i).applyOp(op);
		}
	}
	
	@Override
	public void applyOp(Op op) {
		int cc = columnCount();
		for (int i = 0; i < cc; i++) {
			getColumnView(i).applyOp(op);
		}
	}
	
	@Override
	public double reduce(Op2 op, double init) {
		// override this because getting rows individually is expensive for SparseColumnMatrix
		double result=init;
		for (AVector row: getRows()) {
			result=row.reduce(op, result);
		}
		return result;
	}

    @Override
    public List getRows() {
        return getTransposeView().getColumns();
    }
    
    /**
     * Coerces this matrix into a SparseRowMatrix format.
     * @return
     */
    public SparseRowMatrix toSparseRowMatrix() {
        AVector[] rowVecs = getRows().toArray(new AVector[rows]);
        SparseRowMatrix rm = SparseRowMatrix.create(rowVecs, rows, cols);
        return rm;
    }
    
    /**
     * Ensures that a specific column is stored as a non-null, fully mutable vector.
     * @param i
     * @return
     */
	private AVector ensureMutableColumn(int i) {
		AVector v = unsafeGetVector(i);
		if (v == null) {
			AVector nv=SparseIndexedVector.createLength(rows);
            unsafeSetVec(i, nv);
			return nv;
		}
		if (v.isFullyMutable()) return v;
		AVector mv=v.mutable();
		unsafeSetVec(i, mv);
		return mv;
	}
	
	@Override
	public AVector getColumn(int j) {
		AVector v = unsafeGetVector(j);
		if (v==null) return emptyColumn;
		return v;
	}
	
	@Override
	public AVector getColumnView(int j) {
		return ensureMutableColumn(j);
	}
	
	@Override
	public boolean isLowerTriangular() {
		int cc=columnCount();
		for (int i=1; i acols=a.getColumns(); // allows SparseRowMatrix to efficiently construct column vectors
		for (int i=0; i acols=a.getColumns(); // allows SparseRowMatrix to efficiently construct column vectors
		for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy