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

mikera.matrixx.impl.DiagonalMatrix 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.Matrixx;
import mikera.vectorz.AVector;
import mikera.vectorz.Vector;
import mikera.vectorz.impl.ADenseArrayVector;
import mikera.vectorz.util.DoubleArrays;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.VectorzException;

/**
 * Specialised diagonal matrix class, with dense double[] array storage for the leading diagonal only.
 * 
 * Not fully mutable - only the diagonal values can be changed
 * 
 * @author Mike
 */
public final class DiagonalMatrix extends ADiagonalMatrix {
	private static final long serialVersionUID = -6721785163444613243L;

	final double[] data;
	private final Vector lead;
	
	public DiagonalMatrix(int dimensions) {
		super(dimensions);
		data=new double[dimensions];
		lead=Vector.wrap(data);
	}
	
	private DiagonalMatrix(double... values) {
		super(values.length);
		data=values;
		lead=Vector.wrap(data);
	}
	
	private DiagonalMatrix(Vector values) {
		super(values.length());
		data=values.getArray();
		lead=values;
	}
	
	public static DiagonalMatrix createDimensions(int dims) {
		return new DiagonalMatrix(dims);
	}
	
	public static DiagonalMatrix create(double... values) {
		int dimensions=values.length;
		double[] data=new double[dimensions];
		System.arraycopy(values, 0, data, 0, dimensions);
		return new DiagonalMatrix(data);
	}
	
	public static DiagonalMatrix create(AVector v) {
		return wrap(v.toDoubleArray());
	}
	
	public static DiagonalMatrix create(AMatrix m) {
		if (!m.isDiagonal()) throw new IllegalArgumentException("Source is not a diagonal matrix!");
		return wrap(m.getLeadingDiagonal().toDoubleArray());
	}
	
	public static DiagonalMatrix wrap(double[] data) {
		return new DiagonalMatrix(data);
	}
	
	public static DiagonalMatrix wrap(Vector data) {
		return new DiagonalMatrix(data);
	}
	
	@Override
	public void addSparse(double c) {
		lead.addSparse(c);
	}
	
	@Override
	public void setSparse(AMatrix a) {
		checkSameShape(a);
		lead.set(a.getLeadingDiagonal());
	}
	
	@Override
	public double trace() {
		return lead.elementSum();
	}
	
	@Override
	public double diagonalProduct() {
		return lead.elementProduct();
	}
	
	@Override
	public double elementSum() {
		return lead.elementSum();
	}	
	
	@Override
	public long nonZeroCount() {
		return lead.nonZeroCount();
	}	

	@Override
	public double get(int row, int column) {
		if (row!=column) {
			checkIndex(row,column);
			return 0.0;
		}
		return data[row];
	}
	
	@Override
	public double unsafeGet(int row, int column) {
		if (row!=column) return 0.0;
		return data[row];
	}

	@Override
	public void set(int row, int column, double value) {
		if (row!=column) {
			if (value!=0.0) throw new UnsupportedOperationException(ErrorMessages.notFullyMutable(this, row, column));
		} else {
			data[row]=value;
		}
	}
	
	@Override
	public void unsafeSet(int row, int column, double value) {
		data[row]=value;
	}
	
	@Override
	public boolean isMutable() {
		return true;
	}
	
	@Override
	public boolean isFullyMutable() {
		return dimensions<=1;
	}
	
	@Override
	public void multiply(double factor) {
		lead.multiply(factor);
	}
	
	@Override
	public DiagonalMatrix multiplyCopy(double factor) {
		double[] newData=DoubleArrays.copyOf(data);
		DoubleArrays.multiply(newData, factor);
		return wrap(newData);
	}	
	
	@Override
	public double rowDotProduct(int i, AVector v) {
		return data[i]*v.unsafeGet(i);
	}
		
	@Override
	public void transform(Vector source, Vector dest) {
		int rc = rowCount();
		int cc = rc;
		if (source.length()!=cc) throw new IllegalArgumentException(ErrorMessages.wrongSourceLength(source));
		if (dest.length()!=rc) throw new IllegalArgumentException(ErrorMessages.wrongDestLength(dest));
		double[] sdata=source.getArray();
		double[] ddata=dest.getArray();
		for (int i = 0; i < rc; i++) {
			ddata[i]=sdata[i]*this.data[i];
		}
	}

	@Override
	public void transformInPlace(AVector v) {
		if (v instanceof ADenseArrayVector) {
			transformInPlace((ADenseArrayVector) v);
			return;
		}
		if (v.length()!=dimensions) throw new IllegalArgumentException("Wrong length vector: "+v.length());
		for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy