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

mikera.matrixx.impl.ASparseRCMatrix 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 mikera.matrixx.AMatrix;
import mikera.matrixx.Matrix;
import mikera.vectorz.AVector;
import mikera.vectorz.Op;
import mikera.vectorz.Vector;
import mikera.vectorz.Vectorz;
import mikera.vectorz.impl.RepeatedElementVector;
import mikera.vectorz.util.DoubleArrays;
import mikera.vectorz.util.VectorzException;

/**
 * Abstract base class for matrices that store sparse rows or columns.
 * 
 * @author Mike
 *
 */
public abstract class ASparseRCMatrix extends ARectangularMatrix {
	private static final long serialVersionUID = -4153075712517555814L;

	protected final AVector[] data;

	protected ASparseRCMatrix(int rows, int cols, AVector[] data) {
		super(rows, cols);
		this.data=data;
	}
	
    protected void unsafeSetVec(int i, AVector vec) {
        data[i] = vec;
    }

    /**
     * Gets a vector from the internal data array
     * 
     * The vector may be null (indicating a zero row or column)
     * 
     */
    public AVector unsafeGetVector(int i) {
        return data[i];
    }

	@Override
	public boolean isSparse() {
		return true;
	}
	
	@Override
	public void fill(double value) {
		RepeatedElementVector v=RepeatedElementVector.create(lineLength(), value);
		long n=componentCount();
		for (int i = 0; i < n; i++) {
			unsafeSetVec(i, v);
		}
	}
	
	@Override
	public void reciprocal() {
		AVector rr=RepeatedElementVector.create(lineLength(), 1.0/0.0);
		long n=componentCount();
		for (int i=0; iresult) result=v;
		}
		return result;
	}	
	
	@Override
	public void applyOp(Op op) {
		boolean stoch = op.isStochastic();
		AVector rr = (stoch) ? null : Vectorz.createRepeatedElement(lineLength(), op.apply(0.0));

		long n=componentCount();
		for (int i = 0; i < n; i++) {
			AVector v = unsafeGetVector(i);
			if (v == null) {
				if (!stoch) {
					unsafeSetVec(i, rr);
					continue;
				}
				v = Vector.createLength(lineLength());
				unsafeSetVec(i, v);
			} else if (!v.isFullyMutable()) {
				v = v.sparseClone();
				unsafeSetVec(i, v);
			}
			v.applyOp(op);
		}
	}
	
	@Override
	public final long nonZeroCount() {
		long result=0;
		for (AVector vec: data) {
			if (vec != null) result+=vec.nonZeroCount();
		}
		return result;
	}	
	
	@Override
	public double[] toDoubleArray() {
		double[] result=DoubleArrays.createStorage(rowCount(),columnCount());
		// since this array is sparse, fastest to use addToArray to modify only non-zero elements
		addToArray(result,0);
		return result;
	}
	
	@Override
	public Matrix dense() {
		return toMatrix();
	}
	
	@Override
	public AMatrix sparse() {
		return this;
	}
	
	@Override
	public abstract int componentCount();
	
	@Override
	public abstract AVector getComponent(int k);

	protected abstract int lineLength();

	@Override
	public void validate() {
		super.validate();
        int dlen = data.length;
		if (dlen != componentCount()) throw new VectorzException("Too many rows");
		for (int i = 0; i < dlen; ++i) {
            AVector vec = unsafeGetVector(i);
			int vlen = (vec == null) ? lineLength() : vec.length();
			if (vlen!=lineLength()) throw new VectorzException("Wrong length data line vector, length "+vlen+" at position: "+i);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy