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

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

import mikera.matrixx.AMatrix;
import mikera.matrixx.Matrix;
import mikera.vectorz.AVector;
import mikera.vectorz.Vector;
import mikera.vectorz.Vectorz;
import mikera.vectorz.impl.ADenseArrayVector;
import mikera.vectorz.impl.ASingleElementVector;
import mikera.vectorz.impl.SingleElementVector;
import mikera.vectorz.util.ErrorMessages;
import mikera.vectorz.util.VectorzException;

/**
 * Abstract base class for square diagonal matrices
 * @author Mike
 *
 */
public abstract class ADiagonalMatrix extends ASingleBandMatrix {
	private static final long serialVersionUID = -6770867175103162837L;

	protected final int dimensions;
	
	protected ADiagonalMatrix(int dimensions) {
		this.dimensions=dimensions;
	}
	
	@Override
	public int nonZeroBand() {
		return 0;
	}

	@Override
	public boolean isSquare() {
		return true;
	}
	
	@Override
	public boolean isZero() {
		return getLeadingDiagonal().isZero();
	}
	
	@Override
	public boolean isBoolean() {
		return getLeadingDiagonal().isBoolean();
	}
	
	@Override
	public boolean isSymmetric() {
		return true;
	}
	
	@Override
	public boolean isDiagonal() {
		return true;
	}
	
	@Override
	public boolean isRectangularDiagonal() {
		return true;
	}
	
	@Override
	public boolean isUpperTriangular() {
		return true;
	}
	
	@Override
	public boolean isLowerTriangular() {
		return true;
	}
	
	@Override
	public abstract boolean isMutable();
	
	@Override
	public boolean isFullyMutable() {
		return (dimensions<=1)&&(getLeadingDiagonal().isFullyMutable());
	}
	
	@Override
	protected void checkSameShape(AMatrix m) {
		int dims=dimensions;
		if((dims!=m.rowCount())||(dims!=m.columnCount())) {
			throw new IndexOutOfBoundsException(ErrorMessages.mismatch(this, m));
		}
	}
	
	@Override
	protected void checkSameShape(ARectangularMatrix m) {
		int dims=dimensions;
		if((dims!=m.rowCount())||(dims!=m.columnCount())) {
			throw new IndexOutOfBoundsException(ErrorMessages.mismatch(this, m));
		}
	}
	
	@Override
	protected final void checkIndex(int i, int j) {
		if ((i<0)||(i>=dimensions)||(j<0)||(j>=dimensions)) {
			throw new IndexOutOfBoundsException(ErrorMessages.invalidIndex(this, i,j));
		}
	}
	
	public final boolean isSameShape(ARectangularMatrix m) {
		return (dimensions==m.rows)&&(dimensions==m.cols);
	}
	
	@Override
	public final int upperBandwidthLimit() {
		return 0;
	}
	
	@Override
	public final int lowerBandwidthLimit() {
		return 0; 
	}
	
	@Override
	public AVector getBand(int band) {
		if (band==0) {
			return getLeadingDiagonal();
		} else {
			if ((band>dimensions)||(band<-dimensions)) throw new IndexOutOfBoundsException(ErrorMessages.invalidBand(this, band));
			return Vectorz.createZeroVector(bandLength(band));
		}
	}
	
	@Override
	public AVector getNonZeroBand() {
		return getLeadingDiagonal();
	}
	
	@Override
	public double determinant() {
		double det=1.0;
		for (int i=0; i1) return Math.max(0, ldv); else return ldv;
	}
	
	@Override
	public double elementMin(){
		double ldv=getLeadingDiagonal().elementMin();
		if (dimensions>1) return Math.min(0, ldv); else return ldv;
	}
	
	@Override
	public double elementSum(){
		return getLeadingDiagonal().elementSum();
	}
	
	@Override
	public double elementSquaredSum(){
		return getLeadingDiagonal().elementSquaredSum();
	}
	
	@Override
	public long nonZeroCount(){
		return getLeadingDiagonal().nonZeroCount();
	}
	
	@Override
	public void copyRowTo(int row, double[] dest, int destOffset) {
		Arrays.fill(dest, destOffset,destOffset+dimensions,0.0);
		dest[destOffset+row]=unsafeGetDiagonalValue(row);
	}
	
	@Override
	public void addToArray(double[] dest, int offset) {
		getLeadingDiagonal().addToArray(dest, offset, dimensions+1);
	}
	
	@Override
	public AMatrix addCopy(AMatrix a) {
		if (a.isDiagonal()) {
			if (a.rowCount()!=dimensions) throw new IllegalArgumentException(ErrorMessages.incompatibleShapes(this,a));
			DiagonalMatrix m=DiagonalMatrix.create(this.getLeadingDiagonal());
			a.getLeadingDiagonal().addToArray(m.data,0);
			return m;
		} else {
			return a.addCopy(this);
		}
	}
	
	@Override
	public void copyColumnTo(int col, double[] dest, int destOffset) {
		// copying rows and columns is the same!
		copyRowTo(col,dest,destOffset);
	}
	
	/**
	 * Computes the inner product of this matrix with another diagonal matrix of the same shape.
	 * 
	 * The result will be a diagnonal matrix of the same shape.
	 * @param a
	 * @return
	 */
	public AMatrix innerProduct(ADiagonalMatrix a) {
		AMatrix result=clone();
		result.getLeadingDiagonal().multiply(a.getLeadingDiagonal());
		return result;
	}
	
	@Override
	public AMatrix innerProduct(AMatrix a) {
		if (a instanceof ADiagonalMatrix) {
			return innerProduct((ADiagonalMatrix) a);
		} 
		if (!(dimensions==a.rowCount())) throw new IllegalArgumentException(ErrorMessages.incompatibleShapes(this,a));
		AMatrix m=a.clone();
		for (int i=0; i=dimensions)) throw new IndexOutOfBoundsException();
		return unsafeGet(i,i);
	}
	
	@Override
	public ASingleElementVector getRow(int row) {
		return SingleElementVector.create(getDiagonalValue(row), row, dimensions);
	}
	
	@Override
	public ASingleElementVector getColumn(int col) {
		return getRow(col);
	}
	
	public double unsafeGetDiagonalValue(int i) {
		return unsafeGet(i,i);
	}
	
	@Override
	public ADiagonalMatrix getTranspose() {
		return this;
	}
	
	@Override
	public ADiagonalMatrix getTransposeView() {
		return this;
	}
	
	@Override
	public Matrix toMatrix() {
		Matrix m=Matrix.create(dimensions, dimensions);
		for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy