From eb9eab42572edd44322e68d0fc1b7c4918cdb67d Mon Sep 17 00:00:00 2001 From: Daniele Rapetti <5535617+Iximiel@users.noreply.github.com> Date: Wed, 15 May 2024 16:27:13 +0200 Subject: [PATCH] templatized the type of Vector --- src/tools/Communicator.h | 8 +- src/tools/Tensor.h | 3 +- src/tools/Vector.h | 249 ++++++++++++++++++++------------------- 3 files changed, 136 insertions(+), 124 deletions(-) diff --git a/src/tools/Communicator.h b/src/tools/Communicator.h index aff4771852..875bb4f5f0 100644 --- a/src/tools/Communicator.h +++ b/src/tools/Communicator.h @@ -73,9 +73,9 @@ class Communicator { /// Init from reference template explicit Data(T&p): pointer(&p), size(1), nbytes(sizeof(T)), type(getMPIType()) {} /// Init from pointer to VectorGeneric - template explicit Data(VectorGeneric *p,int s): pointer(p), size(n*s), nbytes(sizeof(double)), type(getMPIType()) {} + template explicit Data(VectorTyped *p,int s): pointer(p), size(n*s), nbytes(sizeof(T)), type(getMPIType()) {} /// Init from reference to VectorGeneric - template explicit Data(VectorGeneric &p): pointer(&p), size(n), nbytes(sizeof(double)), type(getMPIType()) {} + template explicit Data(VectorTyped &p): pointer(&p), size(n), nbytes(sizeof(T)), type(getMPIType()) {} /// Init from pointer to TensorGeneric template explicit Data(TensorGeneric *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(double)), type(getMPIType()) {} /// Init from reference to TensorGeneric @@ -104,8 +104,8 @@ class Communicator { MPI_Datatype type; template explicit ConstData(const T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType()) {} template explicit ConstData(const T&p): pointer(&p), size(1), nbytes(sizeof(T)), type(getMPIType()) {} - template explicit ConstData(const VectorGeneric *p,int s): pointer(p), size(n*s), nbytes(sizeof(double)), type(getMPIType()) {} - template explicit ConstData(const VectorGeneric &p): pointer(&p), size(n), nbytes(sizeof(double)), type(getMPIType()) {} + template explicit ConstData(const VectorTyped *p,int s): pointer(p), size(n*s), nbytes(sizeof(T)), type(getMPIType()) {} + template explicit ConstData(const VectorTyped &p): pointer(&p), size(n), nbytes(sizeof(T)), type(getMPIType()) {} template explicit ConstData(const TensorGeneric *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(double)), type(getMPIType()) {} template explicit ConstData(const TensorGeneric &p): pointer(&p), size(n*m), nbytes(sizeof(double)), type(getMPIType()) {} template explicit ConstData(const std::vector&v) { diff --git a/src/tools/Tensor.h b/src/tools/Tensor.h index cac5460af7..c831bc7607 100644 --- a/src/tools/Tensor.h +++ b/src/tools/Tensor.h @@ -570,5 +570,4 @@ static_assert(sizeof(Tensor)==9*sizeof(double), "code cannot work if this is not } -#endif - +#endif //__PLUMED_tools_Tensor_h diff --git a/src/tools/Vector.h b/src/tools/Vector.h index 0911a4ec30..1a108ef25f 100644 --- a/src/tools/Vector.h +++ b/src/tools/Vector.h @@ -73,246 +73,259 @@ int main(){ \endverbatim */ - - -template -class VectorGeneric { - std::array d; +template class VectorTyped; +template +std::ostream & operator<<(std::ostream &os, const VectorTyped& v); +template +class VectorTyped { + std::array d; /// Auxiliary private function for constructor void auxiliaryConstructor(); /// Auxiliary private function for constructor template - void auxiliaryConstructor(double first,Args... arg); + void auxiliaryConstructor(T first,Args... arg); public: -/// Constructor accepting n double parameters. +/// Constructor accepting n T parameters. /// Can be used as Vector<3>(1.0,2.0,3.0) or Vector<2>(2.0,3.0). /// In case a wrong number of parameters is given, a static assertion will fail. template - VectorGeneric(double first,Args... arg); + VectorTyped(T first,Args... arg); /// create it null - VectorGeneric(); + VectorTyped(); +/// get the underline pointer to the data + T* data(); +/// get the underline pointer to the data + const T* data() const; /// set it to zero void zero(); /// array-like access [i] - double & operator[](unsigned i); + T & operator[](unsigned i); /// array-like access [i] - const double & operator[](unsigned i)const; + const T & operator[](unsigned i)const; /// parenthesis access (i) - double & operator()(unsigned i); + T & operator()(unsigned i); /// parenthesis access (i) - const double & operator()(unsigned i)const; + const T & operator()(unsigned i)const; /// increment - VectorGeneric& operator +=(const VectorGeneric& b); + VectorTyped& operator +=(const VectorTyped& b); /// decrement - VectorGeneric& operator -=(const VectorGeneric& b); + VectorTyped& operator -=(const VectorTyped& b); /// multiply - VectorGeneric& operator *=(double s); + VectorTyped& operator *=(T s); /// divide - VectorGeneric& operator /=(double s); + VectorTyped& operator /=(T s); /// sign + - VectorGeneric operator +()const; + VectorTyped operator +()const; /// sign - - VectorGeneric operator -()const; + VectorTyped operator -()const; /// return v1+v2 - template - friend VectorGeneric operator+(const VectorGeneric&,const VectorGeneric&); + template + friend VectorTyped operator+(const VectorTyped&,const VectorTyped&); /// return v1-v2 - template - friend VectorGeneric operator-(const VectorGeneric&,const VectorGeneric&); + template + friend VectorTyped operator-(VectorTyped,const VectorTyped&); /// return s*v - template - friend VectorGeneric operator*(double,const VectorGeneric&); + template + friend VectorTyped operator*(J,VectorTyped); /// return v*s - template - friend VectorGeneric operator*(const VectorGeneric&,double); + template + friend VectorTyped operator*(VectorTyped,J); /// return v/s - template - friend VectorGeneric operator/(const VectorGeneric&,double); + template + friend VectorTyped operator/(const VectorTyped&,J); /// return v2-v1 - template - friend VectorGeneric delta(const VectorGeneric&v1,const VectorGeneric&v2); + template + friend VectorTyped delta(const VectorTyped&v1,const VectorTyped&v2); /// return v1 .scalar. v2 - template - friend double dotProduct(const VectorGeneric&,const VectorGeneric&); + template + friend U dotProduct(const VectorTyped&,const VectorTyped&); + //this bad boy produces a warning (in fact becasue declrare the crossproduc as a friend for ALL thhe possible combinations of n and T) /// return v1 .vector. v2 /// Only available for size 3 - friend VectorGeneric<3> crossProduct(const VectorGeneric<3>&,const VectorGeneric<3>&); + template + friend VectorTyped crossProduct(const VectorTyped&,const VectorTyped&); /// compute the squared modulo - double modulo2()const; + T modulo2()const; /// Compute the modulo. /// Shortcut for sqrt(v.modulo2()) - double modulo()const; + T modulo()const; /// friend version of modulo2 (to simplify some syntax) - template - friend double modulo2(const VectorGeneric&); + template + friend U modulo2(const VectorTyped&); /// friend version of modulo (to simplify some syntax) - template - friend double modulo(const VectorGeneric&); + template + friend U modulo(const VectorTyped&); /// << operator. /// Allows printing vector `v` with `std::cout< - friend std::ostream & operator<<(std::ostream &os, const VectorGeneric&); + friend std::ostream & operator<< <>(std::ostream &os, const VectorTyped&); }; -template -void VectorGeneric::auxiliaryConstructor() +template +void VectorTyped::auxiliaryConstructor() {} -template +template template -void VectorGeneric::auxiliaryConstructor(double first,Args... arg) +void VectorTyped::auxiliaryConstructor(T first,Args... arg) { d[n-(sizeof...(Args))-1]=first; auxiliaryConstructor(arg...); } -template +template template -VectorGeneric::VectorGeneric(double first,Args... arg) +VectorTyped::VectorTyped(T first,Args... arg) { static_assert((sizeof...(Args))+1==n,"you are trying to initialize a Vector with the wrong number of arguments"); auxiliaryConstructor(first,arg...); } -template -void VectorGeneric::zero() { - LoopUnroller::_zero(d.data()); +template +T* VectorTyped::data() {return d.data();} + +template +const T* VectorTyped::data() const {return d.data();} + +template +void VectorTyped::zero() { + LoopUnroller::_zero(d.data()); } -template -VectorGeneric::VectorGeneric() { - LoopUnroller::_zero(d.data()); +template +VectorTyped::VectorTyped() { + LoopUnroller::_zero(d.data()); } -template -double & VectorGeneric::operator[](unsigned i) { +template +T & VectorTyped::operator[](unsigned i) { return d[i]; } -template -const double & VectorGeneric::operator[](unsigned i)const { +template +const T & VectorTyped::operator[](unsigned i)const { return d[i]; } -template -double & VectorGeneric::operator()(unsigned i) { +template +T & VectorTyped::operator()(unsigned i) { return d[i]; } -template -const double & VectorGeneric::operator()(unsigned i)const { +template +const T & VectorTyped::operator()(unsigned i)const { return d[i]; } -template -VectorGeneric& VectorGeneric::operator +=(const VectorGeneric& b) { - LoopUnroller::_add(d.data(),b.d.data()); +template +VectorTyped& VectorTyped::operator +=(const VectorTyped& b) { + LoopUnroller::_add(d.data(),b.d.data()); return *this; } -template -VectorGeneric& VectorGeneric::operator -=(const VectorGeneric& b) { - LoopUnroller::_sub(d.data(),b.d.data()); +template +VectorTyped& VectorTyped::operator -=(const VectorTyped& b) { + LoopUnroller::_sub(d.data(),b.d.data()); return *this; } -template -VectorGeneric& VectorGeneric::operator *=(double s) { - LoopUnroller::_mul(d.data(),s); +template +VectorTyped& VectorTyped::operator *=(T s) { + LoopUnroller::_mul(d.data(),s); return *this; } -template -VectorGeneric& VectorGeneric::operator /=(double s) { - LoopUnroller::_mul(d.data(),1.0/s); +template +VectorTyped& VectorTyped::operator /=(T s) { + LoopUnroller::_mul(d.data(),1.0/s); return *this; } -template -VectorGeneric VectorGeneric::operator +()const { +template +VectorTyped VectorTyped::operator +()const { return *this; } -template -VectorGeneric VectorGeneric::operator -()const { - VectorGeneric r; - LoopUnroller::_neg(r.d.data(),d.data()); +template +VectorTyped VectorTyped::operator -()const { + VectorTyped r; + LoopUnroller::_neg(r.d.data(),d.data()); return r; } -template -VectorGeneric operator+(const VectorGeneric&v1,const VectorGeneric&v2) { - VectorGeneric v(v1); +template +VectorTyped operator+(const VectorTyped&v1,const VectorTyped&v2) { + VectorTyped v(v1); return v+=v2; } -template -VectorGeneric operator-(const VectorGeneric&v1,const VectorGeneric&v2) { - VectorGeneric v(v1); - return v-=v2; +template +VectorTyped operator-(VectorTypedv1,const VectorTyped&v2) { + return v1-=v2; } -template -VectorGeneric operator*(double s,const VectorGeneric&v) { - VectorGeneric vv(v); - return vv*=s; +template +VectorTyped operator*(J s,VectorTypedv) { + return v*=s; } -template -VectorGeneric operator*(const VectorGeneric&v,double s) { - return s*v; +template +VectorTyped operator*(VectorTyped v,J s) { + return v*=s; } -template -VectorGeneric operator/(const VectorGeneric&v,double s) { +template +VectorTyped operator/(const VectorTyped&v,J s) { return v*(1.0/s); } -template -VectorGeneric delta(const VectorGeneric&v1,const VectorGeneric&v2) { +template +VectorTyped delta(const VectorTyped&v1,const VectorTyped&v2) { return v2-v1; } -template -double VectorGeneric::modulo2()const { - return LoopUnroller::_sum2(d.data()); +template +T VectorTyped::modulo2()const { + return LoopUnroller::_sum2(d.data()); } -template -double dotProduct(const VectorGeneric& v1,const VectorGeneric& v2) { - return LoopUnroller::_dot(v1.d.data(),v2.d.data()); +template +T dotProduct(const VectorTyped& v1,const VectorTyped& v2) { + return LoopUnroller::_dot(v1.d.data(),v2.d.data()); } +template inline -VectorGeneric<3> crossProduct(const VectorGeneric<3>& v1,const VectorGeneric<3>& v2) { - return VectorGeneric<3>( +VectorTyped crossProduct(const VectorTyped& v1,const VectorTyped& v2) { + return VectorTyped( v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]); } -template -double VectorGeneric::modulo()const { +template +T VectorTyped::modulo()const { return sqrt(modulo2()); } -template -double modulo2(const VectorGeneric&v) { +template +T modulo2(const VectorTyped&v) { return v.modulo2(); } -template -double modulo(const VectorGeneric&v) { +template +T modulo(const VectorTyped&v) { return v.modulo(); } -template -std::ostream & operator<<(std::ostream &os, const VectorGeneric& v) { +template +std::ostream & operator<<(std::ostream &os, const VectorTyped& v) { for(unsigned i=0; i +using VectorGeneric=VectorTyped; /// \ingroup TOOLBOX /// Alias for one dimensional vectors @@ -331,13 +344,13 @@ typedef VectorGeneric<4> Vector4d; typedef VectorGeneric<5> Vector5d; /// \ingroup TOOLBOX /// Alias for three dimensional vectors -typedef Vector3d Vector; +using Vector=Vector3d; +//using the using keyword seems to be more trasparent static_assert(sizeof(VectorGeneric<2>)==2*sizeof(double), "code cannot work if this is not satisfied"); static_assert(sizeof(VectorGeneric<3>)==3*sizeof(double), "code cannot work if this is not satisfied"); static_assert(sizeof(VectorGeneric<4>)==4*sizeof(double), "code cannot work if this is not satisfied"); -} - -#endif +} //PLMD +#endif //__PLUMED_tools_Vector_h