class BaseVector; typedef auto_ptr TempVector; template class S_BaseVector; /** Base class to linalg expression templates */ template class VVecExpr { const T data; public: /// VVecExpr (const T & d) : data(d) { ; } /// assign s * vector-expression data to v template void AssignTo (TS s , BaseVector & v) const { data.AssignTo(s, v); } /// add s * vector-expression data to v template void AddTo (TS s, BaseVector & v) const { data.AddTo(s, v); } }; /** Base vector for linalg */ class BaseVector { protected: /// size of vector int size; /// number of doubles per entry int entrysize; public: /// BaseVector () throw () { ; } /// virtual ~BaseVector () throw () { ; } /// template BaseVector & operator= (const VVecExpr & v) { v.AssignTo (1.0, *this); return *this; } /// BaseVector & operator= (const BaseVector & v); /// BaseVector & operator= (double s); /// BaseVector & operator= (Complex s); /// template BaseVector & operator+= (const VVecExpr & v) { v.AddTo (1.0, *this); return *this; } /// BaseVector & operator+= (const BaseVector & v) { Add (1.0, v); return *this; } /// template BaseVector & operator-= (const VVecExpr & v) { v.AddTo (-1.0, *this); return *this; } /// BaseVector & operator-= (const BaseVector & v) { Add (-1.0, v); return *this; } /// BaseVector & operator*= (double s) { return Scale (s); } /// BaseVector & operator*= (Complex s) { return Scale (s); } /// BaseVector & operator/= (double s) { if (s == 0) throw Exception ("BaseVector::operator/=: division by zero"); return Scale (1/s); } /// BaseVector & operator/= (Complex s) { if (s == 0.0) throw Exception ("BaseVector::operator/=: division by zero"); return Scale (1.0/s); } template S_BaseVector & Spec() { return dynamic_cast&> (*this); } template const S_BaseVector & Spec() const { return dynamic_cast&> (*this); } int Size() const throw () { return size; } int EntrySize() const throw () { return entrysize; } virtual void * Memory () const throw () = 0; virtual FlatVector FVDouble () const throw() = 0; virtual FlatVector FVComplex () const throw() = 0; template TSCAL InnerProduct (const BaseVector & v2) const { return dynamic_cast&> (*this) . InnerProduct (v2); } double L2Norm () const { return ngbla::L2Norm (FVDouble()); } BaseVector & Scale (double scal); BaseVector & Scale (Complex scal); BaseVector & SetScalar (double scal); BaseVector & SetScalar (Complex scal); BaseVector & Set (double scal, const BaseVector & v); BaseVector & Set (Complex scal, const BaseVector & v); BaseVector & Add (double scal, const BaseVector & v); BaseVector & Add (Complex scal, const BaseVector & v); virtual ostream & Print (ostream & ost) const; virtual void Save(ostream & ost) const; virtual void Load(istream & ist); virtual void MemoryUsage (ARRAY & mu) const; virtual BaseVector * CreateVector () const; virtual void SetRandom (); virtual TempVector Range (int begin, int end); virtual TempVector Range (int begin, int end) const; void GetIndirect (const ARRAY & ind, FlatVector & v) const; void GetIndirect (const ARRAY & ind, FlatVector & v) const; void SetIndirect (const ARRAY & ind, const FlatVector & v); void SetIndirect (const ARRAY & ind, const FlatVector & v); void AddIndirect (const ARRAY & ind, const FlatVector & v); void AddIndirect (const ARRAY & ind, const FlatVector & v); }; /** Decision between double or Complex */ template class S_BaseVector : public BaseVector { public: S_BaseVector () throw () { ; } virtual ~S_BaseVector() throw() { ; } S_BaseVector & operator= (double s); SCAL InnerProduct (const BaseVector & v2) const { return ngbla::InnerProduct (FVScal(), dynamic_cast(v2).FVScal()); } virtual FlatVector FVDouble () const throw(); virtual FlatVector FVComplex () const throw(); virtual FlatVector FVScal () const throw() { return FlatVector (size * entrysize, Memory()); } }; template <> class S_BaseVector : public BaseVector { public: S_BaseVector () throw() { ; } ~S_BaseVector () throw() { ; } Complex InnerProduct (const BaseVector & v2) const { return ngbla::InnerProduct (FVScal(), dynamic_cast(v2).FVScal()); } virtual FlatVector FVDouble () const throw(); virtual FlatVector FVComplex () const throw(); virtual FlatVector FVScal () const throw() { return FlatVector (size * entrysize/2, Memory()); } }; /* ********************* Expression templates ***************** */ template <> class VVecExpr { const BaseVector & v; public: VVecExpr (const BaseVector & av) : v(av) { ; } template void AssignTo (TS s, BaseVector & v2) const { v2.Set (s, v); } template void AddTo (TS s, BaseVector & v2) const { v2.Add (s, v); } }; /* ***************************** VSumExpr ************************** */ /// template class VSumExpr { const TA a; const TB b; public: VSumExpr (const TA & aa, const TB & ab) : a(aa), b(ab) { ; } template void AssignTo (TS s, BaseVector & v) const { a.AssignTo (s, v); b.AddTo (s, v); } template void AddTo (TS s, BaseVector & v) const { a.AddTo (s, v); b.AddTo (s, v); } }; inline VVecExpr, VVecExpr > > operator+ (const BaseVector & a, const BaseVector & b) { typedef VSumExpr, VVecExpr > TRES; return TRES (a, b); } template inline VVecExpr, VVecExpr > > operator+ (const VVecExpr & a, const BaseVector & b) { typedef VSumExpr, VVecExpr > TRES; return TRES (a, b); } template inline VVecExpr, VVecExpr > > operator+ (const BaseVector & a, const VVecExpr & b) { typedef VSumExpr, VVecExpr > TRES; return TRES (a, b); } template inline VVecExpr, VVecExpr > > operator+ (const VVecExpr & a, const VVecExpr & b) { typedef VSumExpr, VVecExpr > TRES; return TRES (a, b); } /* ***************************** VSubExpr ************************** */ /// template class VSubExpr { const TA a; const TB b; public: VSubExpr (const TA & aa, const TB & ab) : a(aa), b(ab) { ; } template void AssignTo (TS s, BaseVector & v) const { a.AssignTo (s, v); b.AddTo (-s, v); } template void AddTo (TS s, BaseVector & v) const { a.AddTo (s, v); b.AddTo (-s, v); } }; inline VVecExpr, VVecExpr > > operator- (const BaseVector & a, const BaseVector & b) { typedef VSubExpr, VVecExpr > TRES; return TRES (a, b); } template inline VVecExpr, VVecExpr > > operator- (const VVecExpr & a, const BaseVector & b) { typedef VSubExpr, VVecExpr > TRES; return TRES (a, b); } template inline VVecExpr, VVecExpr > > operator- (const BaseVector & a, const VVecExpr & b) { typedef VSubExpr, VVecExpr > TRES; return TRES (a, b); } template inline VVecExpr, VVecExpr > > operator- (const VVecExpr & a, const VVecExpr & b) { typedef VSubExpr, VVecExpr > TRES; return TRES (a, b); } /* ************************* Scal * Vec ******************** */ /// template class VScaleExpr { const TA a; const TSCAL scal; public: VScaleExpr (const TA & aa, const TSCAL & as) : a(aa), scal(as) { ; } template void AssignTo (TS s, BaseVector & v) const { a.AssignTo (scal * s, v); } template void AddTo (TS s, BaseVector & v) const { a.AddTo (scal * s, v); } }; inline VVecExpr, double> > operator* (const BaseVector & a, const double & b) { typedef VScaleExpr, double> TRES; return TRES (a, b); } template inline VVecExpr, double> > operator* (const VVecExpr & a, const double & b) { typedef VScaleExpr, double> TRES; return TRES (a, b); } inline VVecExpr, Complex> > operator* (const BaseVector & a, const Complex & b) { typedef VScaleExpr, Complex> TRES; return TRES (a, b); } template inline VVecExpr, Complex> > operator* (const VVecExpr & a, const Complex & b) { typedef VScaleExpr, Complex> TRES; return TRES (a, b); } inline VVecExpr, double> > operator* (const double & b, const BaseVector & a) { typedef VScaleExpr, double> TRES; return TRES (a, b); } template inline VVecExpr, double> > operator* (const double & b, const VVecExpr & a) { typedef VScaleExpr, double> TRES; return TRES (a, b); } inline VVecExpr, Complex> > operator* (const Complex & b, const BaseVector & a) { typedef VScaleExpr, Complex> TRES; return TRES (a, b); } template inline VVecExpr, Complex> > operator* (const Complex & b, const VVecExpr & a) { typedef VScaleExpr, Complex> TRES; return TRES (a, b); } /* *********************** operator<< ********************** */ /// inline ostream & operator<< (ostream & ost, const BaseVector & v) { return v.Print(ost); } /// inline double InnerProduct (const BaseVector & v1, const BaseVector & v2) { return dynamic_cast&>(v1).InnerProduct(v2); } /// template inline SCAL S_InnerProduct (const BaseVector & v1, const BaseVector & v2) { return dynamic_cast&>(v1).InnerProduct(v2); } /// inline double L2Norm (const BaseVector & v) { return v.L2Norm(); }