diff --git a/sparsesmat.cc b/sparsesmat.cc index 7af5eae..248bc9e 100644 --- a/sparsesmat.cc +++ b/sparsesmat.cc @@ -28,6 +28,7 @@ template void SparseSMat::gemm(const T beta, const SparseSMat &a, const char transa, const SparseSMat &b, const char transb, const T alpha) { +std::cerr << "enter gemm\n"; (*this) *= beta; if(alpha==(T)0) return; if(a.nn!=b.nn || a.nn!=nn) laerror("incompatible sizes in SparseSMat::gemm"); @@ -63,7 +64,11 @@ for(SPMatindex k=0; k::iterator p; for(p=x.v[i]->begin(); p!=x.v[i]->end(); ++p) (*v[i])[p->first] = p->second * alpha; } +simplify(); } @@ -115,11 +121,83 @@ for(SPMatindex i=0; i +SparseSMat & SparseSMat::operator=(const T &a) +{ +clear(); +for(SPMatindex i=0; i; + (*v[i])[i] = a; + } +return *this; +} + +template +SparseSMat & SparseSMat::operator+=(const T &a) +{ +copyonwrite(); +for(SPMatindex i=0; i::iterator p; + p= v[i]->find(i); + if(p!=v[i]->end()) p->second+=a; else (*v[i])[i] = a; + } + else {v[i] = new std::map; (*v[i])[i] = a;} + } +return *this; +} + + +template +SparseSMat & SparseSMat::operator-=(const T &a) +{ +copyonwrite(); +for(SPMatindex i=0; i::iterator p; + p= v[i]->find(i); + if(p!=v[i]->end()) p->second-=a; else (*v[i])[i] = -a; + } + else {v[i] = new std::map; (*v[i])[i] = -a;} + } +return *this; +} + +template +typename LA_traits::normtype SparseSMat::norm(const T scalar) const +{ +typename LA_traits::normtype sum=0; + +for(SPMatindex i=0; i::iterator p; + p= v[i]->find(i); + if(p!=v[i]->end()) sum += LA_traits::sqrabs(p->second - scalar); + else sum += LA_traits::sqrabs(scalar); + } + else sum += LA_traits::sqrabs(scalar); //missing diagonal element + +return sqrt(sum); +} + + + + #define INSTANTIZE(T) \ template void SparseSMat::gemm(const T beta, const SparseSMat &a, const char transa, const SparseSMat &b, const char transb, const T alpha); \ template SparseSMat & SparseSMat::operator*=(const T &a); \ template void SparseSMat::gemv(const T beta, NRVec &r, const char trans, const T alpha, const NRVec &x) const; \ template void SparseSMat::axpy(const T alpha, const SparseSMat &x, const bool transp); \ +template SparseSMat & SparseSMat::operator=(const T &a); \ +template SparseSMat & SparseSMat::operator+=(const T &a); \ +template SparseSMat & SparseSMat::operator-=(const T &a); \ +template LA_traits::normtype SparseSMat::norm(const T scalar) const; \ INSTANTIZE(double) diff --git a/sparsesmat.h b/sparsesmat.h index 41ec3bd..298b8b3 100644 --- a/sparsesmat.h +++ b/sparsesmat.h @@ -59,12 +59,11 @@ public: void copyonwrite(); void resize(const SPMatindex n); void clear() {resize(nn);} - void simplify(); + unsigned long long simplify(); ~SparseSMat(); inline int getcount() const {return count?*count:0;} SparseSMat & operator*=(const T &a); //multiply by a scalar inline const SparseSMat operator*(const T &rhs) const {return SparseSMat(*this) *= rhs;} -/*@@@to be done inline const SparseSMat operator+(const T &rhs) const {return SparseSMat(*this) += rhs;} inline const SparseSMat operator-(const T &rhs) const {return SparseSMat(*this) -= rhs;} inline const SparseSMat operator+(const SparseSMat &rhs) const {return SparseSMat(*this) += rhs;} @@ -72,16 +71,15 @@ public: SparseSMat & operator=(const T &a); //assign a to diagonal SparseSMat & operator+=(const T &a); //assign a to diagonal SparseSMat & operator-=(const T &a); //assign a to diagonal - SparseSMat & operator+=(const SparseSMat &rhs); - SparseSMat & operator-=(const SparseSMat &rhs); - void gemv(const T beta, NRVec &r, const char trans, const T alpha, const NRVec &x) const; void axpy(const T alpha, const SparseSMat &x, const bool transp=0); // this+= a*x - const typename LA_traits::normtype norm(const T scalar=(T)0) const; -*/ + inline SparseSMat & operator+=(const SparseSMat &rhs) {axpy((T)1,rhs); return *this;}; + inline SparseSMat & operator-=(const SparseSMat &rhs) {axpy((T)-1,rhs); return *this;}; + void gemv(const T beta, NRVec &r, const char trans, const T alpha, const NRVec &x) const; + typename LA_traits::normtype norm(const T scalar=(T)0) const; inline const SparseSMat operator*(const SparseSMat &rhs) const {SparseSMat r(nn); r.gemm(0,*this,'n',rhs,'n',1); return r;}; //!!!NOT A GENERAL ROUTINE, JUST FOR THE CASES WHEN THE RESULT STAYS SYMMETRIC void gemm(const T beta, const SparseSMat &a, const char transa, const SparseSMat &b, const char transb, const T alpha); //this := alpha*op( A )*op( B ) + beta*this !!!NOT A GENERAL ROUTINE, JUST FOR THE CASES WHEN THE RESULT STAYS SYMMETRIC inline void add(const SPMatindex n, const SPMatindex m, const T elem, const bool both=true); - unsigned int length() const; + inline unsigned long long length() {return simplify();}; void transposeme() const {}; int nrows() const {return nn;} int ncols() const {return nn;} @@ -234,7 +232,7 @@ if(*count > 1) //it was shared else //it was not shared { //delete all trees - for(SPMatindex i=0; i & SparseSMat::operator=(const SparseSMat &rhs) { if(v) { - for(SPMatindex i=0; i -void SparseSMat::simplify() +unsigned long long SparseSMat::simplify() { +unsigned long long count=0; for(SPMatindex i=0; i l; typename std::map::iterator p; -for(p=v[i]->begin(); p!=v[i]->end(); ++p) - if(std::abs(p->second) < SPARSEEPSILON) l.push_front(p->first); -typename std::list::iterator q; -for(q=l.begin(); q!=l.end(); ++q) v[i]->erase(*q); -if(v[i]->size() == 0) delete v[i]; -} + for(p=v[i]->begin(); p!=v[i]->end(); ++p) + if(std::abs(p->second) < SPARSEEPSILON) l.push_front(p->first); else ++count; + typename std::list::iterator q; + for(q=l.begin(); q!=l.end(); ++q) v[i]->erase(*q); + if(v[i]->size() == 0) {delete v[i]; v[i]=NULL;} + } +return count; } template