package org.openlca.core.matrix; import gnu.trove.impl.Constants; import gnu.trove.map.hash.TIntObjectHashMap; import org.openlca.core.math.IMatrix; import org.openlca.core.math.IMatrixFactory; import org.openlca.expressions.FormulaInterpreter; /** * A matrix with impact assessment factors where the flows are mapped to the * columns and the impact categories are mapped to the rows. The factors should * be negative in this matrix if the corresponding flow is an input flow. */ public class ImpactFactorMatrix { private final int columns; private final int rows; private final TIntObjectHashMap<TIntObjectHashMap<ImpactFactorCell>> cells; public ImpactFactorMatrix(int rows, int columns) { this.rows = rows; this.columns = columns; cells = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, -1); } public boolean isEmpty() { return cells.isEmpty(); } public void setEntry(int row, int col, ImpactFactorCell cell) { TIntObjectHashMap<ImpactFactorCell> rowMap = cells.get(row); if (rowMap == null) { rowMap = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, -1); cells.put(row, rowMap); } rowMap.put(col, cell); } public ImpactFactorCell getEntry(int row, int col) { TIntObjectHashMap<ImpactFactorCell> rowMap = cells.get(row); if (rowMap == null) return null; return rowMap.get(col); } public <M extends IMatrix> M createRealMatrix(IMatrixFactory<M> factory) { final M matrix = factory.create(rows, columns); iterate(new Fn() { @Override public void apply(int row, int col, ImpactFactorCell cell) { matrix.set(row, col, cell.getMatrixValue()); } }); return matrix; } void eval(final FormulaInterpreter interpreter) { iterate(new Fn() { @Override public void apply(int row, int col, ImpactFactorCell cell) { cell.eval(interpreter); } }); } public void apply(final IMatrix matrix) { iterate(new Fn() { @Override public void apply(int row, int col, ImpactFactorCell cell) { matrix.set(row, col, cell.getMatrixValue()); } }); } public void simulate(final IMatrix matrix) { iterate(new Fn() { @Override public void apply(int row, int col, ImpactFactorCell cell) { matrix.set(row, col, cell.getNextSimulationValue()); } }); } private void iterate(Fn fn) { for (int row : cells.keys()) { if (row == -1) continue; TIntObjectHashMap<ImpactFactorCell> rowMap = cells.get(row); if (rowMap == null) continue; for (int col : rowMap.keys()) { if (col == -1) continue; ImpactFactorCell cell = rowMap.get(col); if (cell == null) continue; fn.apply(row, col, cell); } } } private interface Fn { void apply(int row, int col, ImpactFactorCell cell); } }