bugfixes in vec.h, vec.cc

This commit is contained in:
jiri committed 2026-10-27 16:32:53 +01:00
1 parent 8b55c3d0c1
commit 37f790c20a
2 files changed
+35 -8

No files matched your search

+7 -1
View File
@@ -486,6 +486,7 @@ void NRVec<double>::gemv(const double beta, const NRMat<double> &A,
const char trans, const double alpha, const NRVec &x) { const char trans, const double alpha, const NRVec &x) {
#ifdef DEBUG #ifdef DEBUG
if((tolower(trans) == 'n'?A.ncols():A.nrows()) != x.size()){ laerror("incompatible vectors"); } 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 #endif
SAME_LOC3(*this, x, A); SAME_LOC3(*this, x, A);
copyonwrite(); copyonwrite();
@@ -517,6 +518,7 @@ void NRVec<std::complex<double> >::gemv(const double beta, const NRMat<double> &
const char trans, const double alpha, const NRVec<std::complex<double> > &x) { const char trans, const double alpha, const NRVec<std::complex<double> > &x) {
#ifdef DEBUG #ifdef DEBUG
if ((tolower(trans) == 'n'?A.ncols():A.nrows()) != x.size()){ laerror("incompatible vectors"); } 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 #endif
SAME_LOC3(*this, x, A); SAME_LOC3(*this, x, A);
copyonwrite(); copyonwrite();
@@ -556,6 +558,7 @@ void NRVec<std::complex<double> >::gemv(const std::complex<double> beta,
const std::complex<double> alpha, const NRVec<std::complex<double> > &x) { const std::complex<double> alpha, const NRVec<std::complex<double> > &x) {
#ifdef DEBUG #ifdef DEBUG
if ((tolower(trans) == 'n'?A.ncols():A.nrows()) != x.size()){ laerror("incompatible vectors"); } 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 #endif
SAME_LOC3(*this, x, A); SAME_LOC3(*this, x, A);
copyonwrite(); copyonwrite();
@@ -593,6 +596,7 @@ void NRVec<double>::gemv(const double beta, const NRSMat<double> &A,
const char trans, const double alpha, const NRVec &x) { const char trans, const double alpha, const NRVec &x) {
#ifdef DEBUG #ifdef DEBUG
if(A.ncols() != x.size()){ laerror("incompatible dimensions"); } if(A.ncols() != x.size()){ laerror("incompatible dimensions"); }
if(A.nrows() != nn){ laerror("incompatible result vector in gemv"); }
#endif #endif
SAME_LOC3(*this, A, x); SAME_LOC3(*this, A, x);
copyonwrite(); copyonwrite();
@@ -625,6 +629,7 @@ void NRVec<std::complex<double> >::gemv(const double beta, const NRSMat<double>
const char trans, const double alpha, const NRVec<std::complex<double> > &x) { const char trans, const double alpha, const NRVec<std::complex<double> > &x) {
#ifdef DEBUG #ifdef DEBUG
if(A.ncols() != x.size()){ laerror("incompatible dimensions"); } if(A.ncols() != x.size()){ laerror("incompatible dimensions"); }
if(A.nrows() != nn){ laerror("incompatible result vector in gemv"); }
#endif #endif
SAME_LOC3(*this, A, x); SAME_LOC3(*this, A, x);
copyonwrite(); copyonwrite();
@@ -661,6 +666,7 @@ void NRVec<std::complex<double> >::gemv(const std::complex<double> beta,
const std::complex<double> alpha, const NRVec<std::complex<double> > &x){ const std::complex<double> alpha, const NRVec<std::complex<double> > &x){
#ifdef DEBUG #ifdef DEBUG
if(A.ncols() != x.size()) laerror("incompatible dimensions"); if(A.ncols() != x.size()) laerror("incompatible dimensions");
if(A.nrows() != nn){ laerror("incompatible result vector in gemv"); }
#endif #endif
SAME_LOC3(*this, A, x); SAME_LOC3(*this, A, x);
copyonwrite(); copyonwrite();
@@ -883,7 +889,7 @@ copyonwrite();
template<typename T> template<typename T>
NRVec<T>& NRVec<T>::negateconjugateme() { NRVec<T>& NRVec<T>::negateconjugateme() {
if(!LA_traits<T>::is_complex()) negateme(); if(!LA_traits<T>::is_complex()) return negateme();
copyonwrite(); copyonwrite();
#ifdef CUDALA #ifdef CUDALA
if(location != cpu) laerror("general conjugation only on CPU"); if(location != cpu) laerror("general conjugation only on CPU");
+28 -7
View File
@@ -72,6 +72,18 @@ template<class T> \
inline const NR##E<T> operator X(const T &a, const NR##E<T> &rhs) \ inline const NR##E<T> operator X(const T &a, const NR##E<T> &rhs) \
{ return NR##E<T>(rhs) X##= a; } { return NR##E<T>(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<class T> \
inline const NR##E<T> NR##E<T>::operator X(const T &a) const \
{ return NR##E(*this) X##= a; } \
\
template<class T> \
const NR##E<T> operator X(const T &a, const NR##E<T> &rhs) = delete;
#define NRVECMAT_OPER2(E,X) \ #define NRVECMAT_OPER2(E,X) \
template<class T> \ template<class T> \
inline const NR##E<T> NR##E<T>::operator X(const NR##E<T> &a) const \ inline const NR##E<T> NR##E<T>::operator X(const NR##E<T> &a) const \
@@ -261,7 +273,7 @@ public:
NRVec concatscaled(const NRVec &rhs, const T alpha=1) const 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; if(rhs.nn==0) return *this;
NRVec r(nn+rhs.nn); NRVec r(nn+rhs.nn);
for(int i=0; i<nn; ++i) r[i] = (*this)[i]; for(int i=0; i<nn; ++i) r[i] = (*this)[i];
@@ -377,7 +389,8 @@ public:
//! compute the sum of squares the vector elements //! compute the sum of squares the vector elements
inline const T sumsqr() const { inline const T sumsqr() const {
T sum(v[0]); if(nn==0) return (T)0;
T sum(v[0]*v[0]);
for(register int i=1; i<nn; i++){ sum += v[i]*v[i];} for(register int i=1; i<nn; i++){ sum += v[i]*v[i];}
return sum; return sum;
}; };
@@ -385,6 +398,7 @@ public:
//! compute the product of the vector elements //! compute the product of the vector elements
inline const T prod() const { inline const T prod() const {
if(nn==0) return (T)1; //empty product
T prod(v[0]); T prod(v[0]);
for(register int i=1; i<nn; i++){ prod *= v[i];} for(register int i=1; i<nn; i++){ prod *= v[i];}
return prod; return prod;
@@ -1215,9 +1229,9 @@ inline const NRVec<T> NRVec<T>::unitvector() const {
* generate operators involving vector and scalar * generate operators involving vector and scalar
******************************************************************************/ ******************************************************************************/
NRVECMAT_OPER(Vec,+) NRVECMAT_OPER(Vec,+)
NRVECMAT_OPER(Vec,-) NRVECMAT_OPER_NONCOMMUTATIVE(Vec,-)
NRVECMAT_OPER(Vec,*) NRVECMAT_OPER(Vec,*)
NRVECMAT_OPER(Vec,/) NRVECMAT_OPER_NONCOMMUTATIVE(Vec,/)
/***************************************************************************//** /***************************************************************************//**
* generate operators involving vector and vector * generate operators involving vector and vector
@@ -1960,6 +1974,7 @@ inline const double NRVec< std::complex<double> >::norm(int length, int offset,
******************************************************************************/ ******************************************************************************/
template<> template<>
inline const double NRVec<double>::amax() const { inline const double NRVec<double>::amax() const {
if(nn==0) laerror("amax of an empty vector");
double ret(0.0); double ret(0.0);
#ifdef CUDALA #ifdef CUDALA
if(location == cpu){ if(location == cpu){
@@ -1978,6 +1993,7 @@ inline const double NRVec<double>::amax() const {
template<> template<>
inline int NRVec<double>::iamax() const { inline int NRVec<double>::iamax() const {
if(nn==0) laerror("iamax of an empty vector");
int ret; int ret;
#ifdef CUDALA #ifdef CUDALA
if(location == cpu){ if(location == cpu){
@@ -1999,14 +2015,16 @@ inline int NRVec<double>::iamax() const {
******************************************************************************/ ******************************************************************************/
template<> template<>
inline const double NRVec<double>::amin() const { inline const double NRVec<double>::amin() const {
double ret(std::numeric_limits<double>::max()); if(nn==0) laerror("amin of an empty vector");
double ret(0.0);
#ifdef CUDALA #ifdef CUDALA
if(location == cpu){ if(location == cpu){
#endif #endif
//BLAS routine idamin seems no to be supported //BLAS routine idamin seems no to be supported
double val(0.0); double val(0.0);
int index(-1); int index(0);
for(register int i = 0; i < nn; i++){ ret = std::abs(v[0]);
for(register int i = 1; i < nn; i++){
val = std::abs(v[i]); val = std::abs(v[i]);
if(val < ret){ index = i; ret = val; } if(val < ret){ index = i; ret = val; }
} }
@@ -2028,6 +2046,7 @@ inline const double NRVec<double>::amin() const {
******************************************************************************/ ******************************************************************************/
template<> template<>
inline const std::complex<double> NRVec<std::complex<double> >::amax() const { inline const std::complex<double> NRVec<std::complex<double> >::amax() const {
if(nn==0) laerror("amax of an empty vector");
std::complex<double> ret(0., 0.); std::complex<double> ret(0., 0.);
#ifdef CUDALA #ifdef CUDALA
if(location == cpu){ if(location == cpu){
@@ -2045,6 +2064,7 @@ inline const std::complex<double> NRVec<std::complex<double> >::amax() const {
template<> template<>
inline int NRVec<std::complex<double> >::iamax() const { inline int NRVec<std::complex<double> >::iamax() const {
if(nn==0) laerror("iamax of an empty vector");
int ret; int ret;
#ifdef CUDALA #ifdef CUDALA
if(location == cpu){ if(location == cpu){
@@ -2067,6 +2087,7 @@ inline int NRVec<std::complex<double> >::iamax() const {
******************************************************************************/ ******************************************************************************/
template<> template<>
inline const std::complex<double> NRVec<std::complex<double> >::amin() const { inline const std::complex<double> NRVec<std::complex<double> >::amin() const {
if(nn==0) laerror("amin of an empty vector");
std::complex<double> ret(0., 0.); std::complex<double> ret(0., 0.);
#ifdef CUDALA #ifdef CUDALA
if(location == cpu){ if(location == cpu){