diff --git a/vec.cc b/vec.cc index 6b34ca8..fd2f79e 100644 --- a/vec.cc +++ b/vec.cc @@ -486,6 +486,7 @@ void NRVec::gemv(const double beta, const NRMat &A, const char trans, const double alpha, const NRVec &x) { #ifdef DEBUG if((tolower(trans) == 'n'?A.ncols():A.nrows()) != x.size()){ laerror("incompatible vectors"); } + if((tolower(trans) == 'n'?A.nrows():A.ncols()) != nn){ laerror("incompatible result vector in gemv"); } #endif SAME_LOC3(*this, x, A); copyonwrite(); @@ -517,6 +518,7 @@ void NRVec >::gemv(const double beta, const NRMat & const char trans, const double alpha, const NRVec > &x) { #ifdef DEBUG if ((tolower(trans) == 'n'?A.ncols():A.nrows()) != x.size()){ laerror("incompatible vectors"); } + if((tolower(trans) == 'n'?A.nrows():A.ncols()) != nn){ laerror("incompatible result vector in gemv"); } #endif SAME_LOC3(*this, x, A); copyonwrite(); @@ -556,6 +558,7 @@ void NRVec >::gemv(const std::complex beta, const std::complex alpha, const NRVec > &x) { #ifdef DEBUG if ((tolower(trans) == 'n'?A.ncols():A.nrows()) != x.size()){ laerror("incompatible vectors"); } + if((tolower(trans) == 'n'?A.nrows():A.ncols()) != nn){ laerror("incompatible result vector in gemv"); } #endif SAME_LOC3(*this, x, A); copyonwrite(); @@ -593,6 +596,7 @@ void NRVec::gemv(const double beta, const NRSMat &A, const char trans, const double alpha, const NRVec &x) { #ifdef DEBUG if(A.ncols() != x.size()){ laerror("incompatible dimensions"); } + if(A.nrows() != nn){ laerror("incompatible result vector in gemv"); } #endif SAME_LOC3(*this, A, x); copyonwrite(); @@ -625,6 +629,7 @@ void NRVec >::gemv(const double beta, const NRSMat const char trans, const double alpha, const NRVec > &x) { #ifdef DEBUG if(A.ncols() != x.size()){ laerror("incompatible dimensions"); } + if(A.nrows() != nn){ laerror("incompatible result vector in gemv"); } #endif SAME_LOC3(*this, A, x); copyonwrite(); @@ -661,6 +666,7 @@ void NRVec >::gemv(const std::complex beta, const std::complex alpha, const NRVec > &x){ #ifdef DEBUG if(A.ncols() != x.size()) laerror("incompatible dimensions"); + if(A.nrows() != nn){ laerror("incompatible result vector in gemv"); } #endif SAME_LOC3(*this, A, x); copyonwrite(); @@ -883,7 +889,7 @@ copyonwrite(); template NRVec& NRVec::negateconjugateme() { -if(!LA_traits::is_complex()) negateme(); +if(!LA_traits::is_complex()) return negateme(); copyonwrite(); #ifdef CUDALA if(location != cpu) laerror("general conjugation only on CPU"); diff --git a/vec.h b/vec.h index 3d3b71c..f783223 100644 --- a/vec.h +++ b/vec.h @@ -72,6 +72,18 @@ template \ inline const NR##E operator X(const T &a, const NR##E &rhs) \ { return NR##E(rhs) X##= a; } +/***************************************************************************//** + * the same for noncommutative -,/: only X - a, X / a are generated, + * a - X, a / X are deliberately not available (write -X + a explicitly) + ******************************************************************************/ +#define NRVECMAT_OPER_NONCOMMUTATIVE(E,X) \ +template \ + inline const NR##E NR##E::operator X(const T &a) const \ +{ return NR##E(*this) X##= a; } \ + \ + template \ + const NR##E operator X(const T &a, const NR##E &rhs) = delete; + #define NRVECMAT_OPER2(E,X) \ template \ inline const NR##E NR##E::operator X(const NR##E &a) const \ @@ -261,7 +273,7 @@ public: NRVec concatscaled(const NRVec &rhs, const T alpha=1) const { - if(nn==0) return rhs; + if(nn==0) return alpha==(T)1 ? rhs : rhs*alpha; if(rhs.nn==0) return *this; NRVec r(nn+rhs.nn); for(int i=0; i NRVec::unitvector() const { * generate operators involving vector and scalar ******************************************************************************/ NRVECMAT_OPER(Vec,+) -NRVECMAT_OPER(Vec,-) +NRVECMAT_OPER_NONCOMMUTATIVE(Vec,-) NRVECMAT_OPER(Vec,*) -NRVECMAT_OPER(Vec,/) +NRVECMAT_OPER_NONCOMMUTATIVE(Vec,/) /***************************************************************************//** * generate operators involving vector and vector @@ -1960,6 +1974,7 @@ inline const double NRVec< std::complex >::norm(int length, int offset, ******************************************************************************/ template<> inline const double NRVec::amax() const { + if(nn==0) laerror("amax of an empty vector"); double ret(0.0); #ifdef CUDALA if(location == cpu){ @@ -1978,6 +1993,7 @@ inline const double NRVec::amax() const { template<> inline int NRVec::iamax() const { + if(nn==0) laerror("iamax of an empty vector"); int ret; #ifdef CUDALA if(location == cpu){ @@ -1999,14 +2015,16 @@ inline int NRVec::iamax() const { ******************************************************************************/ template<> inline const double NRVec::amin() const { - double ret(std::numeric_limits::max()); + if(nn==0) laerror("amin of an empty vector"); + double ret(0.0); #ifdef CUDALA if(location == cpu){ #endif //BLAS routine idamin seems no to be supported double val(0.0); - int index(-1); - for(register int i = 0; i < nn; i++){ + int index(0); + ret = std::abs(v[0]); + for(register int i = 1; i < nn; i++){ val = std::abs(v[i]); if(val < ret){ index = i; ret = val; } } @@ -2028,6 +2046,7 @@ inline const double NRVec::amin() const { ******************************************************************************/ template<> inline const std::complex NRVec >::amax() const { + if(nn==0) laerror("amax of an empty vector"); std::complex ret(0., 0.); #ifdef CUDALA if(location == cpu){ @@ -2045,6 +2064,7 @@ inline const std::complex NRVec >::amax() const { template<> inline int NRVec >::iamax() const { + if(nn==0) laerror("iamax of an empty vector"); int ret; #ifdef CUDALA if(location == cpu){ @@ -2067,6 +2087,7 @@ inline int NRVec >::iamax() const { ******************************************************************************/ template<> inline const std::complex NRVec >::amin() const { + if(nn==0) laerror("amin of an empty vector"); std::complex ret(0., 0.); #ifdef CUDALA if(location == cpu){