
hu.kazocsaba.math.matrix.backbone.MatrixOp Maven / Gradle / Ivy
package hu.kazocsaba.math.matrix.backbone;
import hu.kazocsaba.math.matrix.EigenDecomposition;
import hu.kazocsaba.math.matrix.Matrix;
import hu.kazocsaba.math.matrix.Matrix2;
import hu.kazocsaba.math.matrix.Matrix3;
import hu.kazocsaba.math.matrix.MatrixCore;
import hu.kazocsaba.math.matrix.MatrixFactory;
import hu.kazocsaba.math.matrix.SingularValueDecomposition;
import hu.kazocsaba.math.matrix.SingularityException;
import hu.kazocsaba.math.matrix.SubmatrixAccessor;
import hu.kazocsaba.math.matrix.SubmatrixAccessor2;
import hu.kazocsaba.math.matrix.SubmatrixAccessor3;
import hu.kazocsaba.math.matrix.immutable.ImmutableMatrixFactory;
/**
* Implementations of the Matrix functions for the benefit of Matrix subclasses. These methods rely on the
* {@link Matrix#get(int, int)}, {@link Matrix#set(int, int, double)}, {@link Matrix#getRowCount()}, and
* {@link Matrix#getColumnCount()} functions, so all others can delegate to this class.
* @author Kazó Csaba
*/
public class MatrixOp {
MatrixOp() {}
/**
* @see Matrix#mul(Matrix)
*/
public static Matrix mul(Matrix caller, Matrix m) {
if (caller.getColumnCount() != m.getRowCount()) throw new IllegalArgumentException();
Matrix result = MatrixFactory.createMatrix(caller.getRowCount(), m.getColumnCount());
for (int row = 0; row < result.getRowCount(); row++)
for (int col = 0; col < result.getColumnCount(); col++) {
double v = 0;
for (int i = 0; i < caller.getColumnCount(); i++)
v += caller.getQuick(row, i) * m.getQuick(i, col);
result.setQuick(row, col, v);
}
return result;
}
/**
* @see Matrix#scale(double)
*/
public static void scale(Matrix caller, double c) {
for (int row = 0; row < caller.getRowCount(); row++)
for (int col = 0; col < caller.getColumnCount(); col++)
caller.setQuick(row, col, caller.getQuick(row, col)*c);
}
/**
* @see Matrix#times(double)
*/
public static Matrix times(Matrix caller, double c) {
Matrix result=MatrixFactory.createLike(caller);
for (int row = 0; row < caller.getRowCount(); row++)
for (int col = 0; col < caller.getColumnCount(); col++)
result.setQuick(row, col, caller.getQuick(row, col)*c);
return result;
}
/**
* @see Matrix#add(Matrix)
*/
public static void add(Matrix caller, Matrix m) {
if (caller.getRowCount() != m.getRowCount() || caller.getColumnCount() != m.getColumnCount())
throw new IllegalArgumentException();
for (int i=0; i= caller.getRowCount() || col2 >= caller.getColumnCount() || row2 < row1 || col2 < col1)
throw new IllegalArgumentException();
Matrix result = MatrixFactory.createMatrix(row2 - row1 + 1, col2 - col1 + 1);
for (int row = 0; row < result.getRowCount(); row++)
for (int col = 0; col < result.getColumnCount(); col++)
result.setQuick(row, col, caller.getQuick(row1 + row, col1 + col));
return result;
}
/**
* @see Matrix#getSub()
*/
public static SubmatrixAccessor getSub(Matrix caller) {
return new SubmatrixAccessorImpl(caller);
}
/**
* @see Matrix#viewSub()
*/
public static SubmatrixAccessor viewSub(Matrix caller) {
return new SubmatrixViewAccessorImpl(caller);
}
/**
* @see Matrix2#getSub()
*/
public static SubmatrixAccessor2 getSub(Matrix2 caller) {
return new SubmatrixAccessor2Impl(caller);
}
/**
* @see Matrix2#viewSub()
*/
public static SubmatrixAccessor2 viewSub(Matrix2 caller) {
return new SubmatrixViewAccessor2Impl(caller);
}
/**
* @see Matrix3#getSub()
*/
public static SubmatrixAccessor3 getSub(Matrix3 caller) {
return new SubmatrixAccessor3Impl(caller);
}
/**
* @see Matrix3#viewSub()
*/
public static SubmatrixAccessor3 viewSub(Matrix3 caller) {
return new SubmatrixViewAccessor3Impl(caller);
}
/**
* @see Matrix#setSubmatrix(Matrix,int,int)
*/
public static void setSubmatrix(Matrix caller, Matrix m, int row, int col) {
if (row<0 || col<0 || row+m.getRowCount()>caller.getRowCount() || col+m.getColumnCount()>caller.getColumnCount())
throw new IllegalArgumentException();
for (int r=0; r threshold) D.setQuick(i, i, 1 / D.getQuick(i, i));
}
return svd.getV().mul(D).mul(svd.getU().transpose());
}
/**
* @see Matrix#transpose()
*/
public static Matrix transpose(Matrix caller) {
Matrix result = MatrixFactory.createMatrix(caller.getColumnCount(), caller.getRowCount());
for (int i = 0; i < caller.getRowCount(); i++)
for (int j = 0; j < caller.getColumnCount(); j++)
result.setQuick(j, i, caller.getQuick(i, j));
return result;
}
/**
* @see Matrix#transposedView()
*/
public static Matrix transposedView(final Matrix caller) {
return MatrixFactory.create(new MatrixCore(caller.getColumnCount(), caller.getRowCount()) {
@Override
public double getQuick(int row, int col) {
return caller.getQuick(col, row);
}
@Override
public void setQuick(int row, int col, double value) {
caller.setQuick(col, row, value);
}
});
}
/**
* @see Matrix#determinant()
*/
public static double determinant(Matrix caller) {
if (caller.getRowCount()!=caller.getColumnCount()) throw new IllegalArgumentException("Matrix is not square");
switch (caller.getRowCount()) {
case 2:
return caller.getQuick(0, 0)*caller.getQuick(1, 1)-caller.getQuick(1, 0)*caller.getQuick(0, 1);
case 3:
return caller.getQuick(0, 0)*caller.getQuick(1, 1)*caller.getQuick(2, 2)+
caller.getQuick(0, 1)*caller.getQuick(1, 2)*caller.getQuick(2, 0)+
caller.getQuick(0, 2)*caller.getQuick(1, 0)*caller.getQuick(2, 1)-
caller.getQuick(0, 0)*caller.getQuick(1, 2)*caller.getQuick(2, 1)-
caller.getQuick(0, 1)*caller.getQuick(1, 0)*caller.getQuick(2, 2)-
caller.getQuick(0, 2)*caller.getQuick(1, 1)*caller.getQuick(2, 0);
default:
return new JamaLU(caller).det();
}
}
/**
* @see Matrix#svd()
*/
public static SingularValueDecomposition svd(Matrix caller) {
return new JamaSVD(caller);
}
/**
* @see Matrix#eig()
*/
public static EigenDecomposition eig(Matrix caller) {
return new JamaEIG(caller);
}
/**
* @see Matrix#norm()
*/
public static double norm(Matrix caller) {
double n = 0;
for (int i = 0; i < caller.getRowCount(); i++)
for (int j = 0; j < caller.getColumnCount(); j++)
n += caller.getQuick(i, j) * caller.getQuick(i, j);
return Math.sqrt(n);
}
/**
* @see Matrix#normalize()
*/
public static void normalize(Matrix caller) {
caller.scale(1/caller.norm());
}
/**
* @see Matrix#normalized()
*/
public static Matrix normalized(Matrix caller) {
return caller.times(1/caller.norm());
}
/**
* @see Matrix#error(Matrix)
*/
public static double error(Matrix caller, Matrix other) {
if (caller.getRowCount()!=other.getRowCount() || caller.getColumnCount()!=other.getColumnCount())
throw new IllegalArgumentException("Matrix dimensions do not match");
double error=0;
for (int row=0; row>> 32));
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy