package org.openlca.core.math; import gnu.trove.impl.Constants; import gnu.trove.map.hash.TIntIntHashMap; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Sorts a *quadratic* matrix (the technology matrix in openLCA) so that rows * with more entries are located at the bottom of the matrix. */ public class MatrixRowSorter { private IMatrixFactory<?> factory; private IMatrix original; private TIntIntHashMap indexMap; public MatrixRowSorter(IMatrix original, IMatrixFactory<?> factory) { this.original = original; this.factory = factory; } public IMatrix run() { List<Row> rows = collectRows(); buildIndexMap(rows); IMatrix swapped = createSwappedMatrix(); return swapped; } private List<Row> collectRows() { List<Row> rows = new ArrayList<>(); for (int rowIdx = 0; rowIdx < original.rows(); rowIdx++) { Row row = new Row(); row.idx = rowIdx; rows.add(row); for (int col = 0; col < original.columns(); col++) { double val = original.get(rowIdx, col); if (val != 0) row.entries++; } } return rows; } private void buildIndexMap(List<Row> rows) { Collections.sort(rows); indexMap = new TIntIntHashMap(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, -1, -1); for (int i = 0; i < rows.size(); i++) { Row row = rows.get(i); indexMap.put(row.idx, i); } } private IMatrix createSwappedMatrix() { IMatrix swapped = factory.create(original.rows(), original.rows()); for (int r = 0; r < original.rows(); r++) { for (int c = 0; c < original.columns(); c++) { double val = original.get(r, c); if (val == 0) continue; int newRow = indexMap.get(r); int newCol = indexMap.get(c); swapped.set(newRow, newCol, val); } } return swapped; } private class Row implements Comparable<Row> { int idx = -1; int entries = 0; @Override public int compareTo(Row o) { int c = this.entries - o.entries; if (c != 0) return c; else return this.idx - o.idx; } } }