Go to the documentation of this file.00001
00002
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
00025 template<class F>
00026 class Matrix;
00027
00028 template<class F>
00029 class DenseMatrix;
00030
00031
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; }
00085 inline uint HashBits() const { return hashBits; }
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 }
00225 }
00226 }
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 }
00245 }
00246 }
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 }
00266
00267 #endif // hSparseMatrix_hh