diff --git a/regtest/basic/rt-make-0/config b/regtest/basic/rt-make-0/config index df1f95bf3e..3e5d21664c 100644 --- a/regtest/basic/rt-make-0/config +++ b/regtest/basic/rt-make-0/config @@ -1 +1,2 @@ type=make +#should we rename this to something meaningful? like "rt-VectorTensor"? diff --git a/regtest/basic/rt-make-4/main.cpp b/regtest/basic/rt-make-4/main.cpp index 86f79df350..84315d99a0 100644 --- a/regtest/basic/rt-make-4/main.cpp +++ b/regtest/basic/rt-make-4/main.cpp @@ -50,7 +50,9 @@ int main () { PLMD::TensorGeneric<4,4> mat; PLMD::TensorGeneric<1,4> evec; PLMD::VectorGeneric<4> eval_underlying; - + + //The both of the two following lines are scary, but on my machine are equivalent + //PLMD::Vector1d* eval=reinterpret_cast(eval_underlying.data()); auto eval = new(&eval_underlying[0]) PLMD::VectorGeneric<1>; mat[1][0]=mat[0][1]=3.0; diff --git a/src/tools/Communicator.h b/src/tools/Communicator.h index 875bb4f5f0..47ae0673f7 100644 --- a/src/tools/Communicator.h +++ b/src/tools/Communicator.h @@ -76,10 +76,10 @@ class Communicator { 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(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 - template explicit Data(TensorGeneric &p): pointer(&p), size(n*m), nbytes(sizeof(double)), type(getMPIType()) {} +/// Init from pointer to TensorTyped + template explicit Data(TensorTyped *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(T)), type(getMPIType()) {} +/// Init from reference to TensorTyped + template explicit Data(TensorTyped &p): pointer(&p), size(n*m), nbytes(sizeof(T)), type(getMPIType()) {} /// Init from reference to std::vector template explicit Data(std::vector&v) { Data d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type; @@ -106,8 +106,8 @@ class Communicator { template explicit ConstData(const T&p): pointer(&p), size(1), nbytes(sizeof(T)), 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 TensorTyped *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(T)), type(getMPIType()) {} + template explicit ConstData(const TensorTyped &p): pointer(&p), size(n*m), nbytes(sizeof(T)), type(getMPIType()) {} template explicit ConstData(const std::vector&v) { ConstData d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type; } diff --git a/src/tools/Tensor.h b/src/tools/Tensor.h index c831bc7607..755050204e 100644 --- a/src/tools/Tensor.h +++ b/src/tools/Tensor.h @@ -31,10 +31,10 @@ namespace PLMD { +//should I add something for calling ssyevr? /// Small class to contain local utilities. /// Should not be used outside of the TensorGeneric class. -class TensorGenericAux { -public: +struct TensorGenericAux { // local redefinition, just to avoid including lapack.h here static void local_dsyevr(const char *jobz, const char *range, const char *uplo, int *n, double *a, int *lda, double *vl, double *vu, int * @@ -83,166 +83,142 @@ int main(){ \endverbatim */ -template -class TensorGeneric: - public MatrixSquareBracketsAccess,double> + +template class TensorTyped; + +template +std::ostream & operator<<(std::ostream &os, const TensorTyped& t); + +template +class TensorTyped: + public MatrixSquareBracketsAccess,T> { - std::array d; + 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*m double parameters. +/// Constructor accepting n*m T parameters. /// Can be used as Tensor<2,2>(1.0,2.0,3.0,4.0) /// In case a wrong number of parameters is given, a static assertion will fail. template - TensorGeneric(double first,Args... arg); + TensorTyped(T first,Args... arg); /// initialize the tensor to zero - TensorGeneric(); + TensorTyped(); /// initialize a tensor as an external product of two Vector - TensorGeneric(const VectorGeneric&v1,const VectorGeneric&v2); + TensorTyped(const VectorTyped&v1,const VectorTyped&v2); /// set it to zero void zero(); +/// get the underline pointer to data + T* data(); +/// get the underline pointer to data + const T* data() const; /// access element - double & operator() (unsigned i,unsigned j); + T & operator() (unsigned i,unsigned j); /// access element - const double & operator() (unsigned i,unsigned j)const; + const T & operator() (unsigned i,unsigned j)const; /// increment - TensorGeneric& operator +=(const TensorGeneric& b); + TensorTyped& operator +=(const TensorTyped& b); /// decrement - TensorGeneric& operator -=(const TensorGeneric& b); + TensorTyped& operator -=(const TensorTyped& b); /// multiply - TensorGeneric& operator *=(double); + TensorTyped& operator *=(T); /// divide - TensorGeneric& operator /=(double); + TensorTyped& operator /=(T); /// return +t - TensorGeneric operator +()const; + TensorTyped operator +()const; /// return -t - TensorGeneric operator -()const; + TensorTyped operator -()const; /// set j-th column - TensorGeneric& setCol(unsigned j,const VectorGeneric & c); + TensorTyped& setCol(unsigned j,const VectorTyped & c); /// set i-th row - TensorGeneric& setRow(unsigned i,const VectorGeneric & r); + TensorTyped& setRow(unsigned i,const VectorTyped & r); /// get j-th column - VectorGeneric getCol(unsigned j)const; + VectorTyped getCol(unsigned j)const; /// get i-th row - VectorGeneric getRow(unsigned i)const; -/// return t1+t2 - template - friend TensorGeneric operator+(const TensorGeneric&,const TensorGeneric&); -/// return t1+t2 - template - friend TensorGeneric operator-(const TensorGeneric&,const TensorGeneric&); -/// scale the tensor by a factor s - template - friend TensorGeneric operator*(double,const TensorGeneric&); -/// scale the tensor by a factor s - template - friend TensorGeneric operator*(const TensorGeneric&,double s); -/// scale the tensor by a factor 1/s - template - friend TensorGeneric operator/(const TensorGeneric&,double s); + VectorTyped getRow(unsigned i)const; /// returns the determinant - double determinant()const; + T determinant()const; /// return an identity tensor - static TensorGeneric identity(); + static TensorTyped identity(); /// return the matrix inverse - TensorGeneric inverse()const; + TensorTyped inverse()const; /// return the transpose matrix - TensorGeneric transpose()const; -/// matrix-matrix multiplication - template - friend TensorGeneric matmul(const TensorGeneric&,const TensorGeneric&); -/// matrix-vector multiplication - template - friend VectorGeneric matmul(const TensorGeneric&,const VectorGeneric&); -/// vector-matrix multiplication - template - friend VectorGeneric matmul(const VectorGeneric&,const TensorGeneric&); -/// vector-vector multiplication (maps to dotProduct) - template - friend double matmul(const VectorGeneric&,const VectorGeneric&); -/// matrix-matrix-matrix multiplication - template - friend TensorGeneric matmul(const TensorGeneric&,const TensorGeneric&,const TensorGeneric&); -/// matrix-matrix-vector multiplication - template - friend VectorGeneric matmul(const TensorGeneric&,const TensorGeneric&,const VectorGeneric&); -/// vector-matrix-matrix multiplication - template - friend VectorGeneric matmul(const VectorGeneric&,const TensorGeneric&,const TensorGeneric&); -/// vector-matrix-vector multiplication - template - friend double matmul(const VectorGeneric&,const TensorGeneric&,const VectorGeneric&); -/// returns the determinant of a tensor - friend double determinant(const TensorGeneric<3,3>&); -/// returns the inverse of a tensor (same as inverse()) - friend TensorGeneric<3,3> inverse(const TensorGeneric<3,3>&); -/// returns the transpose of a tensor (same as transpose()) - template - friend TensorGeneric transpose(const TensorGeneric&); -/// returns the transpose of a tensor (same as TensorGeneric(const VectorGeneric&,const VectorGeneric&)) - template - friend TensorGeneric extProduct(const VectorGeneric&,const VectorGeneric&); - friend TensorGeneric<3,3> dcrossDv1(const VectorGeneric<3>&,const VectorGeneric<3>&); - friend TensorGeneric<3,3> dcrossDv2(const VectorGeneric<3>&,const VectorGeneric<3>&); - friend TensorGeneric<3,3> VcrossTensor(const VectorGeneric<3>&,const TensorGeneric<3,3>&); - friend TensorGeneric<3,3> VcrossTensor(const TensorGeneric<3,3>&,const VectorGeneric<3>&); -/// Derivative of a normalized vector - friend TensorGeneric<3,3> deriNorm(const VectorGeneric<3>&,const TensorGeneric<3,3>&); + TensorTyped transpose()const; /// << operator. /// Allows printing tensor `t` with `std::cout< - friend std::ostream & operator<<(std::ostream &os, const TensorGeneric&); -/// Diagonalize tensor. -/// Syntax is the same as Matrix::diagMat. -/// In addition, it is possible to call if with m_ smaller than n_. In this case, -/// only the first (smaller) m_ eigenvalues and eigenvectors are retrieved. -/// If case lapack fails (info!=0) it throws an exception. -/// Notice that tensor is assumed to be symmetric!!! - template - friend void diagMatSym(const TensorGeneric&,VectorGeneric&evals,TensorGeneric&evec); + friend std::ostream & operator<< <>(std::ostream &os, const TensorTyped&); }; -template -void TensorGeneric::auxiliaryConstructor() +template +void TensorTyped::auxiliaryConstructor() {} -template +template template -void TensorGeneric::auxiliaryConstructor(double first,Args... arg) +void TensorTyped::auxiliaryConstructor(T first,Args... arg) { d[n*m-(sizeof...(Args))-1]=first; auxiliaryConstructor(arg...); } -template +template template -TensorGeneric::TensorGeneric(double first,Args... arg) +TensorTyped::TensorTyped(T first,Args... arg) { static_assert((sizeof...(Args))+1==n*m,"you are trying to initialize a Tensor with the wrong number of arguments"); auxiliaryConstructor(first,arg...); } -template -TensorGeneric::TensorGeneric() { - LoopUnroller::_zero(d.data()); +template +T* TensorTyped::data() {return d.data();} +template +const T* TensorTyped::data() const {return d.data();} + +template +TensorTyped::TensorTyped() { + LoopUnroller::_zero(d.data()); } -template -TensorGeneric::TensorGeneric(const VectorGeneric&v1,const VectorGeneric&v2) { - for(unsigned i=0; i +void external_rec(T*const out,const T*const v1, const T*const v2){ + if constexpr (j>0) { + external_rec(out,v1,v2); + } else if constexpr (i>0) { + external_rec(out,v1,v2); + } + out[i*m+j]=v1[i]*v2[j]; +} +template +std::array externaProd(const VectorGeneric&v1,const VectorGeneric&v2){ +std::array toRet; +external_rec(toRet.data(),v1.data(),v2.data()); +return toRet; } +template +TensorGeneric::TensorGeneric(const VectorGeneric&v1,const VectorGeneric&v2) +:d(externaProd(v1,v2)) {} +*/ -template -void TensorGeneric::zero() { - LoopUnroller::_zero(d.data()); +template +TensorTyped::TensorTyped(const VectorTyped&v1,const VectorTyped&v2) { + for(unsigned i=0; i -double & TensorGeneric::operator() (unsigned i,unsigned j) { +template +void TensorTyped::zero() { + LoopUnroller::_zero(d.data()); +} + +template +T & TensorTyped::operator() (unsigned i,unsigned j) { #ifdef _GLIBCXX_DEBUG // index i is implicitly checked by the std::array class plumed_assert(j::operator() (unsigned i,unsigned j) { return d[m*i+j]; } -template -const double & TensorGeneric::operator() (unsigned i,unsigned j)const { +template +const T & TensorTyped::operator() (unsigned i,unsigned j)const { #ifdef _GLIBCXX_DEBUG // index i is implicitly checked by the std::array class plumed_assert(j::operator() (unsigned i,unsigned j)const { return d[m*i+j]; } -template -TensorGeneric& TensorGeneric::operator +=(const TensorGeneric& b) { - LoopUnroller::_add(d.data(),b.d.data()); +template +TensorTyped& TensorTyped::operator +=(const TensorTyped& b) { + LoopUnroller::_add(d.data(),b.d.data()); return *this; } -template -TensorGeneric& TensorGeneric::operator -=(const TensorGeneric& b) { - LoopUnroller::_sub(d.data(),b.d.data()); +template +TensorTyped& TensorTyped::operator -=(const TensorTyped& b) { + LoopUnroller::_sub(d.data(),b.d.data()); return *this; } -template -TensorGeneric& TensorGeneric::operator *=(double s) { - LoopUnroller::_mul(d.data(),s); +template +TensorTyped& TensorTyped::operator *=(T s) { + LoopUnroller::_mul(d.data(),s); return *this; } -template -TensorGeneric& TensorGeneric::operator /=(double s) { - LoopUnroller::_mul(d.data(),1.0/s); +template +TensorTyped& TensorTyped::operator /=(T s) { + LoopUnroller::_mul(d.data(),1.0/s); return *this; } -template -TensorGeneric TensorGeneric::operator+()const { +template +TensorTyped TensorTyped::operator+()const { return *this; } -template -TensorGeneric TensorGeneric::operator-()const { - TensorGeneric r; - LoopUnroller::_neg(r.d.data(),d.data()); +template +TensorTyped TensorTyped::operator-()const { + TensorTyped r; + LoopUnroller::_neg(r.d.data(),d.data()); return r; } -template -TensorGeneric& TensorGeneric::setCol(unsigned j,const VectorGeneric & c) { +template +TensorTyped& TensorTyped::setCol(unsigned j,const VectorTyped & c) { for(unsigned i=0; i -TensorGeneric& TensorGeneric::setRow(unsigned i,const VectorGeneric & r) { +template +TensorTyped& TensorTyped::setRow(unsigned i,const VectorTyped & r) { for(unsigned j=0; j -VectorGeneric TensorGeneric::getCol(unsigned j)const { - VectorGeneric v; +template +VectorTyped TensorTyped::getCol(unsigned j)const { + VectorTyped v; for(unsigned i=0; i -VectorGeneric TensorGeneric::getRow(unsigned i)const { - VectorGeneric v; +template +VectorTyped TensorTyped::getRow(unsigned i)const { + VectorTyped v; for(unsigned j=0; j -TensorGeneric operator+(const TensorGeneric&t1,const TensorGeneric&t2) { - TensorGeneric t(t1); +template +TensorTyped operator+(const TensorTyped&t1,const TensorTyped&t2) { + TensorTyped t(t1); t+=t2; return t; } -template -TensorGeneric operator-(const TensorGeneric&t1,const TensorGeneric&t2) { - TensorGeneric t(t1); +template +TensorTyped operator-(const TensorTyped&t1,const TensorTyped&t2) { + TensorTyped t(t1); t-=t2; return t; } -template -TensorGeneric operator*(const TensorGeneric&t1,double s) { - TensorGeneric t(t1); +template +TensorTyped operator*(const TensorTyped&t1,J s) { + TensorTyped t(t1); t*=s; return t; } -template -TensorGeneric operator*(double s,const TensorGeneric&t1) { +template +TensorTyped operator*(J s,const TensorTyped&t1) { return t1*s; } -template -TensorGeneric operator/(const TensorGeneric&t1,double s) { - return t1*(1.0/s); +template +TensorTyped operator/(const TensorTyped&t1,J s) { + return t1*(T(1.0)/s); } -template<> +template inline -double TensorGeneric<3,3>::determinant()const { +T TensorTyped::determinant()const { + static_assert(n==3&&m==3,"determinanat can be called only for 3x3 Tensors"); return d[0]*d[4]*d[8] + d[1]*d[5]*d[6] @@ -364,120 +341,136 @@ double TensorGeneric<3,3>::determinant()const { - d[2]*d[4]*d[6]; } -template +//consider to make this a constexpr function +template inline -TensorGeneric TensorGeneric::identity() { - TensorGeneric t; +TensorTyped TensorTyped::identity() { + TensorTyped t; for(unsigned i=0; i -TensorGeneric TensorGeneric::transpose()const { - TensorGeneric t; +template +TensorTyped TensorTyped::transpose()const { + TensorTyped t; for(unsigned i=0; i +template inline -TensorGeneric<3,3> TensorGeneric<3,3>::inverse()const { - TensorGeneric t; - double invdet=1.0/determinant(); +TensorTyped TensorTyped::inverse()const { + static_assert(n==3&&m==3,"inverse can be called only for 3x3 Tensors"); + TensorTyped t; + T invdet=1.0/determinant(); for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) t(j,i)=invdet*( (*this)((i+1)%3,(j+1)%3)*(*this)((i+2)%3,(j+2)%3) -(*this)((i+1)%3,(j+2)%3)*(*this)((i+2)%3,(j+1)%3)); return t; } -template -TensorGeneric matmul(const TensorGeneric&a,const TensorGeneric&b) { - TensorGeneric t; +/// matrix-matrix multiplication +template +TensorTyped matmul(const TensorTyped&a,const TensorTyped&b) { + TensorTyped t; for(unsigned i=0; i -VectorGeneric matmul(const TensorGeneric&a,const VectorGeneric&b) { - VectorGeneric t; +/// matrix-vector multiplication +template +VectorTyped matmul(const TensorTyped&a,const VectorTyped&b) { + VectorTyped t; for(unsigned i=0; i -VectorGeneric matmul(const VectorGeneric&a,const TensorGeneric&b) { - VectorGeneric t; +/// vector-matrix multiplication +template +VectorTyped matmul(const VectorTyped&a,const TensorTyped&b) { + VectorTyped t; for(unsigned i=0; i -double matmul(const VectorGeneric&a,const VectorGeneric&b) { +/// vector-vector multiplication (maps to dotProduct) +template +T matmul(const VectorTyped&a,const VectorTyped&b) { return dotProduct(a,b); } -template -TensorGeneric matmul(const TensorGeneric&a,const TensorGeneric&b,const TensorGeneric&c) { +/// matrix-matrix-matrix multiplication +template +TensorTyped matmul(const TensorTyped&a,const TensorTyped&b,const TensorTyped&c) { return matmul(matmul(a,b),c); } -template -VectorGeneric matmul(const TensorGeneric&a,const TensorGeneric&b,const VectorGeneric&c) { +/// matrix-matrix-vector multiplication +template +VectorTyped matmul(const TensorTyped&a,const TensorTyped&b,const VectorTyped&c) { return matmul(matmul(a,b),c); } -template -VectorGeneric matmul(const VectorGeneric&a,const TensorGeneric&b,const TensorGeneric&c) { +/// vector-matrix-matrix multiplication +template +VectorTyped matmul(const VectorTyped&a,const TensorTyped&b,const TensorTyped&c) { return matmul(matmul(a,b),c); } -template -double matmul(const VectorGeneric&a,const TensorGeneric&b,const VectorGeneric&c) { +/// vector-matrix-vector multiplication +template +T matmul(const VectorTyped&a,const TensorTyped&b,const VectorTyped&c) { return matmul(matmul(a,b),c); } +template inline -double determinant(const TensorGeneric<3,3>&t) { +T determinant(const TensorTyped&t) { return t.determinant(); } +template inline -TensorGeneric<3,3> inverse(const TensorGeneric<3,3>&t) { +TensorTyped inverse(const TensorTyped&t) { return t.inverse(); } -template -TensorGeneric transpose(const TensorGeneric&t) { +/// returns the transpose of a tensor (same as TensorGeneric::transpose()) +template +TensorTyped transpose(const TensorTyped&t) { return t.transpose(); } -template -TensorGeneric extProduct(const VectorGeneric&v1,const VectorGeneric&v2) { - return TensorGeneric(v1,v2); +/// returns the transpose of a tensor (same as TensorGeneric(const VectorGeneric&,const VectorGeneric&)) +template +TensorTyped extProduct(const VectorTyped&v1,const VectorTyped&v2) { + return TensorTyped(v1,v2); } +template inline -TensorGeneric<3,3> dcrossDv1(const VectorGeneric<3>&v1,const VectorGeneric<3>&v2) { +TensorTyped dcrossDv1(const VectorTyped&v1,const VectorTyped&v2) { (void) v1; // this is to avoid warnings. still the syntax of this function is a bit dummy... - return TensorGeneric<3,3>( - 0.0, v2[2],-v2[1], - -v2[2], 0.0, v2[0], - v2[1],-v2[0], 0.0); + return TensorTyped( + T(0.0), v2[2], -v2[1], + -v2[2], T(0.0), v2[0], + v2[1], -v2[0], T(0.0)); } +template inline -TensorGeneric<3,3> dcrossDv2(const VectorGeneric<3>&v1,const VectorGeneric<3>&v2) { +TensorTyped dcrossDv2(const VectorTyped&v1,const VectorTyped&v2) { (void) v2; // this is to avoid warnings. still the syntax of this function is a bit dummy... - return TensorGeneric<3,3>( - 0.0,-v1[2],v1[1], - v1[2],0.0,-v1[0], - -v1[1],v1[0],0.0); + return TensorTyped( + T(0.0),-v1[2], v1[1], + v1[2], T(0.0),-v1[0], + -v1[1],v1[0], T(0.0)); } -template -std::ostream & operator<<(std::ostream &os, const TensorGeneric& t) { +template +std::ostream & operator<<(std::ostream &os, const TensorTyped& t) { for(unsigned i=0; i& t) { return os; } +template +using TensorGeneric=TensorTyped; + /// \ingroup TOOLBOX typedef TensorGeneric<1,1> Tensor1d; /// \ingroup TOOLBOX @@ -498,33 +494,40 @@ typedef TensorGeneric<5,5> Tensor5d; /// \ingroup TOOLBOX typedef Tensor3d Tensor; +template inline -TensorGeneric<3,3> VcrossTensor(const VectorGeneric<3>&v1,const TensorGeneric<3,3>&v2) { - - TensorGeneric<3,3> t; +TensorTyped VcrossTensor(const VectorTyped&v1,const TensorTyped&v2) { + TensorTyped t; for(unsigned i=0; i<3; i++) { t.setRow(i,matmul(dcrossDv2(v1,v1),v2.getRow(i))); } return t; } +template inline -TensorGeneric<3,3> VcrossTensor(const TensorGeneric<3,3>&v2,const VectorGeneric<3>&v1) { - TensorGeneric<3,3> t; +TensorTyped VcrossTensor(const TensorTyped&v2,const VectorTyped&v1) { + TensorTyped t; for(unsigned i=0; i<3; i++) { t.setRow(i,-matmul(dcrossDv2(v1,v1),v2.getRow(i))); } return t; } - +template inline -TensorGeneric<3,3> deriNorm(const VectorGeneric<3>&v1,const TensorGeneric<3,3>&v2) { +TensorTyped deriNorm(const VectorTyped&v1,const TensorTyped&v2) { // delta(v) = delta(v1/v1.norm) = 1/v1.norm*(delta(v1) - (v.delta(v1))cross v; - double over_norm = 1./v1.modulo(); + T over_norm = 1./v1.modulo(); return over_norm*(v2 - over_norm*over_norm*(extProduct(matmul(v2,v1),v1))); } +/// Diagonalize tensor. +/// Syntax is the same as Matrix::diagMat. +/// In addition, it is possible to call if with m_ smaller than n_. In this case, +/// only the first (smaller) m_ eigenvalues and eigenvectors are retrieved. +/// If case lapack fails (info!=0) it throws an exception. +/// Notice that tensor is assumed to be symmetric!!! template void diagMatSym(const TensorGeneric&mat,VectorGeneric&evals,TensorGeneric&evec) { // some guess number to make sure work is large enough. @@ -547,8 +550,8 @@ void diagMatSym(const TensorGeneric&mat,VectorGeneric&evals,TensorGeneri int info=0; // result int liwork=iwork.size(); int lwork=work.size(); - TensorGenericAux::local_dsyevr("V", (n==m?"A":"I"), "U", &nn, const_cast(&mat_copy[0][0]), &nn, &vl, &vu, &one, &mm, - &abstol, &mout, &evals_tmp[0], &evec[0][0], &nn, + TensorGenericAux::local_dsyevr("V", (n==m?"A":"I"), "U", &nn, mat_copy.data(), &nn, &vl, &vu, &one, &mm, + &abstol, &mout, evals_tmp.data(), evec.data(), &nn, isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info); if(info!=0) plumed_error()<<"Error diagonalizing matrix\n" <<"Matrix:\n"<&mat,VectorGeneric&evals,TensorGeneri static_assert(sizeof(Tensor)==9*sizeof(double), "code cannot work if this is not satisfied"); -} +} //PLMD -#endif //__PLUMED_tools_Tensor_h +#endif diff --git a/src/tools/Tools.h b/src/tools/Tools.h index fee3059035..1b3cc78ebc 100644 --- a/src/tools/Tools.h +++ b/src/tools/Tools.h @@ -245,14 +245,14 @@ class Tools { static void set_to_zero(std::vector> & vec) { unsigned s=vec.size(); if(s==0) return; - set_to_zero(&vec[0][0],s*n); + set_to_zero(vec[0].data(),s*n); } - template - static void set_to_zero(std::vector> & vec) { + template + static void set_to_zero(std::vector> & vec) { unsigned s=vec.size(); if(s==0) return; - set_to_zero(&vec[0](0,0),s*n*m); + set_to_zero(vec[0].data(),s*n*m); } static std::unique_ptr> molfile_lock(); diff --git a/src/tools/Vector.h b/src/tools/Vector.h index 1a108ef25f..e79cff0751 100644 --- a/src/tools/Vector.h +++ b/src/tools/Vector.h @@ -74,6 +74,14 @@ int main(){ */ template class VectorTyped; + +template +VectorTyped delta(const VectorTyped&,const VectorTyped&); + +template +T dotProduct(const VectorTyped&,const VectorTyped&); + + template std::ostream & operator<<(std::ostream &os, const VectorTyped& v); template @@ -134,11 +142,9 @@ class VectorTyped { template friend VectorTyped operator/(const VectorTyped&,J); /// return v2-v1 - template - friend VectorTyped delta(const VectorTyped&v1,const VectorTyped&v2); + friend VectorTyped delta<>(const VectorTyped&v1,const VectorTyped&v2); /// return v1 .scalar. v2 - template - friend U dotProduct(const VectorTyped&,const VectorTyped&); + friend T 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 @@ -275,7 +281,7 @@ VectorTyped operator*(VectorTyped v,J s) { template VectorTyped operator/(const VectorTyped&v,J s) { - return v*(1.0/s); + return v*(T(1.0)/s); } template