|
Shinya Kitaoka |
810553 |
#pragma once
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
namespace tlin {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
The tlin::sparse_matrix class implements a hash-based format for storing
|
|
Shinya Kitaoka |
120a6e |
sparse
|
|
Toshihiro Shimizu |
890ddd |
matrices.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
A tlin::sparse_matrix is a tlin::matrix-compliant class that allows the user
|
|
Shinya Kitaoka |
120a6e |
to
|
|
Shinya Kitaoka |
120a6e |
access the matrix in a purely random fashion, without sacrificing storage
|
|
Shinya Kitaoka |
120a6e |
space or
|
|
Shinya Kitaoka |
120a6e |
efficiency. This is achieved using a single, fast, dynamic hash container that
|
|
Shinya Kitaoka |
120a6e |
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)
|
|
Shinya Kitaoka |
120a6e |
|
|
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>
|
|
Shinya Kitaoka |
120a6e |
class sparse_matrix {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
struct IdxFunctor {
|
|
Shinya Kitaoka |
120a6e |
int m_cols;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
IdxFunctor(int cols) : m_cols(cols) {}
|
|
Shinya Kitaoka |
120a6e |
int operator()(const std::pair<int, int=""> &key) {</int,>
|
|
Shinya Kitaoka |
120a6e |
return key.first * m_cols + key.second;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
int m_rows;
|
|
Shinya Kitaoka |
120a6e |
int m_cols;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tcg::hash<std::pair<int, int="">, T, IdxFunctor> m_hash;</std::pair<int,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
sparse_matrix() : m_rows(0), m_cols(0), m_hash(IdxFunctor(0)) {}
|
|
Shinya Kitaoka |
120a6e |
sparse_matrix(int rows, int cols)
|
|
Shinya Kitaoka |
120a6e |
: m_rows(rows), m_cols(cols), m_hash(cols) {}
|
|
Shinya Kitaoka |
120a6e |
~sparse_matrix() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sparse_matrix(const sparse_matrix &mat)
|
|
Shinya Kitaoka |
120a6e |
: m_rows(mat.m_rows), m_cols(mat.m_cols), m_hash(mat.m_hash) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sparse_matrix &operator=(const sparse_matrix &mat) {
|
|
Shinya Kitaoka |
120a6e |
m_rows = mat.m_rows, m_cols = mat.m_cols, m_hash = mat.m_hash;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int rows() const { return m_rows; }
|
|
Shinya Kitaoka |
120a6e |
int cols() const { return m_cols; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typedef typename tcg::hash<std::pair<int, int="">, T, IdxFunctor> HashMap;</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
tcg::hash<std::pair<int, int="">, T, IdxFunctor> &entries() { return m_hash; }</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
const tcg::hash<std::pair<int, int="">, T, IdxFunctor> &entries() const {</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
return m_hash;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//!\warning Assignments of kind: A.at(1,1) = A.at(0,0) are potentially
|
|
Shinya Kitaoka |
38fd86 |
//! harmful.
|
|
Shinya Kitaoka |
120a6e |
//! Use A.get(x,y) on the right side instead.
|
|
Shinya Kitaoka |
120a6e |
T &at(int row, int col) { return m_hash.touch(std::make_pair(row, col), 0); }
|
|
Shinya Kitaoka |
120a6e |
const T get(int row, int col) const {
|
|
Shinya Kitaoka |
120a6e |
typename HashMap::const_iterator it = m_hash.find(std::make_pair(row, col));
|
|
Shinya Kitaoka |
120a6e |
return (it == m_hash.end()) ? 0 : it->m_val;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
const T operator()(int row, int col) const { return get(row, col); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void clear() { m_hash.clear(); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
friend void swap(sparse_matrix &a, sparse_matrix &b) {
|
|
Shinya Kitaoka |
120a6e |
using std::swap;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
swap(a.m_rows, b.m_rows), swap(a.m_cols, b.m_cols);
|
|
Shinya Kitaoka |
120a6e |
swap(a.m_hash, b.m_hash);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
#endif // TLIN_SPARSEMAT_H
|