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

vec.hh

00001 // Copyright (C) 2006, 2007, 2008, 2009, 2010 EPITA Research and
00002 // Development Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
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 // FIXME: Document.
00049 
00050 
00051 namespace mln
00052 {
00053 
00054   // Fwd decls.
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   } // end of namespace mln::trait
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     } // end of namespace mln::metal::internal
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       // Immersion of the vector into its homogeneous space.
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   } // end of namespace mln::metal
00217 
00218 
00219   namespace trait
00220   {
00221 
00222     // For unary traits.
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     // For binary traits.
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   } // end of namespace mln::trait
00274 
00275 
00276 
00277   namespace metal
00278   {
00279 
00280     // eq
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     // vec * vec
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     // vec * s
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     // vec / s
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     // vprod // FIXME: Generalize...
00322 
00323     template <typename T, typename U>
00324     vec<3, mln_trait_op_times(T,U)> // FIXME: Sum of product...
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     // Operators.
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       // FIXME: We made a choice here but is it correct?
00497       // FIXME: We "un-scalar" s so that the scalar status do not propagate.
00498 
00499       // Think of the case: vec<mat> v * scalar(vec w) s
00500       // It gives: for all i, v[i] * w  so  the i-th mat * vec w -> vec
00501       // The result is a vec<vec>
00502 
00503       // If we really want to propage the "scalar" status then
00504       // we shall allow for scalar(scalar(..)) !!!  => FIXME
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     // vprod
00537 
00538     template <typename T, typename U>
00539     inline
00540     vec<3, mln_trait_op_times(T,U)> // FIXME: typename binary_arith_trait<T, U>::ret>
00541     vprod(const vec<3, T>& lhs, const vec<3, U>& rhs)
00542     {
00543       vec<3, mln_trait_op_times(T,U)> tmp; // FIXME: Likewise.
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   } // end of namespace mln::metal
00553 
00554 } // end of namespace mln
00555 
00556 
00557 # include <mln/make/vec.hh>
00558 
00559 
00560 #endif // ! MLN_METAL_VEC_HH

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