LocARNA-1.9.2
|
00001 #ifndef SPARSE_MATRIX_HH 00002 #define SPARSE_MATRIX_HH 00003 00004 #ifdef HAVE_CONFIG_H 00005 #include <config.h> 00006 #endif 00007 00008 #include <iostream> 00009 00010 #include "aux.hh" 00011 00012 namespace LocARNA { 00013 00025 template <typename T> 00026 class SparseMatrix { 00027 public: 00028 typedef T value_t; 00029 00030 typedef size_t size_type; 00031 00032 typedef std::pair<size_type, size_type> 00033 key_t; 00034 00035 protected: 00036 typedef 00037 typename unordered_map<key_t, value_t, pair_of_size_t_hash>::type 00038 map_t; 00039 map_t the_map_; 00040 value_t def_; 00041 00042 public: 00048 typedef typename map_t::const_iterator const_iterator; 00049 00058 class element { 00059 private: 00060 SparseMatrix<T> *m_; 00061 key_t k_; 00062 00063 public: 00072 element(SparseMatrix<T> *m, const key_t &k) : m_(m), k_(k) {} 00073 00081 operator value_t() { 00082 typename map_t::const_iterator it = m_->the_map_.find(k_); 00083 if (it == m_->the_map_.end()) 00084 return m_->def_; 00085 else 00086 return it->second; 00087 } 00088 00100 element 00101 operator+=(const value_t &x) { 00102 const_iterator it = m_->the_map_.find(k_); 00103 if (it == m_->the_map_.end()) 00104 m_->the_map_[k_] = m_->def_ + x; 00105 else 00106 m_->the_map_[k_] += x; 00107 00108 return *this; 00109 } 00110 00123 element & 00124 operator=(const value_t &x) { 00125 if (x == m_->def_) { 00126 m_->the_map_.erase(k_); 00127 } else { 00128 // the following replaces m_->the_map_[k_] = x; 00129 // but never calls the default constructor for value_t 00130 00131 typename map_t::iterator it = m_->the_map_.find(k_); 00132 if (it != m_->the_map_.end()) { 00133 it->second = x; 00134 } else { 00135 m_->the_map_.insert(typename map_t::value_type(k_, x)); 00136 } 00137 } 00138 return *this; 00139 } 00140 }; 00141 00145 SparseMatrix() : the_map_(), def_() {} 00146 00152 explicit SparseMatrix(const value_t &def) : the_map_(), def_(def) {} 00153 00162 element 00163 operator()(size_type i, size_type j) { 00164 return element(this, key_t(i, j)); 00165 } 00166 00175 const value_t & 00176 operator()(size_type i, size_type j) const { 00177 const_iterator it = the_map_.find(key_t(i, j)); 00178 if (it == the_map_.end()) 00179 return def_; 00180 else 00181 return it->second; 00182 } 00183 00197 void 00198 set(size_type i, size_type j, const value_t &val) { 00199 typename map_t::iterator it = the_map_.find(key_t(i, j)); 00200 if (it != the_map_.end()) { 00201 it->second = val; 00202 } else { 00203 the_map_.insert(typename map_t::value_type(key_t(i, j), val)); 00204 } 00205 } 00206 00217 value_t & 00218 ref(size_type i, size_type j) { 00219 typename map_t::iterator it = the_map_.find(key_t(i, j)); 00220 if (it == the_map_.end()) { 00221 the_map_.insert(typename map_t::value_type(key_t(i, j), def_)); 00222 it = the_map_.find(key_t(i, j)); 00223 } 00224 return it->second; 00225 } 00226 00233 void 00234 reset(size_type i, size_type j) { 00235 typename map_t::iterator it = the_map_.find(key_t(i, j)); 00236 if (it != the_map_.end()) { 00237 the_map_.erase(key_t(i, j)); 00238 } 00239 } 00240 00245 size_type 00246 size() const { 00247 return the_map_.size(); 00248 } 00249 00255 bool 00256 empty() const { 00257 return the_map_.empty(); 00258 } 00259 00263 void 00264 clear() { 00265 the_map_.clear(); 00266 } 00267 00275 const_iterator 00276 begin() const { 00277 return the_map_.begin(); 00278 } 00279 00286 const_iterator 00287 end() const { 00288 return the_map_.end(); 00289 } 00290 00296 const value_t & 00297 def() const { 00298 return def_; 00299 } 00300 }; 00301 00310 template <class T> 00311 inline std::ostream & 00312 operator<<(std::ostream &out, const SparseMatrix<T> &m) { 00313 for (typename SparseMatrix<T>::const_iterator it = m.begin(); 00314 m.end() != it; ++it) { 00315 out << "(" << it->first.first << "," << it->first.second << ") " 00316 << it->second << std::endl; 00317 } 00318 return out; 00319 } 00320 00321 } // end namespace LocARNA 00322 00323 #endif // SPARSE_MATRIX_HH