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