package org.openlca.eigen.solvers;
import org.openlca.core.math.IMatrix;
import org.openlca.core.math.IMatrixFactory;
import org.openlca.core.math.IMatrixSolver;
import org.openlca.eigen.Blas;
import org.openlca.eigen.DenseMatrix;
import org.openlca.eigen.DenseMatrixFactory;
import org.openlca.eigen.Lapack;
import org.openlca.eigen.MatrixConverter;
/**
* A double precision solver that uses dense matrices and calls the respective
*/
public class DenseSolver implements IMatrixSolver {
@Override
public double[] solve(IMatrix a, int idx, double d) {
DenseMatrix A = MatrixConverter.asDenseMatrix(a);
DenseMatrix lu = A.copy();
double[] b = new double[a.rows()];
b[idx] = d;
Lapack.dSolve(A.columns(), 1, lu.getData(), b);
return b;
}
@Override
public double[] multiply(IMatrix m, double[] x) {
DenseMatrix a = MatrixConverter.asDenseMatrix(m);
double[] y = new double[m.rows()];
Blas.dMVmult(m.rows(), m.columns(), a.getData(),
x, y);
return y;
}
@Override
public DenseMatrix invert(IMatrix a) {
DenseMatrix _a = MatrixConverter.asDenseMatrix(a);
DenseMatrix i = _a.copy();
Lapack.dInvert(_a.columns(), i.getData());
return i;
}
@Override
public DenseMatrix multiply(IMatrix a, IMatrix b) {
DenseMatrix _a = MatrixConverter.asDenseMatrix(a);
DenseMatrix _b = MatrixConverter.asDenseMatrix(b);
int rowsA = _a.rows();
int colsB = _b.columns();
int k = _a.columns();
DenseMatrix c = new DenseMatrix(rowsA, colsB);
if (colsB == 1)
Blas.dMVmult(rowsA, k, _a.getData(), _b.getData(), c.getData());
else
Blas.dMmult(rowsA, colsB, k, _a.getData(), _b.getData(),
c.getData());
return c;
}
@Override
public void scaleColumns(IMatrix m, double[] v) {
for (int row = 0; row < m.rows(); row++) {
for (int col = 0; col < m.columns(); col++) {
m.set(row, col, v[col] * m.get(row, col));
}
}
}
@Override
public IMatrixFactory<?> getMatrixFactory() {
return new DenseMatrixFactory();
}
}