#ifndef VECT_HH #define VECT_HH #include #include #include #include #include #include #include "defs.hh" #include "dist.hh" #include "vect_helpers.hh" using namespace std; #ifdef CARPET_DEBUG # define ASSERT_VECT(x) assert(x) #else # define ASSERT_VECT(x) #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 () { } /** Create a vector from a lower-dimensional vector. */ vect (const vect& x, const T& a) { assert(D>0); for (int d=0; d& x) { assert(D>0); elt[0] = a; for (int d=0; d operator vect,E> () { vect,E> r; for (int e=0; e /*explicit*/ vect (const vect& a) { for (int d=0; d=0 && d=0 && d vect operator[] (const vect& a) const { vect r; // (*this)[] performs index checking for (int d=0; d=0 && d vect ifthen (const vect& a, const vect& b) const { vect r; for (int d=0; d 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 vect& b, const T& c) { return either (a, b, vect(c)); } template inline vect either (const vect& a, const T& b, const vect& c) { return either (a, vect(b), c); } 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) { vect,DD> r; for (int dd=0; dd inline vect ipow (const vect& a, const vect& b) { vect r; for (int d=0; d , > , bool) DECLARE_OPERATOR_2_RET (operator>=, >=, bool) // Reduction operators // Identity #define id(x) (x) DECLARE_REDUCTION_OPERATOR_1_T_RET (all,true ,&=,id,bool,bool) DECLARE_REDUCTION_OPERATOR_1_T_RET (any,false,|=,id,bool,bool) DECLARE_REDUCTION_FUNCTION_1 (maxval,a[0],max,id) DECLARE_REDUCTION_FUNCTION_1 (minval,a[0],min,id) DECLARE_REDUCTION_OPERATOR_1 (prod,1,*=,id) DECLARE_REDUCTION_OPERATOR_1 (sum,0,+=,id) DECLARE_REDUCTION_OPERATOR_2 (dot ,0,+=,*,id ) DECLARE_REDUCTION_OPERATOR_2 (hypot,0,+=,*,sqrt) /** Count the number of true (non-zero) elements in the vector. */ template inline int count (const vect& a) { return sum(ivect(a != T(0))); } /** Return the size (number of elements) of the vector. */ template inline int size (const vect& a) { return D; } /** Return the first element. */ template inline T head (const vect& a) { return a[0]; } /** Return all but the first element. */ template inline vect tail (const vect& a) { vect r; for (int d=0; d inline T last (const vect& a) { return a[D-1]; } /** Return all but the last element. */ template inline vect init (const vect& a) { vect r; for (int d=0; d inline int maxloc (const vect& a) { ASSERT_VECT (D>0); int r(0); for (int d=1; da[r]) r=d; return r; } /** Return the index of the last maximum element. */ template inline int maxloc1 (const vect& a) { ASSERT_VECT (D>0); int r(D-1); for (int d=D-2; d>=0; --d) if (a[d]>a[r]) r=d; return r; } /** Return the index of the first minimum element. */ template inline int minloc (const vect& a) { ASSERT_VECT (D>0); int r(0); for (int d=1; d inline int minloc1 (const vect& a) { ASSERT_VECT (D>0); int r(D-1); for (int d=D-2; d>=0; --d) if (a[d] inline T index (const vect& ash, const vect& ind) { T r(0); for (int d=D-1; d>=0; --d) { ASSERT_VECT (ash[d]>=0); // Be generous, and allow relative indices which may be negtive // ASSERT_VECT (ind[d]>=0 and ind[d] inline vect vmap (U (* const func)(T x), const vect& a); template inline vect vmap (U (* const func)(T x), const vect& a) { vect r; for (int d=0; d inline vect vzip (U (* const func)(S x, T y), const vect& a, const vect& b); template inline vect vzip (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); template 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); template inline U fold1 (U (* const func)(U val, T x), const vect& a) { ASSERT_VECT (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); template 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); template inline vect scan1 (U (* const func)(U val, T x), U val, const vect& a) { vect r; for (int d=0; d inline size_t memoryof (vect const & a); template inline size_t memoryof (vect const & a) { return a.memory(); } // Input /** Read a formatted vector from a stream. */ template 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; } // Comparison namespace std { // == template struct equal_to >: binary_function, vect, bool> { bool operator()(const vect& x, const vect& y) const { /*const*/ equal_to T_equal_to; for (int d=0; d struct less >: binary_function, vect, bool> { bool operator()(const vect& x, const vect& y) const { /*const*/ less T_less; for (int d=D-1; d>=0; --d) { if (T_less(x[d], y[d])) return true; if (T_less(y[d], x[d])) return false; } return false; } }; // > template struct greater >: binary_function, vect, bool> { bool operator()(const vect& x, const vect& y) const { return less >()(y, x); } }; // >= template struct greater_equal >: binary_function, vect, bool> { bool operator()(const vect& x, const vect& y) const { return not less >()(x, y); } }; // <= template struct less_equal >: binary_function, vect, bool> { bool operator()(const vect& x, const vect& y) const { return not greater >()(x, y); } }; // != template struct not_equal_to >: binary_function, vect, bool> { bool operator()(const vect& x, const vect& y) const { return not equal_to >()(x, y); } }; } // MPI template inline MPI_Datatype mpi_datatype (vect const & a) { return a.mpi_datatype(); } namespace dist { template<> inline MPI_Datatype mpi_datatype () { ivect dummy; return mpi_datatype(dummy); } } #if 0 // Specialise explicit constructors /** Constructor for 2-element vectors from 2 elements. */ template inline vect::vect (const T& x, const T& y); 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); vect (const T& x, const T& y, const T& z) { ASSERT_VECT (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); vect (const T& x, const T& y, const T& z, const T& t) { ASSERT_VECT (D==4); elt[0]=x; elt[1]=y; elt[2]=z; elt[3]=t; } #endif //////////////////////////////////////////////////////////////////////////////// // Specialise some constructors for lower dimensions // These functions are declared, but must not be used. template<> vect::vect (const int& x, const int& y); template<> vect::vect (const int& x, const int& y); template<> vect::vect (const int& x, const int& y); template<> vect::vect (const int& x, const int& y); template<> vect::vect (const int& x, const int& y, const int& z); template<> vect::vect (const int& x, const int& y, const int& z); template<> vect::vect (const int& x, const int& y, const int& z); template<> vect::vect (const int& x, const int& y, const int& z); template<> vect::vect (const int& x, const int& y, const int& z, const int& t); template<> vect::vect (const int& x, const int& y, const int& z, const int& t); template<> vect::vect (const int& x, const int& y, const int& z, const int& t); template<> vect::vect (const int& x, const int& y, const int& z, const int& t); // Specialise for CCTK_REAL template<> inline vect& vect::operator%=(const vect& a) { for (int d=0; da[d]*(CCTK_REAL)(1.0-1.0e-10)) elt[d]=(CCTK_REAL)0; if (elt[d] inline vect operator%(const vect& a, const vect& b) { vect r; for (int d=0; db[d]*(CCTK_REAL)(1.0-1.0e-10)) r[d]=(CCTK_REAL)0; if (r[d] inline vect idiv(const vect& a, const vect& b) { vect r; for (int d=0; db[d]*(CCTK_REAL)(1.0-1.0e-10)) r[d]=(CCTK_REAL)0; if (r[d] inline vect imod(const vect& a, const vect& b) { vect r; for (int d=0; db[d]*(CCTK_REAL)(1.0-1.0e-10)) r[d]=(CCTK_REAL)0; if (r[d]