Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)

operator/hashedSMatrix.hh
Go to the documentation of this file.
00001 /* SMatrix
00002  * sparse matrices
00003  */
00004 
00005 #ifndef hSparseMatrix_hh
00006 #define hSparseMatrix_hh
00007 
00008 #include <iostream>
00009 #include <fstream>
00010 #if __GNUC__ == 2
00011 #  include <float.h>
00012 #  define EPS DBL_EPSILON
00013 #else
00014 #  include <limits>
00015 #  define EPS std::numeric_limits<double>::epsilon()
00016 #endif
00017 #include "basics/typedefs.hh"
00018 #include "basics/outputOperator.hh"
00019 #include "toolbox/pool.hh"
00020 #include "hashedSMatrixIterator.hh"
00021 
00022 namespace concepts {
00023 
00024   // forward declaration
00025   template<class F>
00026   class Matrix;
00027 
00028   template<class F>
00029   class DenseMatrix;
00030 
00031   // **************************************************** HashedSparseMatrix **
00032 
00035   template <class T>
00036   class HashedSparseMatrix {
00037   public:
00038     typedef T value_type;
00040     typedef typename Realtype<T>::type r_type;
00042     typedef typename Cmplxtype<T>::type c_type;
00043 
00044     typedef _HashedSMatrix_iterator<T, T&, T*>             iterator;
00045     typedef _HashedSMatrix_iterator<T, const T&, const T*> const_iterator;
00046 
00050     struct Value {
00051       Value* lnk;
00052       uint   idx;
00053       T      val;
00054 
00064       Value(Value* l, int i, T v = 0.0) { lnk = l; idx = i; val = v; }
00065       void* operator new(size_t sz) { return new char[sz]; }
00066       void* operator new
00067       (size_t, Pool<typename HashedSparseMatrix<T>::Value>& pool) { 
00068         return pool.alloc(); }
00070       Value& operator*=(const T factor) {
00071         val *= factor;
00072         return *this;
00073       }
00074     };
00075 
00081     HashedSparseMatrix(uint r, uint c, uint h);
00082     ~HashedSparseMatrix();
00083 
00084     inline Value** Matrix() const { return matrix; } // new
00085     inline uint HashBits() const { return hashBits; } // new
00086 
00093     T& operator()(const uint r, const uint c);
00094     T operator()(const uint r, const uint c) const;
00095 
00097     const uint rows() const { return nofRows; }
00099     const uint cols() const { return nofCols; }
00100 
00102     template<typename F, typename G>
00103     void operator()(const F f[], G g[]) const;
00104 
00106     HashedSparseMatrix<T>& operator*=(const T factor);
00107 
00112     template<typename F, typename G>
00113     void transpMult(const F f[], G g[]) const;
00114 
00116     uint used() const { return _used; }
00117     float memory() const { 
00118       return sizeof(HashedSparseMatrix<T>) + pool.memory() 
00119         - sizeof(pool); 
00120     }
00121 
00122     void write(std::ostream& ofs) const;
00123     void outputMatlab(std::ostream& ofs) const;
00124     void outputSparseQR(std::ostream& ofs) const;
00125 
00127     void multiply(const HashedSparseMatrix<T>* const fact,
00128                   concepts::Matrix<T>& dest) const;
00130     void multiply(const concepts::Matrix<T>* const fact,
00131                   concepts::Matrix<T>& dest) const;
00132 
00139     const_iterator begin(uint row = 0) const;
00146     iterator begin(uint row = 0);
00148     static iterator end();
00149 
00150     std::ostream& info(std::ostream& os) const;
00151 
00157     void compress(Real threshold = EPS);
00158   private:
00159     Pool<Value> pool;
00160     Value**     matrix;
00161     uint        _used;
00162 
00164     uint        nofRows;
00165 
00167     uint        nofCols;
00168 
00169     uint        hashBits;
00170     uint        hashMsk;
00171 
00172     HashedSparseMatrix(const HashedSparseMatrix<T>&);
00173     void operator =(const HashedSparseMatrix<T>&);
00174 
00185     void dropEntry_(Value*& v, Value*& vPrev, const uint r, const uint c);
00186   };
00187 
00188   template<typename T>
00189   std::ostream& operator<<(std::ostream& os, const HashedSparseMatrix<T>& o) {
00190 #ifdef DEBUG
00191     os << std::flush;
00192 #endif
00193     return o.info(os);
00194   }
00195 
00196   template<class T>
00197   template<class F, class G>
00198   void HashedSparseMatrix<T>::transpMult(const F f[], G g[]) const {
00199     uint r = nofRows << hashBits;
00200 
00201     while (r--)
00202       for(Value* v = matrix[r]; v != NULL; v = v->lnk) 
00203         g[v->idx] += v->val * f[r >> hashBits];
00204   }
00205 
00206   template<class T>
00207   void HashedSparseMatrix<T>::multiply(const HashedSparseMatrix<T>* const fact,
00208                                        concepts::Matrix<T>& dest) const {
00209     conceptsAssert(nofCols == fact->nofRows, Assertion());
00210     conceptsAssert(nofRows == dest.dimX(), Assertion());
00211     conceptsAssert(fact->nofCols == dest.dimY(), Assertion());
00212     uint r = nofRows << hashBits;
00213 
00214     while (r--) {
00215       for (Value* v= matrix[r]; v != 0; v = v->lnk) {
00216         for (uint k = 0; k < fact->nofCols; ++k) {
00217           Value* w = fact->matrix[v->idx << fact->hashBits | (k & fact->hashMsk)];
00218           for (; w != 0 && w->idx != k; w = w->lnk);
00219           if (w != 0) {
00220             T sum = v->val * w->val;
00221             if (sum != (T)0)
00222               dest(r >> hashBits, k) += sum;
00223           }
00224         } // for k
00225       } // for v
00226     } // while
00227   }
00228 
00229 
00230   template<class T>
00231   void HashedSparseMatrix<T>::multiply(const concepts::Matrix<T>* const fact,
00232                                        concepts::Matrix<T>& dest) const {
00233     conceptsAssert(nofCols == fact->dimX(), Assertion());
00234     conceptsAssert(nofRows == dest.dimX(), Assertion());
00235     conceptsAssert(fact->dimY() == dest.dimY(), Assertion());
00236     uint r = nofRows << hashBits;
00237     const uint BnofCols = fact->dimY();
00238     while (r--) {
00239       for (Value* v= matrix[r]; v != 0; v = v->lnk) {
00240         for (uint k = 0; k < BnofCols; ++k) {
00241           T sum = v->val * (*fact)(v->idx,k);
00242           if (sum != (T)0)
00243             dest(r >> hashBits, k) += sum;
00244         } // for k
00245       } // for v
00246     } // while
00247   }
00248 
00249   template<class T>
00250   template<class F, class G>
00251   void HashedSparseMatrix<T>::operator()(const F f[], G g[]) const {
00252     G sum = 0.0;
00253     uint r = nofRows << hashBits;
00254 
00255     while (r--) {
00256       for(Value* v = matrix[r]; v != NULL; v = v->lnk) 
00257         sum += v->val * f[v->idx];
00258       if (!(r & hashMsk)) { 
00259         g[r >> hashBits] = sum;
00260         sum = 0.0;
00261       }
00262     }
00263   }
00264   
00265 } // namespace concepts
00266 
00267 #endif // hSparseMatrix_hh

Home | Doxygen Documentation | Tutorials | Developer Tools (restricted)