SparseMat SparseMat::operator*(const SparseMat &right) const { if(!consolidated() || !right.consolidated()) throw ErrProgrammingError("Attempt to multiply unconsolidated SparseMats!", __FILE__, __LINE__); SparseMat result(nrows(), right.ncols()); const SparseMat rightt = right.transpose(); for(unsigned int i=0; i<nrows(); i++) { for(unsigned int j=0; j<rightt.nrows(); j++) { const_row_iterator ai = begin(i); const_row_iterator bj = rightt.begin(j); while(ai < end(i) && bj < rightt.end(j)) { if(ai.col() == bj.col()) { result.insert(i, j, (*ai)*(*bj)); ++ai; ++bj; } else if(ai.col() < bj.col()) ++ai; else ++bj; } } result.consolidate_row(i); } // result.consolidate(); result.consolidated_ = true; return result; }
SparseMatRowIterator::SparseMatRowIterator(SparseMat& mat, unsigned int row) : mat(mat), row_(row) { if(row >= mat.nrows()) throw ErrProgrammingError("SparseMatRowIterator row index out of range", __FILE__, __LINE__); coliter = mat.data[row].begin(); // iterates over the row }
void SparseMat::tile(unsigned int i, unsigned int j, const SparseMat &other) { // Add other to this, offset by i rows and j columns. assert(i + other.nrows() <= nrows()); assert(j + other.ncols() <= ncols()); for(SparseMat::const_iterator kl = other.begin(); kl<other.end(); ++kl) { unsigned int ii = kl.row() + i; unsigned int jj = kl.col() + j; assert(0 <= ii && ii < nrows_); assert(0 <= jj && jj < ncols_); insert(ii, jj, *kl); } }
void mmadump(const std::string &filename, const std::string &mtxname, const SparseMat &m) { std::ofstream os(filename.c_str()); os << mtxname << " = Table[Table[0, {i, 1, " << m.ncols() << "}], {j, 1, " << m.nrows() << "}]" << std::endl; for(SparseMat::const_iterator ij=m.begin(); ij<m.end(); ++ij) { std::string val(to_string(*ij)); int epos = val.find("e"); if(epos >= 0) val.replace(epos, 1, "*^"); os << mtxname << "[[" << ij.row()+1 << "," << ij.col()+1 << "]] = " << val << std::endl; } os.close(); }