00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_METAL_VEC_HH
00027 # define MLN_METAL_VEC_HH
00028
00032
00033 # include <iostream>
00034 # include <cmath>
00035
00036 # include <mln/core/concept/object.hh>
00037 # include <mln/algebra/h_vec.hh>
00038
00039 # include <mln/trait/all.hh>
00040 # include <mln/trait/value_.hh>
00041 # include <mln/fun/i2v/all_to.hh>
00042 # include <mln/debug/format.hh>
00043
00044 # include <mln/value/ops.hh>
00045
00046
00047
00048
00049
00050 namespace mln
00051 {
00052
00053
00054 namespace metal {
00055 template <unsigned n, typename T> class vec;
00056 }
00057 namespace literal {
00058 struct zero_t;
00059 }
00060 template <unsigned d, typename C> struct h_vec;
00061
00062
00063
00064 namespace trait
00065 {
00066
00067 template <unsigned n, typename T>
00068 struct value_< mln::metal::vec<n,T> >
00069 {
00070 typedef trait::value::nature::vectorial nature;
00071 typedef trait::value::kind::data kind;
00072
00073 enum {
00074 nbits = n * mln_nbits(T),
00075 card = n * mln_card(T)
00076 };
00077 typedef mln_value_quant_from_(card) quant;
00078
00079 typedef metal::vec<n, mln_sum(T)> sum;
00080 };
00081
00082 }
00083
00084
00085
00086 namespace metal
00087 {
00088
00089 namespace internal
00090 {
00091
00092 template <unsigned n, typename T>
00093 class vec_base_ : public Object< vec<n,T> >
00094 {
00095 protected:
00096 T data_[n];
00097 };
00098
00099 template <typename T>
00100 class vec_base_ <1, T> : public Object< vec<1,T> >
00101 {
00102 public:
00103 void set(const T& val0)
00104 {
00105 data_[0] = val0;
00106 }
00107 protected:
00108 T data_[1];
00109 };
00110
00111 template <typename T>
00112 class vec_base_ <2, T> : public Object< vec<2,T> >
00113 {
00114 public:
00115 void set(const T& val0, const T& val1)
00116 {
00117 data_[0] = val0;
00118 data_[1] = val1;
00119 }
00120 protected:
00121 T data_[2];
00122 };
00123
00124 template <typename T>
00125 class vec_base_ <3, T> : public Object< vec<3,T> >
00126 {
00127 public:
00128 void set(const T& val0, const T& val1, const T& val2)
00129 {
00130 data_[0] = val0;
00131 data_[1] = val1;
00132 data_[2] = val2;
00133 }
00134 protected:
00135 T data_[3];
00136 };
00137
00138 template <typename T>
00139 class vec_base_ <4, T> : public Object< vec<4,T> >
00140 {
00141 public:
00142 void set(const T& val0, const T& val1, const T& val2, const T& val3)
00143 {
00144 data_[0] = val0;
00145 data_[1] = val1;
00146 data_[2] = val2;
00147 data_[3] = val3;
00148 }
00149 protected:
00150 T data_[4];
00151 };
00152
00153
00154 }
00155
00156
00157
00158 template <unsigned n, typename T>
00159 class vec : public internal::vec_base_<n, T>
00160 {
00161 typedef internal::vec_base_<n, T> super_;
00162
00163 protected:
00164 using super_::data_;
00165
00166 public:
00167
00168 typedef T equiv[n];
00169 typedef T enc[n];
00170
00171 typedef T coord;
00172 enum { dim = n };
00173
00174 vec();
00175
00177 vec(const literal::zero_t&);
00178 vec& operator=(const literal::zero_t&);
00180
00181 vec(const vec<n, T>& rhs);
00182
00183 template <typename U>
00184 vec(const vec<n, U>& rhs);
00185
00186 template <typename U>
00187 vec& operator=(const vec<n, U>& rhs);
00188
00189
00190
00191 algebra::h_vec<n, T> to_h_vec() const;
00192
00193
00194 const T& operator[](unsigned i) const;
00195
00196 T& operator[](unsigned i);
00197
00198 void set_all(const T& val);
00199
00200 unsigned size() const;
00201
00202 const vec<n, T>& normalize();
00203
00205 template <typename F>
00206 vec(const Function_v2v<F>& f);
00207
00209 static const vec<n, T> zero;
00210
00212 static const vec<n, T> origin;
00213 };
00214
00215 }
00216
00217
00218 namespace trait
00219 {
00220
00221
00222
00223 template < template <class> class Name,
00224 unsigned n, typename T >
00225 struct set_precise_unary_< Name, metal::vec<n, T> >
00226 {
00227 typedef mln_trait_unary(Name, T) V;
00228 typedef metal::vec<n, V> ret;
00229 };
00230
00231
00232
00233 template < template <class, class> class Name,
00234 unsigned n, typename T,
00235 typename U >
00236 struct set_precise_binary_< Name,
00237 metal::vec<n, T>, metal::vec<n, U> >
00238 {
00239 typedef mln_trait_binary(Name, T, U) V;
00240 typedef metal::vec<n, V> ret;
00241 };
00242
00243 template < unsigned n, typename T,
00244 typename U >
00245 struct set_precise_binary_< op::times,
00246 metal::vec<n, T>, metal::vec<n, U> >
00247 {
00248 typedef mln_sum_product(T,U) ret;
00249 };
00250
00251 template < template <class, class> class Name,
00252 unsigned n, typename T,
00253 typename S >
00254 struct set_precise_binary_< Name,
00255 metal::vec<n, T>, mln::value::scalar_<S> >
00256 {
00257 typedef mln_trait_binary(Name, T, S) V;
00258 typedef metal::vec<n, V> ret;
00259 };
00260
00261 template < template<class, class> class Name,
00262 unsigned n, typename T,
00263 typename S >
00264 struct set_binary_< Name,
00265 mln::Object, metal::vec<n, T>,
00266 mln::value::Scalar, S >
00267 {
00268 typedef mln_trait_binary(Name, T, S) V;
00269 typedef metal::vec<n, V> ret;
00270 };
00271
00272 }
00273
00274
00275
00276 namespace metal
00277 {
00278
00279
00280
00281 template <unsigned n, typename T, typename U>
00282 bool operator==(const vec<n,T>& lhs, const vec<n,U>& rhs);
00283
00284
00285
00286 template <unsigned n, typename T, typename U>
00287 vec<n, mln_trait_op_plus(T,U)>
00288 operator+(const vec<n,T>& lhs, const vec<n,U>& rhs);
00289
00290
00291
00292 template <unsigned n, typename T, typename U>
00293 vec<n, mln_trait_op_minus(T,U)>
00294 operator-(const vec<n,T>& lhs, const vec<n,U>& rhs);
00295
00296
00297
00298 template <unsigned n, typename T, typename U>
00299 mln_sum_product(T,U)
00300 operator*(const vec<n,T>& lhs, const vec<n,U>& rhs);
00301
00302
00303
00304 template <unsigned n, typename T, typename S>
00305 vec<n, mln_trait_op_times(T, S)>
00306 operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s);
00307
00308
00309
00310 template <unsigned n, typename T, typename S>
00311 vec<n, mln_trait_op_div(T, S)>
00312 operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s);
00313
00314
00315
00316 template <unsigned n, typename T>
00317 std::ostream&
00318 operator<<(std::ostream& ostr, const vec<n,T>& v);
00319
00320
00321
00322 template <typename T, typename U>
00323 vec<3, mln_trait_op_times(T,U)>
00324 vprod(const vec<3, T>& lhs, const vec<3, U>& rhs);
00325
00326
00327 # ifndef MLN_INCLUDE_ONLY
00328
00329 template <unsigned n, typename T>
00330 inline
00331 vec<n,T>::vec()
00332 {
00333 }
00334
00335 template <unsigned n, typename T>
00336 inline
00337 vec<n,T>::vec(const literal::zero_t&)
00338 {
00339 this->set_all(0);
00340 }
00341
00342 template <unsigned n, typename T>
00343 inline
00344 vec<n,T>&
00345 vec<n,T>::operator=(const literal::zero_t&)
00346 {
00347 this->set_all(0);
00348 return *this;
00349 }
00350
00351 template <unsigned n, typename T>
00352 inline
00353 vec<n,T>::vec(const vec<n,T>& rhs)
00354 : super_()
00355 {
00356 for (unsigned i = 0; i < n; ++i)
00357 data_[i] = rhs[i];
00358 }
00359
00360 template <unsigned n, typename T>
00361 template <typename U>
00362 inline
00363 vec<n,T>::vec(const vec<n, U>& rhs)
00364 : super_()
00365 {
00366 for (unsigned i = 0; i < n; ++i)
00367 data_[i] = rhs[i];
00368 }
00369
00370 template <unsigned n, typename T>
00371 template <typename U>
00372 inline
00373 vec<n,T>& vec<n,T>::operator=(const vec<n, U>& rhs)
00374 {
00375 for (unsigned i = 0; i < n; ++i)
00376 data_[i] = rhs[i];
00377 return *this;
00378 }
00379
00380 template <unsigned n, typename T>
00381 inline
00382 const T& vec<n,T>::operator[](unsigned i) const
00383 {
00384 mln_precondition(i < dim);
00385 return data_[i];
00386 }
00387
00388 template <unsigned n, typename T>
00389 inline
00390 T& vec<n,T>::operator[](unsigned i)
00391 {
00392 mln_precondition(i < dim);
00393 return data_[i];
00394 }
00395
00396 template <unsigned n, typename T>
00397 inline
00398 void vec<n,T>::set_all(const T& val)
00399 {
00400 for (unsigned i = 0; i < n; ++i)
00401 data_[i] = val;
00402 }
00403
00404 template <unsigned n, typename T>
00405 inline
00406 unsigned vec<n,T>::size() const
00407 {
00408 return n;
00409 }
00410
00411 template <unsigned n, typename T>
00412 inline
00413 const vec<n, T>& vec<n, T>::normalize()
00414 {
00415 float n_l2 = 0;
00416 for (unsigned i = 0; i < n; ++i)
00417 n_l2 += data_[i] * data_[i];
00418 n_l2 = sqrt(n_l2);
00419 for (unsigned i = 0; i < n; ++i)
00420 data_[i] = T(data_[i] / n_l2);
00421 return *this;
00422 }
00423
00424 template <unsigned n, typename T>
00425 template <typename F>
00426 inline
00427 vec<n, T>::vec(const Function_v2v<F>& f_)
00428 {
00429 mlc_converts_to(mln_result(F), T)::check();
00430 const F& f = exact(f_);
00431 for (unsigned i = 0; i < n; ++i)
00432 data_[i] = f(i);
00433 }
00434
00435
00436 template <unsigned n, typename T>
00437 const vec<n, T> vec<n, T>::zero = all_to(0);
00438
00439 template <unsigned n, typename T>
00440 const vec<n, T> vec<n, T>::origin = all_to(0);
00441
00442
00443
00444
00445
00446 template <unsigned n, typename T, typename U>
00447 inline
00448 bool operator==(const vec<n,T>& lhs, const vec<n,U>& rhs)
00449 {
00450 for (unsigned i = 0; i < n; ++i)
00451 if (lhs[i] != rhs[i])
00452 return false;
00453 return true;
00454 }
00455
00456
00457 template <unsigned n, typename T, typename U>
00458 inline
00459 vec<n, mln_trait_op_plus(T,U)>
00460 operator+(const vec<n,T>& lhs, const vec<n,U>& rhs)
00461 {
00462 vec<n, mln_trait_op_plus(T,U)> tmp;
00463 for (unsigned i = 0; i < n; ++i)
00464 tmp[i] = lhs[i] + rhs[i];
00465 return tmp;
00466 }
00467
00468 template <unsigned n, typename T, typename U>
00469 inline
00470 vec<n, mln_trait_op_minus(T,U)>
00471 operator-(const vec<n,T>& lhs, const vec<n,U>& rhs)
00472 {
00473 vec<n, mln_trait_op_minus(T,U)> tmp;
00474 for (unsigned i = 0; i < n; ++i)
00475 tmp[i] = lhs[i] - rhs[i];
00476 return tmp;
00477 }
00478
00479 template <unsigned n, typename T, typename U>
00480 inline
00481 mln_sum_product(T,U)
00482 operator*(const vec<n,T>& lhs, const vec<n,U>& rhs)
00483 {
00484 mln_sum_product(T,U) tmp(literal::zero);
00485 for (unsigned i = 0; i < n; ++i)
00486 tmp += lhs[i] * rhs[i];
00487 return tmp;
00488 }
00489
00490 template <unsigned n, typename T, typename S>
00491 inline
00492 vec<n, mln_trait_op_times(T, S)>
00493 operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s)
00494 {
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 vec<n, mln_trait_op_times(T, S)> tmp;
00506 for (unsigned i = 0; i < n; ++i)
00507 tmp[i] = lhs[i] * s.to_equiv();
00508 return tmp;
00509 }
00510
00511 template <unsigned n, typename T, typename S>
00512 inline
00513 vec<n, mln_trait_op_div(T, S)>
00514 operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s)
00515 {
00516 mln_precondition(value::equiv(s) != literal::zero);
00517 vec<n, mln_trait_op_div(T, S)> tmp;
00518 for (unsigned i = 0; i < n; ++i)
00519 tmp[i] = lhs[i] / s.to_equiv();
00520 return tmp;
00521 }
00522
00523
00524 template <unsigned n, typename T>
00525 inline
00526 std::ostream&
00527 operator<<(std::ostream& ostr, const vec<n,T>& v)
00528 {
00529 ostr << '(';
00530 for (unsigned i = 0; i < n; ++i)
00531 ostr << debug::format(v[i]) << (i == n - 1 ? ")" : ", ");
00532 return ostr;
00533 }
00534
00535
00536
00537 template <typename T, typename U>
00538 inline
00539 vec<3, mln_trait_op_times(T,U)>
00540 vprod(const vec<3, T>& lhs, const vec<3, U>& rhs)
00541 {
00542 vec<3, mln_trait_op_times(T,U)> tmp;
00543 tmp[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1];
00544 tmp[1] = lhs[2] * rhs[0] - lhs[0] * rhs[2];
00545 tmp[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0];
00546 return tmp;
00547 }
00548
00549 # endif // MLN_INCLUDE_ONLY
00550
00551 }
00552
00553 }
00554
00555
00556 # include <mln/make/vec.hh>
00557
00558
00559 #endif // ! MLN_METAL_VEC_HH