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