/*
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
*
* This file is part of Jalview.
*
* Jalview is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Jalview is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jalview. If not, see
* This method is optimised for the sparse arrays which store column values * for a SparseMatrix. Note that postMultiply is not so optimised. That would * require redundantly also storing sparse arrays for the rows, which has not * been done. Currently only preMultiply is used in Jalview. */ @Override public MatrixI preMultiply(MatrixI in) { if (in.width() != rows) { throw new IllegalArgumentException("Can't pre-multiply " + this.rows + " rows by " + in.width() + " columns"); } double[][] tmp = new double[in.height()][this.cols]; long count = 0L; for (int i = 0; i < in.height(); i++) { for (int j = 0; j < this.cols; j++) { /* * result[i][j] is the vector product of * in.row[i] and this.column[j] * we only need to use non-zero values from the column */ SparseDoubleArray vals = sparseColumns[j]; boolean added = false; for (int nonZero = 0; nonZero < vals.size(); nonZero++) { int myRow = vals.keyAt(nonZero); double myValue = vals.valueAt(nonZero); tmp[i][j] += (in.getValue(i, myRow) * myValue); added = true; } if (added && tmp[i][j] != 0d) { count++; // non-zero entry in product } } } /* * heuristic rule - if product is more than 80% zero * then construct a SparseMatrix, else a Matrix */ if (count * 5 < in.height() * cols) { return new SparseMatrix(tmp); } else { return new Matrix(tmp); } } @Override protected double divideValue(int i, int j, double divisor) { if (divisor == 0d) { return getValue(i, j); } double v = sparseColumns[j].divide(i, divisor); return v; } @Override protected double addValue(int i, int j, double addend) { double v = sparseColumns[j].add(i, addend); return v; } /** * Returns the fraction of the whole matrix size that is actually modelled in * sparse arrays (normally, the non-zero values) * * @return */ public float getFillRatio() { long count = 0L; for (SparseDoubleArray col : sparseColumns) { count += col.size(); } return count / (float) (height() * width()); } }