diff --git a/diis.h b/diis.h index d6f09b8..90b9666 100644 --- a/diis.h +++ b/diis.h @@ -9,7 +9,9 @@ #include "la_traits.h" #include "auxstorage.h" -// T is some solution vector in form of NRVec, NRMat, or NRSMat over double or complex fields +// Typically, T is some solution vector in form of NRVec, NRMat, or NRSMat over double or complex fields +// actually it can be anything what has operator=(), dot() , axpy(), norm() and copyonwrite(), and LA_traits::normtype and elementtype +// and get() and put() if external storage is requested template class DIIS @@ -23,7 +25,9 @@ class DIIS AuxStorage *st; T *stor; public: + DIIS() {dim=0;}; //for array of diis DIIS(const int n, const bool core=1); + void setup(const int n, const bool core=1); ~DIIS(); typename LA_traits::normtype extrapolate(T &vec); //vec is input/output; returns square residual norm }; @@ -35,9 +39,21 @@ st=incore?NULL: new AuxStorage; stor= incore? new T[dim] : NULL; bmat= (Te)0; for(int i=1; i +void DIIS::setup(const int n, const bool core) +{ +dim=n; +incore=core; +bmat.resize(n); +st=incore?NULL: new AuxStorage; +stor= incore? new T[dim] : NULL; +bmat= (Te)0; for(int i=1; i DIIS::~DIIS() { @@ -49,6 +65,7 @@ if(stor) delete[] stor; template typename LA_traits::normtype DIIS::extrapolate(T &vec) { +if(!dim) laerror("attempt to extrapolate from uninitialized DIIS"); //if dim exceeded, shift if(aktdim==dim) { @@ -68,12 +85,12 @@ if(aktdim==1) return (typename LA_traits::normtype)1000000000; //calculate difference; vec.copyonwrite(); -if(incore) vec -= stor[(aktdim-2+cyclicshift)%dim]; +if(incore) vec.axpy((Te)-1,stor[(aktdim-2+cyclicshift)%dim]); else { T tmp=vec; st->get(tmp,(aktdim-2+cyclicshift)%dim); - vec -= tmp; + vec.axpy((Te)-1,tmp); } //calculate overlaps of differences (if storage is cheap, they could rather be stored than recomputed) diff --git a/fourindex.h b/fourindex.h index 4008494..fb11e75 100644 --- a/fourindex.h +++ b/fourindex.h @@ -600,8 +600,17 @@ istream& operator>>(istream &s, fourindex &x) //note - loops for the twoelectronrealmullikan integral to be unique and in canonical order // i=1..n, j=1..i, k=1..i, l=1..(i==k?j:k) +//general template declaration template class fourindex_dense; +//traits class +template +struct LA_traits > { +typedef T elementtype; +typedef typename LA_traits::normtype normtype; +}; + + //make it as a derived class in order to be able to use it in a base class context - "supermatrix" operations template class fourindex_dense : public NRSMat { @@ -768,7 +777,4 @@ if(a class NRVec; template class NRMat; +template class NRMat_from1; template class NRSMat; +template class NRSMat_from1; template class SparseMat; //for general sortable classes @@ -174,30 +176,34 @@ static void clear(C *dest, unsigned int n) {for(unsigned int i=0; i -struct LA_traits_aux, scalar_false> { -typedef C elementtype; -typedef NRMat producttype; -typedef typename LA_traits::normtype normtype; -static bool gencmp(const C *x, const C *y, int n) {for(int i=0; iy;} -static inline bool smaller(const C &x, const C &y) {return x &x) {return x.norm();} -static inline void axpy (NRSMat&s, const NRSMat &x, const C c) {s.axpy(c,x);} -static void put(int fd, const C &x, bool dimensions=1, bool transp=0) {x.put(fd,dimensions);} -static void get(int fd, C &x, bool dimensions=1, bool transp=0) {x.get(fd,dimensions);} -static void multiput(unsigned int n,int fd, const C *x, bool dimensions=1) {for(unsigned int i=0; i \ +struct LA_traits_aux, scalar_false> { \ +typedef C elementtype; \ +typedef NRMat producttype; \ +typedef typename LA_traits::normtype normtype; \ +static bool gencmp(const C *x, const C *y, int n) {for(int i=0; iy;} \ +static inline bool smaller(const C &x, const C &y) {return x &x) {return x.norm();} \ +static inline void axpy (X&s, const X &x, const C c) {s.axpy(c,x);} \ +static void put(int fd, const C &x, bool dimensions=1, bool transp=0) {x.put(fd,dimensions);} \ +static void get(int fd, C &x, bool dimensions=1, bool transp=0) {x.get(fd,dimensions);} \ +static void multiput(unsigned int n,int fd, const C *x, bool dimensions=1) {for(unsigned int i=0; i