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.DenseMatrix; import org.openlca.eigen.Eigen; import org.openlca.eigen.HashMatrix; import org.openlca.eigen.HashMatrix.MatrixIterator; import org.openlca.eigen.HashMatrixFactory; import org.openlca.eigen.MatrixConverter; import org.openlca.eigen.SparseMatrixData; public class BalancedSolver implements IMatrixSolver { private DenseSolver denseSolver = new DenseSolver(); @Override public double[] solve(IMatrix a, int idx, double d) { if (a.columns() == 1) return new double[] { d / a.get(0, 0) }; // see sparseLU doc if (a instanceof DenseMatrix) return denseSolver.solve(a, idx, d); HashMatrix A = MatrixConverter.asHashMatrix(a); SparseMatrixData aData = new SparseMatrixData(A); double[] b = new double[a.rows()]; b[idx] = d; double[] x = new double[aData.rows]; Eigen.sparseLu(aData.columns, aData.numberOfEntries, aData.rowIndices, aData.columnIndices, aData.values, b, x); return x; } @Override public double[] multiply(IMatrix m, final double[] v) { if (m instanceof DenseMatrix) return denseSolver.multiply(m, v); final double[] x = new double[m.rows()]; HashMatrix a = MatrixConverter.asHashMatrix(m); a.iterate(new MatrixIterator() { @Override public void next(int row, int col, double val) { x[row] += val * v[col]; } }); return x; } @Override public IMatrix invert(IMatrix a) { return denseSolver.invert(a); } @Override public IMatrix multiply(IMatrix a, IMatrix b) { return denseSolver.multiply(a, b); } @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 HashMatrixFactory(); } }