Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TLIN_SPARSEMAT_H
Toshihiro Shimizu 890ddd
#define TLIN_SPARSEMAT_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tlin_basicops.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcg/tcg_hash.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tlin
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  The tlin::sparse_matrix class implements a hash-based format for storing sparse
Toshihiro Shimizu 890ddd
  matrices.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  A tlin::sparse_matrix is a tlin::matrix-compliant class that allows the user to
Toshihiro Shimizu 890ddd
  access the matrix in a purely random fashion, without sacrificing storage space or
Toshihiro Shimizu 890ddd
  efficiency. This is achieved using a single, fast, dynamic hash container that maps
Toshihiro Shimizu 890ddd
  (row, col) entries into their values, the hash function being like:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    (row, col) -> row * nCols + col;    (taken modulo nBuckets)
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  Observe that if the number of buckets of the hash map is nCols, the resulting
Toshihiro Shimizu 890ddd
  representation is similar to a CCS (Harwell-Boeing), with the difference that
Toshihiro Shimizu 890ddd
  buckets are not sorted by row.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename t=""></typename>
Toshihiro Shimizu 890ddd
class sparse_matrix
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	struct IdxFunctor {
Toshihiro Shimizu 890ddd
		int m_cols;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		IdxFunctor(int cols) : m_cols(cols) {}
Toshihiro Shimizu 890ddd
		int operator()(const std::pair<int, int=""> &key) { return key.first * m_cols + key.second; }</int,>
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	int m_rows;
Toshihiro Shimizu 890ddd
	int m_cols;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tcg::hash<std::pair<int, int="">, T, IdxFunctor> m_hash;</std::pair<int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	sparse_matrix() : m_rows(0), m_cols(0), m_hash(IdxFunctor(0)) {}
Toshihiro Shimizu 890ddd
	sparse_matrix(int rows, int cols) : m_rows(rows), m_cols(cols), m_hash(cols) {}
Toshihiro Shimizu 890ddd
	~sparse_matrix() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	sparse_matrix(const sparse_matrix &mat) : m_rows(mat.m_rows), m_cols(mat.m_cols), m_hash(mat.m_hash) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	sparse_matrix &operator=(const sparse_matrix &mat)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_rows = mat.m_rows, m_cols = mat.m_cols, m_hash = mat.m_hash;
Toshihiro Shimizu 890ddd
		return *this;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int rows() const { return m_rows; }
Toshihiro Shimizu 890ddd
	int cols() const { return m_cols; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef typename tcg::hash<std::pair<int, int="">, T, IdxFunctor> HashMap;</std::pair<int,>
Toshihiro Shimizu 890ddd
	tcg::hash<std::pair<int, int="">, T, IdxFunctor> &entries() { return m_hash; }</std::pair<int,>
Toshihiro Shimizu 890ddd
	const tcg::hash<std::pair<int, int="">, T, IdxFunctor> &entries() const { return m_hash; }</std::pair<int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//!\warning Assignments of kind: A.at(1,1) = A.at(0,0) are potentially harmful.
Toshihiro Shimizu 890ddd
	//!Use A.get(x,y) on the right side instead.
Toshihiro Shimizu 890ddd
	T &at(int row, int col) { return m_hash.touch(std::make_pair(row, col), 0); }
Toshihiro Shimizu 890ddd
	const T get(int row, int col) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		typename HashMap::const_iterator it = m_hash.find(std::make_pair(row, col));
Toshihiro Shimizu 890ddd
		return (it == m_hash.end()) ? 0 : it->m_val;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	const T operator()(int row, int col) const { return get(row, col); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void clear() { m_hash.clear(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	friend void swap(sparse_matrix &a, sparse_matrix &b)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		using std::swap;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		swap(a.m_rows, b.m_rows), swap(a.m_cols, b.m_cols);
Toshihiro Shimizu 890ddd
		swap(a.m_hash, b.m_hash);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  The Standard matrix data type in tlin is double
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef tlin::sparse_matrix<double> spmat;</double>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //TLIN_SPARSEMAT_H