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

vec.hh

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

Generated on Thu Sep 8 2011 18:33:02 for Milena (Olena) by  doxygen 1.7.1