GEL
2
GEL is a library for Geometry and Linear Algebra
|
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