• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

vec.hh

00001 // Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
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 // FIXME: Document.
00050 
00051 
00052 namespace mln
00053 {
00054 
00055   // Forward declarations.
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   } // end of namespace mln::trait
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     } // end of namespace mln::algebra::internal
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       // Immersion of the vector into its homogeneous space.
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       /* FIXME: What if the vector is null?  Even if we choose not to
00223          handle this case, we should *state* in the documentation the
00224          behavior of this method.
00225 
00226          I (Roland) have added an assertion to detect ``erroneous''
00227          cases, but we might want something different.
00228          ``Implementation defined'' or ``undefined behavior'' is fine
00229          by me, as long as the documentation mentions it.
00230 
00231          FWIW, Trimesh's developers chose to set all the coordinates
00232          of a vector being normalized to 1, when it norm is equal or
00233          lower (sic) to zero.  */
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   } // end of namespace mln::algebra
00264 
00265 
00266 
00267   namespace trait
00268   {
00269 
00270     // For unary traits.
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     // For binary traits.
00283 
00284 
00285     // vec + vec
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     // - vec
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     // vec - vec
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     // vec * vec
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     // vec * s
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     // vec / s
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 //     template < template<class, class> class Name,
00350 //             unsigned n, typename T,
00351 //             typename S >
00352 //     struct set_binary_< Name,
00353 //                      mln::Object, algebra::vec<n, T>,
00354 //                      mln::value::Scalar, S >
00355 //     {
00356 //       typedef mln_trait_binary(Name, T, S) V;
00357 //       typedef algebra::vec<n, V> ret;
00358 //     };
00359 
00360   } // end of namespace mln::trait
00361 
00362 
00363 
00364   namespace algebra
00365   {
00366 
00367     // vec == vec
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     // vec + vec
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     // - vec
00380 
00381     template <unsigned n, typename T>
00382     vec<n, mln_trait_op_uminus(T)>
00383     operator-(const vec<n,T>& rhs);
00384 
00385     // vec - vec
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     // vec * vec
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     // vec * s
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     // vec / s
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     // vprod // FIXME: Generalize...
00423 
00425     template <typename T, typename U>
00426     vec<3, mln_trait_op_times(T,U)> // FIXME: Sum of product...
00427     vprod(const vec<3, T>& lhs, const vec<3, U>& rhs);
00428 
00429   } // end of namespace mln::algebra
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       mln_sum_product(T,T) l2_norm = norm::l2(*this);
00544       mln_assertion(l2_norm > mln_sum_product(T,T)(0));
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     // Operators.
00571 
00572 
00573     // vec == vec
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     // vec + vec
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     // - vec
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     // vec - vec
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     // vec * vec
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     // vec * s
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       // FIXME: We made a choice here but is it correct?
00649       // FIXME: We "un-scalar" s so that the scalar status do not propagate.
00650 
00651       // Think of the case: vec<mat> v * scalar(vec w) s
00652       // It gives: for all i, v[i] * w  so  the i-th mat * vec w -> vec
00653       // The result is a vec<vec>
00654 
00655       // If we really want to propage the "scalar" status then
00656       // we shall allow for scalar(scalar(..)) !!!  => FIXME
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     // vec / s
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     // << v
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     // >> v
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     // vprod
00709 
00710     template <typename T, typename U>
00711     inline
00712     vec<3, mln_trait_op_times(T,U)> // FIXME: typename binary_arith_trait<T, U>::ret>
00713     vprod(const vec<3, T>& lhs, const vec<3, U>& rhs)
00714     {
00715       vec<3, mln_trait_op_times(T,U)> tmp; // FIXME: Likewise.
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   } // end of namespace mln::algebra
00736 
00737 
00738 # endif // MLN_INCLUDE_ONLY
00739 
00740 } // end of namespace mln
00741 
00742 
00743 # include <mln/make/vec.hh>
00744 # include <mln/algebra/mat.hh>
00745 
00746 
00747 #endif // ! MLN_ALGEBRA_VEC_HH

Generated on Tue Oct 4 2011 15:25:06 for Milena (Olena) by  doxygen 1.7.1