#ifndef SPARSEMATRIX_H #define SPARSEMATRIX_H #include #include "MatrixLibrary.h" #include /** * @struct TRI_COORD * @brief Triplet SparseMatrix entry */ template struct TRI_COORD { TRI_COORD(unsigned row=0, unsigned col=0); TRI_COORD(unsigned row, unsigned col, T val, bool add_to=0); unsigned i, j; T v; bool add; }; /** * @class SparseMatrix * @brief Stores data in triplet format or CRS format */ template class SparseMatrix : public Matrix { //* SparseMatrix-Vector multiplication (S * v) friend DenseVector operator*(const SparseMatrix &A, const Vector& x); //* SparseMatrix-DenseMatrix multiplication (S * F) friend DenseMatrix operator*(const SparseMatrix &A, const Matrix& D); //* SparseMatrix-DiagonalMatrix multiplication (S * D) friend SparseMatrix operator*(const SparseMatrix &A, const DiagonalMatrix& D); //* SparseMatrix-SparseMatrix multiplication (S * S) friend SparseMatrix operator*(const SparseMatrix &A, const SparseMatrix &B); //* computes the product of a SparseMatrix tranpose with a SparseVector (M'*v). friend SparseVector operator*(const SparseMatrix &M, const SparseVector &v); //* computes the product of a SparseMatrix tranpose with a SparseVector (M'*v). friend SparseVector operator*(const SparseVector &v, const SparseMatrix &M); public: SparseMatrix(INDEX rows=0, INDEX cols=0); SparseMatrix(const SparseMatrix& c); SparseMatrix(const DenseMatrix& c); ~SparseMatrix(); //* General index by value (requires a binary search on the row) T operator()(INDEX i, INDEX j) const; //* General index by reference (requires a binary search on the row) T& operator()(INDEX i, INDEX j); //* General flat index by value operator (by nth nonzero) T operator[](INDEX i) const; //* General flat index by reference operator (by nth nonzero) T& operator[](INDEX i); //* adds a value to index i,j void set(INDEX i, INDEX j, T v); //* sets a value to index i,j void add(INDEX i, INDEX j, T v); //* return a triplet value of the ith nonzero TRIPLET get_triplet(INDEX i) const; //* full reset - completely wipes out all SparseMatrix data void reset(INDEX rows=0, INDEX cols=0, bool zero=true); //* only changes the bounds of the matrix, no deletion void resize(INDEX rows=0, INDEX cols=0, bool zero=true); //* reset - from DenseMatrix - this will be SLOW void reset(const DenseMatrix& D, double TOL=-1.0); //* copy data void copy(const T * ptr, INDEX rows=0, INDEX cols=0); void dense_copy(DenseMatrix& D) const; DenseMatrix dense_copy(void) const; //* returns true if the matrix has no nonzero elements bool empty() const; //* returns the user-specified number of rows INDEX nRows() const; //* returns the user-specified number of cols INDEX nCols() const; //* returns the number of non-zero elements INDEX size() const; //* returns the number of non-zeros in a row INDEX RowSize(INDEX r) const; //* returns a pointer to the nonzero data inline T* get_ptr() const; //* checks if the index i,j falls in the user-specified range bool in_range(INDEX i, INDEX j) const; /* * \section assignment operators */ //* copies SparseMatrix R to this SparseMatrix& operator=(const SparseMatrix &R); //* sets all nonzero values to a constant SparseMatrix& operator=(const T v); //* scales all nonzero values by a constant SparseMatrix& operator*=(const T &a); /* * \section Multiplication operations */ //* S' * F DenseMatrix transMat(const DenseMatrix &D) const; //* S' * S DenseMatrix transMat(const SparseMatrix &S) const; //* S' * v DenseVector transMat(const Vector &x) const; SparseMatrix transpose() const; SparseMatrix& row_scale(const Vector &v); SparseMatrix& col_scale(const Vector &v); DenseVector col_sum() const; DenseVector column_count() const; DiagonalMatrix get_diag() const; void get_row(INDEX i, DenseVector& row, DenseVector& indx) const; void WeightedLeastSquares(const SparseMatrix &N, const DiagonalMatrix &D); T get_row_max(INDEX row) const; T get_row_min(INDEX row) const; /* * \section I/O functions */ //* outputs this SparseMatrix to a formatted string string tostring() const; using Matrix::matlab; //* writes a command to recreate this matrix in matlab to a stream void matlab(ostream &o, const string &name="S") const; //* prints a row histogram for each row void print_row_histogram(const string &name, INDEX nbins = 10) const; //* prints a histogram of the values in a row void print_row_histogram(INDEX row, INDEX nbins) const; //! Writes the matrix to a binary file (after a compress). void binary_write(std::fstream& f) const; //! Reads a SparseMatrix from a binary file. (wipes out any original data) void binary_read(std::fstream& f); //* Dump templated type to disk; operation not safe for all types void write_restart(FILE *f) const; /* * \section Utility functions */ //* converts all triplets and merges with CRS void compress(); //* converts T to CRS static void compress(const SparseMatrix &C); //* sorts and returns the # of unique triplets INDEX CountUniqueTriplets(); private: //* creates a CRS structure void _create(INDEX size, INDEX nrows); //* clears all memory and nulls references void _delete(); //* copys all data from another SparseMatrix void _copy(const SparseMatrix &C); //* general sparse matrix assignment void _set_equal(const Matrix &r); //* returns the first row with a nonzero in it (from the CRS structure only) int _first_nonzero_row_crs() const; /* * \section CRS storage variables */ T * _val; // matrix non-zeros INDEX *_ia, *_ja; // ptrs to rows, column indexes INDEX _size, _nRowsCRS; // # of non-zeros, rows //* new (unsorted triplet values - won't intersect CRS values) mutable vector > _tri; /* * \section User specified variables */ INDEX _nRows, _nCols; static T _zero; }; #include "SparseMatrix-inl.h" #endif