package org.openlca.core.math; /** * Interface for linear algebra and matrix problems that we need to solve in * openLCA. We provide different implementations for these functions also in * other packages which are based on high performance libraries like Eigen and * OpenBLAS. */ public interface IMatrixSolver { /** * Solves the system of linear equations A * s = d. In openLCA this is used * to calculate the scaling factors of an inventory where the vector d has * just a single entry. * * @param a * the technology matrix A * @param d * the demand value (the entry in the vector d). * * @param idx * the index of the entry in the demand vector. * * @return the calculated scaling vector s */ double[] solve(IMatrix a, int idx, double d); /** * Calculates the inverse of the given matrix. */ IMatrix invert(IMatrix a); /** * Returns the matrix product of the given matrices. */ default IMatrix multiply(IMatrix a, IMatrix b) { if (a == null || b == null) return null; if (a.columns() != b.rows()) throw new IllegalArgumentException("a.columns != b.rows"); IMatrix r = getMatrixFactory().create(a.rows(), b.columns()); for (int row = 0; row < a.rows(); row++) { for (int col = 0; col < b.columns(); col++) { double val = 0; for (int k = 0; k < a.columns(); k++) { val += a.get(row, k) * b.get(k, col); } r.set(row, col, val); } } return r; } /** * Calculates a matrix-vector product. In openLCA we use this for example * when we calculate the inventory result: g = B * s */ default double[] multiply(IMatrix m, double[] v) { if (m == null || v == null) return null; int cols = Math.min(m.columns(), v.length); int rows = m.rows(); double[] r = new double[rows]; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { r[row] += (m.get(row, col) * v[col]); } } return r; } /** * Scales the columns of matrix m with the factors in v. This is equivalent * to m * diag(v) but can be implemented in a more efficient way. */ default 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)); } } } /** * Returns the matrix factory of this solver. */ IMatrixFactory<?> getMatrixFactory(); }