#ifndef VECT_HH #define VECT_HH #include #include #include #include #include "cctk.h" using namespace std; #if 0 // A pure function returns a value that depends only on the function // arguments and on global variables, and the function has no side // effects. #ifdef HAVE_CCTK_CXX_ATTRIBUTE_PURE # define PURE __attribute__((pure)) #else # define PURE #endif // A const function returns a value that depends only on the function // arguments, and the function has no side effects. This is even more // strict than pure functions. Const functions cannot dereference // pointers or references (or this). #ifdef HAVE_CCTK_CXX_ATTRIBUTE_CONST # define CONST __attribute__((const)) #else # define CONST #endif #else // Don't take any risks # define PURE # define CONST #endif // Forward definition template class vect; // Input/Output template istream& operator>> (istream& is, vect& a); template ostream& operator<< (ostream& os, const vect& a); /** * A short vector with a size that is specified at compile time. */ template class vect { // Fields /** Vector elements. */ T elt[D==0 ? 1 : D]; public: // Constructors /** Explicit empty constructor. */ explicit vect () CONST { } /** Copy constructor. */ vect (const vect& a) PURE { for (int d=0; d /*explicit*/ vect (const vect& a) /*PURE*/ { for (int d=0; d=0 && d=0 && d vect operator[] (const vect& a) const /*PURE*/ { vect r; // (*this)[] performs index checking for (int d=0; d=0 && d operator! () const PURE { vect r; for (int d=0; d operator&& (const T& x) const PURE { vect r; for (int d=0; d operator|| (const T& x) const PURE { vect r; for (int d=0; d operator&& (const vect& a) const PURE { vect r; for (int d=0; d operator|| (const vect& a) const PURE { vect r; for (int d=0; d operator== (const vect& a) const PURE { vect r; for (int d=0; d operator!= (const vect& a) const PURE { vect r; for (int d=0; d operator< (const vect& a) const PURE { vect r; for (int d=0; d operator<= (const vect& a) const PURE { vect r; for (int d=0; d operator> (const vect& a) const PURE { vect r; for (int d=0; da[d]; return r; } vect operator>= (const vect& a) const PURE { vect r; for (int d=0; d=a[d]; return r; } #endif /** This corresponds to the ?: operator. Return a vector with the elements set to either a[i] or b[i], depending on whether (*this)[i] is true or not. */ template vect ifthen (const vect& a, const vect& b) const /*PURE*/ { vect r; for (int d=0; d inline vect either (const vect& a, const vect& b, const vect& c) PURE; template inline vect either (const vect& a, const vect& b, const vect& c) { vect r; for (int d=0; d inline vect either (const vect& a, const T& b, const T& c) PURE; template inline vect either (const vect& a, const T& b, const T& c) { return either (a, vect(b), vect(c)); } /** Transpose a vector of a vector */ template inline vect,DD> xpose (vect,D> const & a) PURE; template inline vect,DD> xpose (vect,D> const & a) { vect,DD> r; for (int dd=0; dd inline vect abs (const vect& a) PURE; template inline vect abs (const vect& a) { vect r; for (int d=0; d inline vect ceil (const vect& a) PURE; template inline vect ceil (const vect& a) { vect r; for (int d=0; d inline vect floor (const vect& a) PURE; template inline vect floor (const vect& a) { vect r; for (int d=0; d inline vect max (const vect& a, const vect& b) PURE; template inline vect max (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect min (const vect& a, const vect& b) PURE; template inline vect min (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect pow (const vect& a, const vect& b) PURE; template inline vect pow (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect ipow (const vect& a, const vect& b) PURE; template inline vect ipow (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect operator+ (const vect& a, const T& x) PURE; template inline vect operator+ (const vect& a, const T& x) { vect r(a); r+=x; return r; } template inline vect operator+ (const T& x, const vect& a) PURE; template inline vect operator+ (const T& x, const vect& a) { vect r(x); r+=a; return r; } template inline vect operator- (const vect& a, const T& x) PURE; template inline vect operator- (const vect& a, const T& x) { vect r(a); r-=x; return r; } template inline vect operator- (const T& x, const vect& a) PURE; template inline vect operator- (const T& x, const vect& a) { vect r(x); r-=a; return r; } template inline vect operator* (const vect& a, const T& x) PURE; template inline vect operator* (const vect& a, const T& x) { vect r(a); r*=x; return r; } template inline vect operator* (const T& x, const vect& a) PURE; template inline vect operator* (const T& x, const vect& a) { vect r(x); r*=a; return r; } template inline vect operator/ (const vect& a, const T& x) PURE; template inline vect operator/ (const vect& a, const T& x) { vect r(a); r/=x; return r; } template inline vect operator/ (const T& x, const vect& a) PURE; template inline vect operator/ (const T& x, const vect& a) { vect r(x); r/=a; return r; } template inline vect operator% (const vect& a, const T& x) PURE; template inline vect operator% (const vect& a, const T& x) { vect r(a); r%=x; return r; } template inline vect operator% (const T& x, const vect& a) PURE; template inline vect operator% (const T& x, const vect& a) { vect r(x); r%=a; return r; } template inline vect operator| (const vect& a, const T& x) PURE; template inline vect operator| (const vect& a, const T& x) { vect r(a); r|=x; return r; } template inline vect operator| (const T& x, const vect& a) PURE; template inline vect operator| (const T& x, const vect& a) { vect r(x); r|=a; return r; } template inline vect operator& (const vect& a, const T& x) PURE; template inline vect operator& (const vect& a, const T& x) { vect r(a); r&=x; return r; } template inline vect operator& (const T& x, const vect& a) PURE; template inline vect operator& (const T& x, const vect& a) { vect r(x); r&=a; return r; } template inline vect operator^ (const vect& a, const T& x) PURE; template inline vect operator^ (const vect& a, const T& x) { vect r(a); r^=x; return r; } template inline vect operator^ (const T& x, const vect& a) PURE; template inline vect operator^ (const T& x, const vect& a) { vect r(x); r^=a; return r; } template inline vect operator&& (const vect& a, const T& x) PURE; template inline vect operator&& (const vect& a, const T& x) { vect r; for (int d=0; d inline vect operator&& (const T& x, const vect& a) PURE; template inline vect operator&& (const T& x, const vect& a) { vect r; for (int d=0; d inline vect operator|| (const vect& a, const T& x) PURE; template inline vect operator|| (const vect& a, const T& x) { vect r; for (int d=0; d inline vect operator|| (const T& x, const vect& a) PURE; template inline vect operator|| (const T& x, const vect& a) { vect r; for (int d=0; d inline vect operator== (const vect& a, const T& x) PURE; template inline vect operator== (const vect& a, const T& x) { vect r; for (int d=0; d inline vect operator== (const T& x, const vect& a) PURE; template inline vect operator== (const T& x, const vect& a) { vect r; for (int d=0; d inline vect operator!= (const vect& a, const T& x) PURE; template inline vect operator!= (const vect& a, const T& x) { vect r; for (int d=0; d inline vect operator!= (const T& x, const vect& a) PURE; template inline vect operator!= (const T& x, const vect& a) { vect r; for (int d=0; d inline vect operator< (const vect& a, const T& x) PURE; template inline vect operator< (const vect& a, const T& x) { vect r; for (int d=0; d inline vect operator< (const T& x, const vect& a) PURE; template inline vect operator< (const T& x, const vect& a) { vect r; for (int d=0; d inline vect operator<= (const vect& a, const T& x) PURE; template inline vect operator<= (const vect& a, const T& x) { vect r; for (int d=0; d inline vect operator<= (const T& x, const vect& a) PURE; template inline vect operator<= (const T& x, const vect& a) { vect r; for (int d=0; d inline vect operator> (const vect& a, const T& x) PURE; template inline vect operator> (const vect& a, const T& x) { vect r; for (int d=0; dx; return r; } template inline vect operator> (const T& x, const vect& a) PURE; template inline vect operator> (const T& x, const vect& a) { vect r; for (int d=0; da[d]; return r; } template inline vect operator>= (const vect& a, const T& x) PURE; template inline vect operator>= (const vect& a, const T& x) { vect r; for (int d=0; d=x; return r; } template inline vect operator>= (const T& x, const vect& a) PURE; template inline vect operator>= (const T& x, const vect& a) { vect r; for (int d=0; d=a[d]; return r; } template inline vect operator+ (const vect& a, const vect& b) PURE; template inline vect operator+ (const vect& a, const vect& b) { vect r(a); r+=b; return r; } template inline vect operator- (const vect& a, const vect& b) PURE; template inline vect operator- (const vect& a, const vect& b) { vect r(a); r-=b; return r; } template inline vect operator* (const vect& a, const vect& b) PURE; template inline vect operator* (const vect& a, const vect& b) { vect r(a); r*=b; return r; } template inline vect operator/ (const vect& a, const vect& b) PURE; template inline vect operator/ (const vect& a, const vect& b) { vect r(a); r/=b; return r; } template inline vect operator% (const vect& a, const vect& b) PURE; template inline vect operator% (const vect& a, const vect& b) { vect r(a); r%=b; return r; } template inline vect operator& (const vect& a, const vect& b) PURE; template inline vect operator& (const vect& a, const vect& b) { vect r(a); r&=b; return r; } template inline vect operator| (const vect& a, const vect& b) PURE; template inline vect operator| (const vect& a, const vect& b) { vect r(a); r|=b; return r; } template inline vect operator^ (const vect& a, const vect& b) PURE; template inline vect operator^ (const vect& a, const vect& b) { vect r(a); r^=b; return r; } template inline vect operator&& (const vect& a, const vect& b) PURE; template inline vect operator&& (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect operator|| (const vect& a, const vect& b) PURE; template inline vect operator|| (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect operator== (const vect& a, const vect& b) PURE; template inline vect operator== (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect operator!= (const vect& a, const vect& b) PURE; template inline vect operator!= (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect operator< (const vect& a, const vect& b) PURE; template inline vect operator< (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect operator<= (const vect& a, const vect& b) PURE; template inline vect operator<= (const vect& a, const vect& b) { vect r; for (int d=0; d inline vect operator> (const vect& a, const vect& b) PURE; template inline vect operator> (const vect& a, const vect& b) { vect r; for (int d=0; db[d]; return r; } template inline vect operator>= (const vect& a, const vect& b) PURE; template inline vect operator>= (const vect& a, const vect& b) { vect r; for (int d=0; d=b[d]; return r; } // Reduction operators /** Return true iff any of the elements are true (boolean sum). */ template inline bool any (const vect& a) PURE; template inline bool any (const vect& a) { bool r(false); for (int d=0; d inline bool all (const vect& a) PURE; template inline bool all (const vect& a) { bool r(true); for (int d=0; d inline int count (const vect& a) PURE; template inline int count (const vect& a) { return D; } /** Return the dot product of two vectors. */ template inline T dot (const vect& a, const vect& b) PURE; template inline T dot (const vect& a, const vect& b) { T r(0); for (int d=0; d inline T hypot (const vect& a) PURE; template inline T hypot (const vect& a) { return sqrt(dot(a,a)); } /** Return the maximum element. */ template inline T maxval (const vect& a) PURE; template inline T maxval (const vect& a) { assert (D>0); T r(a[0]); for (int d=1; d inline T minval (const vect& a) PURE; template inline T minval (const vect& a) { assert (D>0); T r(a[0]); for (int d=1; d inline int maxloc (const vect& a) PURE; template inline int maxloc (const vect& a) { assert (D>0); int r(0); for (int d=1; da[r]) r=d; return r; } /** Return the index of the first minimum element. */ template inline int minloc (const vect& a) PURE; template inline int minloc (const vect& a) { assert (D>0); int r(0); for (int d=1; d inline T prod (const vect& a) PURE; template inline T prod (const vect& a) { T r(1); for (int d=0; d inline int size (const vect& a) CONST; template inline int size (const vect& a) { return D; } /** Return the sum of the elements. */ template inline T sum (const vect& a) PURE; template inline T sum (const vect& a) { T r(0); for (int d=0; d inline vect map (U (* const func)(T x), const vect& a) { vect r; for (int d=0; d inline vect zip (U (* const func)(S x, T y), const vect& a, const vect& b) { vect r; for (int d=0; d inline U fold (U (* const func)(U val, T x), U val, const vect& a) { for (int d=0; d inline U fold1 (U (* const func)(U val, T x), const vect& a) { assert (D>=1); U val = a[0]; for (int d=1; d inline vect scan0 (U (* const func)(U val, T x), U val, const vect& a) { vect r; for (int d=0; d inline vect scan1 (U (* const func)(U val, T x), U val, const vect& a) { vect r; for (int d=0; d inline istream& operator>> (istream& is, vect& a) { a.input(is); return is; } // Output /** Write a vector formatted to a stream. */ template inline ostream& operator<< (ostream& os, const vect& a) { a.output(os); return os; } #if 0 // Specialise explicit constructors /** Constructor for 2-element vectors from 2 elements. */ template inline vect::vect (const T& x, const T& y) PURE; template inline vect::vect (const T& x, const T& y) { elt[0]=x; elt[1]=y; } /** Constructor for 3-element vectors from 3 elements. */ vect (const T& x, const T& y, const T& z) PURE; vect (const T& x, const T& y, const T& z) { assert (D==3); elt[0]=x; elt[1]=y; elt[2]=z; } /** Constructor for 4-element vectors from 4 elements. */ vect (const T& x, const T& y, const T& z, const T& t) PURE; vect (const T& x, const T& y, const T& z, const T& t) { assert (D==4); elt[0]=x; elt[1]=y; elt[2]=z; elt[3]=t; } #endif //////////////////////////////////////////////////////////////////////////////// // Special versions for vect template inline vect,E> operator== (const vect,E>& a, const vect,E>& b) PURE; template inline vect,E> operator== (const vect,E>& a, const vect,E>& b) { vect,E> r; for (int e=0; e inline vect all (const vect,E>& a) PURE; template inline vect all (const vect,E>& a) { vect r; for (int e=0; e inline vect::vect (const int& x, const int& y) { assert(0); } template<> inline vect::vect (const int& x, const int& y) { assert(0); } template<> inline vect::vect (const int& x, const int& y, const int& z) { assert(0); } template<> inline vect::vect (const int& x, const int& y, const int& z) { assert(0); } template<> inline vect::vect (const int& x, const int& y, const int& z) { assert(0); } template<> inline vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } template<> inline vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } template<> inline vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } template<> inline vect::vect (const int& x, const int& y, const int& z, const int& t) { assert(0); } // Specialise for CCTK_REAL template<> inline vect& vect::operator%=(const vect& a) { for (int d=0; d<3; ++d) { elt[d]=fmod(elt[d],a[d]); if (elt[d]>a[d]*(CCTK_REAL)(1.0-1.0e-10)) elt[d]=(CCTK_REAL)0; if (elt[d]