// -*- C++ -*- /*************************************************************************** * * The IPPL Framework * * * Visit http://people.web.psi.ch/adelmann/ for more details * ***************************************************************************/ #ifndef VEKTOR_H #define VEKTOR_H // include files #include "Utility/PAssert.h" #include "Message/Message.h" #include "PETE/IpplExpressions.h" #include "AppTypes/TSVMeta.h" #include #include #include ////////////////////////////////////////////////////////////////////// // // Definition of class Vektor. // ////////////////////////////////////////////////////////////////////// template class Vektor { public: typedef T Element_t; enum { ElemDim = 1 }; enum { Size = D }; // Default Constructor initializes to zero. Vektor() { TSV_MetaAssignScalar,T,OpAssign>::apply(*this,T(0)); } // Copy Constructor Vektor(const Vektor &rhs) { TSV_MetaAssign< Vektor , Vektor ,OpAssign >::apply(*this,rhs); } // Templated Vektor constructor. template Vektor(const Vektor &rhs) { for (unsigned d=0; d,T,OpAssign>::apply(*this,x00); } // Constructors for fixed dimension Vektor(const T& x00, const T& x01) { PInsist(D==2, "Number of arguments does not match Vektor dimension!!"); X[0] = x00; X[1] = x01; } Vektor(const T& x00, const T& x01, const T& x02) { PInsist(D==3, "Number of arguments does not match Vektor dimension!!"); X[0] = x00; X[1] = x01; X[2] = x02; } Vektor(const T& x00, const T& x01, const T& x02, const T& x03) { PInsist(D==4, "Number of arguments does not match Vektor dimension!!"); X[0] = x00; X[1] = x01; X[2] = x02; X[3] = x03; } // Destructor ~Vektor() { } // Assignment Operators const Vektor& operator=(const Vektor &rhs) { TSV_MetaAssign< Vektor , Vektor ,OpAssign> :: apply(*this,rhs); return *this; } template const Vektor& operator=(const Vektor &rhs) { TSV_MetaAssign< Vektor , Vektor ,OpAssign> :: apply(*this,rhs); return *this; } const Vektor& operator=(const T& rhs) { TSV_MetaAssignScalar< Vektor , T ,OpAssign > :: apply(*this,rhs); return *this; } // Accumulation Operators template Vektor& operator+=(const Vektor &rhs) { TSV_MetaAssign< Vektor , Vektor , OpAddAssign > :: apply(*this,rhs); return *this; } Vektor& operator+=(const T& rhs) { TSV_MetaAssignScalar< Vektor , T , OpAddAssign > :: apply(*this,rhs); return *this; } template Vektor& operator-=(const Vektor &rhs) { TSV_MetaAssign< Vektor , Vektor , OpSubtractAssign > :: apply(*this,rhs); return *this; } Vektor& operator-=(const T& rhs) { TSV_MetaAssignScalar< Vektor , T , OpSubtractAssign > :: apply(*this,rhs); return *this; } template Vektor& operator*=(const Vektor &rhs) { TSV_MetaAssign< Vektor , Vektor , OpMultipplyAssign > :: apply(*this,rhs); return *this; } Vektor& operator*=(const T& rhs) { TSV_MetaAssignScalar< Vektor , T , OpMultipplyAssign > :: apply(*this,rhs); return *this; } template Vektor& operator/=(const Vektor &rhs) { TSV_MetaAssign< Vektor , Vektor , OpDivideAssign > :: apply(*this,rhs); return *this; } Vektor& operator/=(const T& rhs) { TSV_MetaAssignScalar< Vektor , T , OpDivideAssign > :: apply(*this,rhs); return *this; } // Get and Set Operations Element_t& operator[](unsigned int i); Element_t operator[](unsigned int i) const; Element_t& operator()(unsigned int i); Element_t operator()( unsigned int i) const; // Comparison operators. bool operator==(const Vektor& that) const { return TSV_MetaCompareArrays::apply(X,that.X); } bool operator!=(const Vektor& that) const { return !(*this == that); } //---------------------------------------------------------------------- // parallel communication Message& putMessage(Message& m) const { m.setCopy(true); ::putMessage(m, X, X + D); return m; } Message& getMessage(Message& m) { ::getMessage(m, X, X + D); return m; } private: // Just store D elements of type T. T X[D]; }; template typename Vektor::Element_t& Vektor::operator[](unsigned int i) { PAssert (i typename Vektor::Element_t Vektor::operator[](unsigned int i) const { PAssert (i typename Vektor::Element_t& Vektor::operator()(unsigned int i) { PAssert (i typename Vektor::Element_t Vektor::operator()( unsigned int i) const { PAssert (i inline Vektor operator-(const Vektor &op) { return TSV_MetaUnary< Vektor , OpUnaryMinus > :: apply(op); } //---------------------------------------------------------------------- // unary operator+ template inline const Vektor &operator+(const Vektor &op) { return op; } ////////////////////////////////////////////////////////////////////// // // Binary Operators // ////////////////////////////////////////////////////////////////////// // // Elementwise operators. // TSV_ELEMENTWISE_OPERATOR(Vektor,operator+,OpAdd) TSV_ELEMENTWISE_OPERATOR(Vektor,operator-,OpSubtract) TSV_ELEMENTWISE_OPERATOR(Vektor,operator*,OpMultipply) TSV_ELEMENTWISE_OPERATOR(Vektor,operator/,OpDivide) TSV_ELEMENTWISE_OPERATOR(Vektor,Min,FnMin) TSV_ELEMENTWISE_OPERATOR(Vektor,Max,FnMax) //---------------------------------------------------------------------- // dot product //---------------------------------------------------------------------- template < class T1, class T2, unsigned D > inline typename PETEBinaryReturn::type dot(const Vektor &lhs, const Vektor &rhs) { return TSV_MetaDot< Vektor , Vektor > :: apply(lhs,rhs); } //---------------------------------------------------------------------- // cross product //---------------------------------------------------------------------- template < class T1, class T2, unsigned D > inline Vektor::type,D> cross(const Vektor &lhs, const Vektor &rhs) { return TSV_MetaCross< Vektor , Vektor > :: apply(lhs,rhs); } //---------------------------------------------------------------------- // euclidean norm //---------------------------------------------------------------------- template < class T, unsigned D > inline double euclidean_norm(const Vektor &a) { return std::sqrt(dot(a, a)); } //---------------------------------------------------------------------- // I/O template inline std::ostream& operator<<(std::ostream& out, const Vektor& rhs) { std::streamsize sw = out.width(); out << std::setw(1); if (D >= 1) { out << "( "; for (unsigned int i=0; i