GEL  2
GEL is a library for Geometry and Linear Algebra
/Users/jab/Documents/Teaching/02585/GEL2_and_demos/GEL/src/CGLA/ArithVec.h
00001 #ifndef __CGLA_ARITHVEC_H__
00002 #define __CGLA_ARITHVEC_H__
00003 
00004 #include <iostream>
00005 #include "CGLA.h"
00006 
00007 #include <numeric>
00008 
00009 namespace CGLA 
00010 {
00011 
00033   template <class T, class V, unsigned int N> 
00034     class ArithVec
00035     {
00036 
00037     protected:
00038 
00040       T data[N];
00041 
00042     protected:
00043 
00044       //----------------------------------------------------------------------
00045       // Constructors
00046       //----------------------------------------------------------------------
00047 
00049       ArithVec() 
00050         {
00051         }
00052 
00054       explicit ArithVec(T _a)
00055         {
00056           std::fill_n(data, N, _a);
00057         }
00058 
00060       ArithVec(T _a, T _b)
00061         {
00062           assert(N==2);
00063           data[0] = _a;
00064           data[1] = _b;
00065         }
00066 
00068       ArithVec(T _a, T _b, T _c)
00069         {
00070           assert(N==3);
00071           data[0] = _a;
00072           data[1] = _b;
00073           data[2] = _c;
00074         }
00075 
00077       ArithVec(T _a, T _b, T _c, T _d)
00078         {
00079           assert(N==4);
00080           data[0] = _a;
00081           data[1] = _b;
00082           data[2] = _c;
00083           data[3] = _d;
00084         }
00085 
00086 
00087     public:
00088 
00090       typedef T ScalarType;
00091         
00093       typedef V VectorType;
00094 
00096       static unsigned int get_dim() {return N;}
00097         
00099       void set(T _a, T _b)
00100         {
00101           assert(N==2);
00102           data[0] = _a;
00103           data[1] = _b;
00104         }
00105 
00107       void set(T _a, T _b, T _c)
00108         {
00109           assert(N==3);
00110           data[0] = _a;
00111           data[1] = _b;
00112           data[2] = _c;
00113         }
00114 
00116       void set(T _a, T _b, T _c, T _d)
00117         {
00118           assert(N==4);
00119           data[0] = _a;
00120           data[1] = _b;
00121           data[2] = _c;
00122           data[3] = _d;
00123         }
00124 
00126   const T& operator [] ( unsigned int i ) const
00127         {
00128           assert(i<N);
00129           return data[i];
00130         }
00131 
00133   T& operator [] ( unsigned int i ) 
00134         {
00135           assert(i<N);
00136           return data[i];
00137         }
00138 
00140   const T& operator () ( unsigned int i ) const
00141         {
00142           assert(i<N);
00143           return data[i];
00144         }
00145 
00147   T& operator () ( unsigned int i ) 
00148         {
00149           assert(i<N);
00150           return data[i];
00151         }
00152 
00153 
00157       T* get() {return &data[0];}
00158 
00162       const T* get() const {return &data[0];}
00163 
00164       //----------------------------------------------------------------------
00165       // Comparison operators
00166       //----------------------------------------------------------------------
00167 
00169       bool operator==(const V& v) const 
00170         {
00171           return std::inner_product(data, &data[N], v.get(), true,
00172                                     std::logical_and<bool>(), std::equal_to<T>());
00173         }
00174 
00175 #define for_all_i(expr) for(unsigned int i=0;i<N;i++) {expr;}
00176 
00177       bool operator==(T k) const 
00178         { 
00179           for_all_i(if (data[i] != k) return false)
00180             return true;
00181         }
00182 #undef for_all_i  
00183 
00185       bool operator!=(const V& v) const 
00186         {
00187           return std::inner_product(data, &data[N], v.get(), false,
00188                                     std::logical_or<bool>(), std::not_equal_to<T>());
00189         }
00190 
00192       bool operator!=(T k) const 
00193         { 
00194           return !(*this==k);
00195         }
00196 
00197 
00198       //----------------------------------------------------------------------
00199       // Comparison functions ... of geometric significance 
00200       //----------------------------------------------------------------------
00201 
00204       bool  all_l  (const V& v) const
00205         {
00206           return std::inner_product(data, &data[N], v.get(), true, 
00207                                     std::logical_and<bool>(), std::less<T>());
00208         }
00209 
00212       bool  all_le (const V& v) const
00213         {
00214           return std::inner_product(data, &data[N], v.get(), true, 
00215                                     std::logical_and<bool>(), std::less_equal<T>());
00216         }
00217 
00220       bool  all_g  (const V& v) const
00221         {
00222           return std::inner_product(data, &data[N], v.get(), true, 
00223                                     std::logical_and<bool>(), std::greater<T>());
00224         }
00225 
00228       bool  all_ge (const V& v) const
00229         {
00230           return std::inner_product(data, &data[N], v.get(), true, 
00231                                     std::logical_and<bool>(), std::greater_equal<T>());
00232         }
00233 
00234 
00235       //----------------------------------------------------------------------
00236       // Assignment operators
00237       //----------------------------------------------------------------------
00238 
00240       const V& operator *=(T k) 
00241         { 
00242           std::transform(data, &data[N], data, std::bind2nd(std::multiplies<T>(), k));
00243           return static_cast<const V&>(*this);
00244         }
00245 
00247       const V& operator /=(T k)
00248         { 
00249           std::transform(data, &data[N], data, std::bind2nd(std::divides<T>(), k));
00250           return static_cast<const V&>(*this);
00251         }
00252 
00254       const V& operator +=(T k) 
00255         {
00256           std::transform(data, &data[N], data, std::bind2nd(std::plus<T>(), k));
00257           return  static_cast<const V&>(*this);
00258         }
00259 
00261       const V& operator -=(T k) 
00262         { 
00263           std::transform(data, &data[N], data, std::bind2nd(std::minus<T>(), k));
00264           return  static_cast<const V&>(*this);
00265         }
00266 
00269       const V& operator *=(const V& v) 
00270         { 
00271           std::transform(data, &data[N], v.get(), data, std::multiplies<T>());
00272           return  static_cast<const V&>(*this);
00273         }
00274 
00276       const V& operator /=(const V& v)
00277         {
00278           std::transform(data, &data[N], v.get(), data, std::divides<T>());
00279           return  static_cast<const V&>(*this);
00280         }
00281 
00283       const V& operator +=(const V& v) 
00284         {
00285           std::transform(data, &data[N], v.get(), data, std::plus<T>());
00286           return  static_cast<const V&>(*this);
00287         }
00288                 
00290       const V& operator -=(const V& v) 
00291         { 
00292           std::transform(data, &data[N], v.get(), data, std::minus<T>());
00293           return  static_cast<const V&>(*this);
00294         }
00295 
00296 
00297       //----------------------------------------------------------------------
00298       // Unary operators on vectors
00299       //----------------------------------------------------------------------
00300 
00302       const V operator - () const
00303         {
00304           V v_new;
00305           std::transform(data, &data[N], v_new.get(), std::negate<T>());
00306           return v_new;
00307         }
00308 
00309       //----------------------------------------------------------------------
00310       // Binary operators on vectors
00311       //----------------------------------------------------------------------
00312 
00315       const V operator * (const V& v1) const
00316         {
00317           V v_new;
00318           std::transform(data, &data[N], v1.get(), v_new.get(), std::multiplies<T>());
00319           return v_new;
00320         }
00321 
00323       const V operator + (const V& v1) const
00324         {
00325           V v_new;
00326           std::transform(data, &data[N], v1.get(), v_new.get(), std::plus<T>());
00327           return v_new;
00328         }
00329 
00331       const V operator - (const V& v1) const
00332         {
00333           V v_new;
00334           std::transform(data, &data[N], v1.get(), v_new.get(), std::minus<T>());
00335           return v_new;
00336         }
00337 
00339       const V operator / (const V& v1) const
00340         {
00341           V v_new;
00342           std::transform(data, &data[N], v1.get(), v_new.get(), std::divides<T>());
00343           return v_new;
00344         }
00345 
00346       //----------------------------------------------------------------------
00347       // Binary operators on vector and scalar
00348       //----------------------------------------------------------------------
00349 
00351       const V operator * (T k) const
00352         {
00353           V v_new;
00354           std::transform(data, &data[N], v_new.get(), std::bind2nd(std::multiplies<T>(), k));
00355           return v_new;
00356         }
00357   
00358 
00360       const V operator / (T k) const
00361         {
00362           V v_new;
00363           std::transform(data, &data[N], v_new.get(), std::bind2nd(std::divides<T>(), k));
00364           return v_new;      
00365         }
00366 
00367 
00369       const T min_coord() const 
00370         {
00371           return *std::min_element(data, &data[N]);
00372         }
00373 
00375       const T max_coord() const
00376         {
00377           return *std::max_element(data, &data[N]);
00378         }
00379 
00380     };
00381 
00382   template <class T, class V, unsigned int N> 
00383     inline std::ostream& operator<<(std::ostream&os, const ArithVec<T,V,N>& v)
00384     {
00385       os << "[ ";
00386       for(unsigned int i=0;i<N;i++) os << v[i] << " ";
00387       os << "]";
00388       return os;
00389     }
00390 
00392   template <class T,class V, unsigned int N>
00393     inline std::istream& operator>>(std::istream&is, ArithVec<T,V,N>& v)
00394     {
00395       for(unsigned int i=0;i<N;i++) is>>v[i];
00396       return is;
00397     }
00398 
00399 
00402   template <class T,class V, unsigned int N>
00403     inline T dot(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
00404     {
00405       return std::inner_product(v0.get(), v0.get() + N, v1.get(), T(0));
00406     }
00407 
00409   template <class T,class V, unsigned int N>
00410     inline T sqr_length(const ArithVec<T,V,N>& v)
00411     {
00412       return dot(v,v);
00413     }
00414 
00431   template<class T, class V, unsigned int N>
00432     inline const V operator * (double k, const ArithVec<T,V,N>& v) 
00433     {
00434       return v * k;
00435     }
00436 
00439   template<class T, class V, unsigned int N>
00440     inline const V operator * (float k, const ArithVec<T,V,N>& v) 
00441     {
00442       return v * k;
00443     }
00444 
00447   template<class T, class V, unsigned int N>
00448     inline const V operator * (int k, const ArithVec<T,V,N>& v) 
00449     {
00450       return v * k;
00451     }
00452 
00455   template <class T,class V, unsigned int N>
00456     inline V v_min(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
00457     {
00458       V v;
00459       std::transform(v0.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_min<T>));
00460       return v;
00461     }
00462 
00465   template <class T,class V, unsigned int N>
00466     inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
00467     {
00468       V v;
00469       std::transform(v0.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_max<T>));
00470       return v;
00471     }
00472 
00473 
00474 }
00475 
00476 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations