LocARNA-1.9.2
src/LocARNA/sparse_matrix.hh
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
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends