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_ALGEBRA_VEC_HH
00027 # define MLN_ALGEBRA_VEC_HH
00028
00032
00033 # include <iostream>
00034 # include <cmath>
00035
00036 # include <mln/core/concept/object.hh>
00037
00038 # include <mln/literal/zero.hh>
00039 # include <mln/literal/origin.hh>
00040 # include <mln/norm/l2.hh>
00041 # include <mln/trait/all.hh>
00042 # include <mln/trait/value_.hh>
00043 # include <mln/fun/i2v/all_to.hh>
00044 # include <mln/debug/format.hh>
00045
00046 # include <mln/value/ops.hh>
00047
00048
00049
00050
00051
00052 namespace mln
00053 {
00054
00055
00056 namespace algebra {
00057 template <unsigned n, typename T> class vec;
00058 template <unsigned d, typename C> class h_vec;
00059 template <unsigned n, unsigned m, typename T> class mat;
00060 }
00061
00062 namespace literal {
00063 struct zero_t;
00064 }
00065
00066 namespace norm {
00067 template <unsigned n, typename C>
00068 mln_sum_product(C,C) l2(const algebra::vec<n,C>& vec);
00069 }
00070
00071
00072 namespace trait
00073 {
00074
00075 template <unsigned n, typename T>
00076 struct value_< mln::algebra::vec<n,T> >
00077 {
00078 typedef trait::value::nature::vectorial nature;
00079 typedef trait::value::kind::data kind;
00080
00081 enum {
00082 dim = n,
00083 nbits = n * mln_nbits(T),
00084 card = n * mln_card(T)
00085 };
00086 typedef T comp;
00087 typedef mln_value_quant_from_(card) quant;
00088 typedef algebra::vec<n, mln_sum(T)> sum;
00089 };
00090
00091 template <unsigned n, typename T>
00092 struct set_precise_unary_< op::ord, mln::algebra::vec<n,T> >
00093 {
00094 typedef mln::internal::ord_vec< mln::algebra::vec<n,T> > ret;
00095 };
00096
00097 }
00098
00099
00100
00101 namespace algebra
00102 {
00103
00104 namespace internal
00105 {
00106
00107 template <unsigned n, typename T>
00108 class vec_base_ : public Object< vec<n,T> >
00109 {
00110 protected:
00111 T data_[n];
00112 };
00113
00114 template <typename T>
00115 class vec_base_ <1, T> : public Object< vec<1,T> >
00116 {
00117 public:
00118 void set(const T& val0)
00119 {
00120 data_[0] = val0;
00121 }
00122 protected:
00123 T data_[1];
00124 };
00125
00126 template <typename T>
00127 class vec_base_ <2, T> : public Object< vec<2,T> >
00128 {
00129 public:
00130 void set(const T& val0, const T& val1)
00131 {
00132 data_[0] = val0;
00133 data_[1] = val1;
00134 }
00135 protected:
00136 T data_[2];
00137 };
00138
00139 template <typename T>
00140 class vec_base_ <3, T> : public Object< vec<3,T> >
00141 {
00142 public:
00143 void set(const T& val0, const T& val1, const T& val2)
00144 {
00145 data_[0] = val0;
00146 data_[1] = val1;
00147 data_[2] = val2;
00148 }
00149 protected:
00150 T data_[3];
00151 };
00152
00153 template <typename T>
00154 class vec_base_ <4, T> : public Object< vec<4,T> >
00155 {
00156 public:
00157 void set(const T& val0, const T& val1, const T& val2, const T& val3)
00158 {
00159 data_[0] = val0;
00160 data_[1] = val1;
00161 data_[2] = val2;
00162 data_[3] = val3;
00163 }
00164 protected:
00165 T data_[4];
00166 };
00167
00168
00169 }
00170
00171
00172
00173 template <unsigned n, typename T>
00174 class vec : public internal::vec_base_<n, T>
00175 {
00176 typedef internal::vec_base_<n, T> super_;
00177
00178 protected:
00179 using super_::data_;
00180
00181 public:
00182
00183 typedef T equiv[n];
00184 typedef T enc[n];
00185
00186 typedef T coord;
00187 enum { dim = n };
00188
00189 vec();
00190
00192 vec(const literal::zero_t&);
00193 vec& operator=(const literal::zero_t&);
00195
00197 vec(const literal::origin_t&);
00198 vec& operator=(const literal::origin_t&);
00200
00201 vec(const vec<n, T>& rhs);
00202
00203 template <typename U>
00204 vec(const vec<n, U>& rhs);
00205
00206 template <typename U>
00207 vec& operator=(const vec<n, U>& rhs);
00208
00209
00210
00211 algebra::h_vec<n, T> to_h_vec() const;
00212
00213
00214 const T& operator[](unsigned i) const;
00215
00216 T& operator[](unsigned i);
00217
00218 void set_all(const T& val);
00219
00220 unsigned size() const;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 const vec<n, T>& normalize();
00235
00237 mat<1, n, T> t() const;
00238
00240 template <typename F>
00241 vec(const Function_v2v<F>& f);
00242
00244 static const vec<n, T> zero;
00245
00247 static const vec<n, T> origin;
00248
00249
00251 template <typename U>
00252 operator mat<n, 1, U>() const;
00253
00255 template <typename U>
00256 vec(const mat<n, 1, U>& rhs);
00257
00259 template <typename U>
00260 vec& operator=(const mat<n, 1, U>& rhs);
00261 };
00262
00263 }
00264
00265
00266
00267 namespace trait
00268 {
00269
00270
00271
00272
00273 template < template <class> class Name,
00274 unsigned n, typename T >
00275 struct set_precise_unary_< Name, algebra::vec<n, T> >
00276 {
00277 typedef mln_trait_unary(Name, T) V;
00278 typedef algebra::vec<n, V> ret;
00279 };
00280
00281
00282
00283
00284
00285
00286
00287 template < unsigned n, typename T,
00288 typename U >
00289 struct set_precise_binary_< op::plus,
00290 algebra::vec<n, T>, algebra::vec<n, U> >
00291 {
00292 typedef mln_trait_op_plus(T, U) V;
00293 typedef algebra::vec<n, V> ret;
00294 };
00295
00296
00297
00298 template < unsigned n, typename T >
00299 struct set_precise_unary_< op::uminus,
00300 algebra::vec<n, T> >
00301 {
00302 typedef mln_trait_op_uminus(T) V;
00303 typedef algebra::vec<n, V> ret;
00304 };
00305
00306
00307
00308 template < unsigned n, typename T,
00309 typename U >
00310 struct set_precise_binary_< op::minus,
00311 algebra::vec<n, T>, algebra::vec<n, U> >
00312 {
00313 typedef mln_trait_op_minus(T, U) V;
00314 typedef algebra::vec<n, V> ret;
00315 };
00316
00317
00318
00319 template < unsigned n, typename T,
00320 typename U >
00321 struct set_precise_binary_< op::times,
00322 algebra::vec<n, T>, algebra::vec<n, U> >
00323 {
00324 typedef mln_sum_product(T,U) ret;
00325 };
00326
00327
00328
00329 template < unsigned n, typename T,
00330 typename S >
00331 struct set_precise_binary_< op::times,
00332 algebra::vec<n, T>, mln::value::scalar_<S> >
00333 {
00334 typedef mln_trait_op_times(T, S) V;
00335 typedef algebra::vec<n, V> ret;
00336 };
00337
00338
00339
00340 template < unsigned n, typename T,
00341 typename S >
00342 struct set_precise_binary_< op::div,
00343 algebra::vec<n, T>, mln::value::scalar_<S> >
00344 {
00345 typedef mln_trait_op_div(T, S) V;
00346 typedef algebra::vec<n, V> ret;
00347 };
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 }
00361
00362
00363
00364 namespace algebra
00365 {
00366
00367
00368
00369 template <unsigned n, typename T, typename U>
00370 bool
00371 operator==(const vec<n,T>& lhs, const vec<n,U>& rhs);
00372
00373
00374
00375 template <unsigned n, typename T, typename U>
00376 vec<n, mln_trait_op_plus(T,U)>
00377 operator+(const vec<n,T>& lhs, const vec<n,U>& rhs);
00378
00379
00380
00381 template <unsigned n, typename T>
00382 vec<n, mln_trait_op_uminus(T)>
00383 operator-(const vec<n,T>& rhs);
00384
00385
00386
00387 template <unsigned n, typename T, typename U>
00388 vec<n, mln_trait_op_minus(T,U)>
00389 operator-(const vec<n,T>& lhs, const vec<n,U>& rhs);
00390
00391
00392
00394 template <unsigned n, typename T, typename U>
00395 mln_sum_product(T,U)
00396 operator*(const vec<n,T>& lhs, const vec<n,U>& rhs);
00397
00398
00399
00400 template <unsigned n, typename T, typename S>
00401 vec<n, mln_trait_op_times(T, S)>
00402 operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s);
00403
00404
00405
00406 template <unsigned n, typename T, typename S>
00407 vec<n, mln_trait_op_div(T, S)>
00408 operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s);
00409
00410
00411
00412 template <unsigned n, typename T>
00413 std::ostream&
00414 operator<<(std::ostream& ostr, const vec<n,T>& v);
00415
00416
00417
00418 template <unsigned n, typename T>
00419 std::istream&
00420 operator>>(std::istream& istr, vec<n,T>& v);
00421
00422
00423
00425 template <typename T, typename U>
00426 vec<3, mln_trait_op_times(T,U)>
00427 vprod(const vec<3, T>& lhs, const vec<3, U>& rhs);
00428
00429 }
00430
00431
00432
00433
00434 # ifndef MLN_INCLUDE_ONLY
00435
00436 namespace algebra
00437 {
00438
00439 template <unsigned n, typename T>
00440 inline
00441 vec<n,T>::vec()
00442 {
00443 }
00444
00445 template <unsigned n, typename T>
00446 inline
00447 vec<n,T>::vec(const literal::zero_t&)
00448 {
00449 this->set_all(0);
00450 }
00451
00452 template <unsigned n, typename T>
00453 inline
00454 vec<n,T>&
00455 vec<n,T>::operator=(const literal::zero_t&)
00456 {
00457 this->set_all(0);
00458 return *this;
00459 }
00460
00461 template <unsigned n, typename T>
00462 inline
00463 vec<n,T>::vec(const literal::origin_t&)
00464 {
00465 this->set_all(0);
00466 }
00467
00468 template <unsigned n, typename T>
00469 inline
00470 vec<n,T>&
00471 vec<n,T>::operator=(const literal::origin_t&)
00472 {
00473 this->set_all(0);
00474 return *this;
00475 }
00476
00477 template <unsigned n, typename T>
00478 inline
00479 vec<n,T>::vec(const vec<n,T>& rhs)
00480 : super_()
00481 {
00482 for (unsigned i = 0; i < n; ++i)
00483 data_[i] = rhs[i];
00484 }
00485
00486 template <unsigned n, typename T>
00487 template <typename U>
00488 inline
00489 vec<n,T>::vec(const vec<n, U>& rhs)
00490 : super_()
00491 {
00492 mlc_converts_to(U, T)::check();
00493 for (unsigned i = 0; i < n; ++i)
00494 data_[i] = static_cast<T>(rhs[i]);
00495 }
00496
00497 template <unsigned n, typename T>
00498 template <typename U>
00499 inline
00500 vec<n,T>& vec<n,T>::operator=(const vec<n, U>& rhs)
00501 {
00502 mlc_converts_to(U, T)::check();
00503 for (unsigned i = 0; i < n; ++i)
00504 data_[i] = static_cast<T>(rhs[i]);
00505 return *this;
00506 }
00507
00508 template <unsigned n, typename T>
00509 inline
00510 const T& vec<n,T>::operator[](unsigned i) const
00511 {
00512 mln_precondition(i < dim);
00513 return data_[i];
00514 }
00515
00516 template <unsigned n, typename T>
00517 inline
00518 T& vec<n,T>::operator[](unsigned i)
00519 {
00520 mln_precondition(i < dim);
00521 return data_[i];
00522 }
00523
00524 template <unsigned n, typename T>
00525 inline
00526 void vec<n,T>::set_all(const T& val)
00527 {
00528 for (unsigned i = 0; i < n; ++i)
00529 data_[i] = val;
00530 }
00531
00532 template <unsigned n, typename T>
00533 inline
00534 unsigned vec<n,T>::size() const
00535 {
00536 return n;
00537 }
00538
00539 template <unsigned n, typename T>
00540 inline
00541 const vec<n, T>& vec<n, T>::normalize()
00542 {
00543 float l2_norm = float(norm::l2(*this));
00544 mln_assertion(l2_norm > 0.f);
00545 for (unsigned i = 0; i < n; ++i)
00546 data_[i] = static_cast<T>(data_[i] / l2_norm);
00547 return *this;
00548 }
00549
00550 template <unsigned n, typename T>
00551 template <typename F>
00552 inline
00553 vec<n, T>::vec(const Function_v2v<F>& f_)
00554 {
00555 mlc_converts_to(mln_result(F), T)::check();
00556 const F& f = exact(f_);
00557 for (unsigned i = 0; i < n; ++i)
00558 data_[i] = static_cast<T>(f(i));
00559 }
00560
00561
00562 template <unsigned n, typename T>
00563 const vec<n, T> vec<n, T>::zero = all_to(0);
00564
00565 template <unsigned n, typename T>
00566 const vec<n, T> vec<n, T>::origin = all_to(0);
00567
00568
00569
00570
00571
00572
00573
00574
00575 template <unsigned n, typename T, typename U>
00576 inline
00577 bool operator==(const vec<n,T>& lhs, const vec<n,U>& rhs)
00578 {
00579 for (unsigned i = 0; i < n; ++i)
00580 if (lhs[i] != rhs[i])
00581 return false;
00582 return true;
00583 }
00584
00585
00586
00587 template <unsigned n, typename T, typename U>
00588 inline
00589 vec<n, mln_trait_op_plus(T,U)>
00590 operator+(const vec<n,T>& lhs, const vec<n,U>& rhs)
00591 {
00592 typedef mln_trait_op_plus(T,U) R;
00593 vec<n, R> tmp;
00594 for (unsigned i = 0; i < n; ++i)
00595 tmp[i] = lhs[i] + rhs[i];
00596 return tmp;
00597 }
00598
00599
00600
00601 template <unsigned n, typename T>
00602 inline
00603 vec<n, mln_trait_op_uminus(T)>
00604 operator-(const vec<n,T>& rhs)
00605 {
00606 typedef mln_trait_op_uminus(T) R;
00607 vec<n, R> tmp;
00608 for (unsigned i = 0; i < n; ++i)
00609 tmp[i] = - rhs[i];
00610 return tmp;
00611 }
00612
00613
00614
00615 template <unsigned n, typename T, typename U>
00616 inline
00617 vec<n, mln_trait_op_minus(T,U)>
00618 operator-(const vec<n,T>& lhs, const vec<n,U>& rhs)
00619 {
00620 typedef mln_trait_op_minus(T,U) R;
00621 vec<n, R> tmp;
00622 for (unsigned i = 0; i < n; ++i)
00623 tmp[i] = lhs[i] - rhs[i];
00624 return tmp;
00625 }
00626
00627
00628
00629 template <unsigned n, typename T, typename U>
00630 inline
00631 mln_sum_product(T,U)
00632 operator*(const vec<n,T>& lhs, const vec<n,U>& rhs)
00633 {
00634 typedef mln_sum_product(T,U) R;
00635 mln_sum_product(T,U) tmp(literal::zero);
00636 for (unsigned i = 0; i < n; ++i)
00637 tmp += lhs[i] * rhs[i];
00638 return tmp;
00639 }
00640
00641
00642
00643 template <unsigned n, typename T, typename S>
00644 inline
00645 vec<n, mln_trait_op_times(T, S)>
00646 operator*(const vec<n,T>& lhs, const mln::value::scalar_<S>& s)
00647 {
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 typedef mln_trait_op_times(T, S) R;
00659 vec<n, R> tmp;
00660 for (unsigned i = 0; i < n; ++i)
00661 tmp[i] = lhs[i] * s.to_equiv();
00662 return tmp;
00663 }
00664
00665
00666
00667 template <unsigned n, typename T, typename S>
00668 inline
00669 vec<n, mln_trait_op_div(T, S)>
00670 operator/(const vec<n,T>& lhs, const mln::value::scalar_<S>& s)
00671 {
00672 mln_precondition(value::equiv(s) != (S)(literal::zero));
00673 typedef mln_trait_op_div(T, S) R;
00674 vec<n, R> tmp;
00675 for (unsigned i = 0; i < n; ++i)
00676 tmp[i] = lhs[i] / s.to_equiv();
00677 return tmp;
00678 }
00679
00680
00681
00682
00683 template <unsigned n, typename T>
00684 inline
00685 std::ostream&
00686 operator<<(std::ostream& ostr, const vec<n,T>& v)
00687 {
00688 ostr << '(';
00689 for (unsigned i = 0; i < n; ++i)
00690 ostr << debug::format(v[i]) << (i == n - 1 ? ")" : ", ");
00691 return ostr;
00692 }
00693
00694
00695
00696
00697 template <unsigned n, typename T>
00698 inline
00699 std::istream&
00700 operator>>(std::istream& istr, vec<n,T>& v)
00701 {
00702 for (unsigned i = 0; i < n; ++i)
00703 istr >> v[i];
00704 return istr;
00705 }
00706
00707
00708
00709
00710 template <typename T, typename U>
00711 inline
00712 vec<3, mln_trait_op_times(T,U)>
00713 vprod(const vec<3, T>& lhs, const vec<3, U>& rhs)
00714 {
00715 vec<3, mln_trait_op_times(T,U)> tmp;
00716 tmp[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1];
00717 tmp[1] = lhs[2] * rhs[0] - lhs[0] * rhs[2];
00718 tmp[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0];
00719 return tmp;
00720 }
00721
00722
00723 template <typename P>
00724 inline
00725 P
00726 to_point(const vec<P::dim,float>& v)
00727 {
00728 P tmp;
00729 for (unsigned i = 0; i < P::dim; ++i)
00730 tmp[i] = round(v[i]);
00731 return tmp;
00732 }
00733
00734
00735 }
00736
00737
00738 # endif // MLN_INCLUDE_ONLY
00739
00740 }
00741
00742
00743 # include <mln/make/vec.hh>
00744 # include <mln/algebra/mat.hh>
00745
00746
00747 #endif // ! MLN_ALGEBRA_VEC_HH