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

composed.hh

00001 // Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
00002 // 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_FUN_X2X_COMPOSED_HH
00028 # define MLN_FUN_X2X_COMPOSED_HH
00029 
00033 
00034 # include <mln/core/concept/function.hh>
00035 # include <mln/fun/internal/x2x_linear_impl.hh>
00036 # include <mln/algebra/vec.hh>
00037 # include <mln/metal/is.hh>
00038 # include <mln/metal/bexpr.hh>
00039 # include <mln/algebra/h_mat.hh>
00040 
00041 
00042 namespace mln
00043 {
00044 
00045   namespace fun
00046   {
00047 
00048     namespace x2x
00049     {
00050 
00051       // Forward declaration.
00052       template <typename T2, typename T1>
00053       struct composed;
00054 
00055       namespace internal
00056       {
00057         template <typename T2, typename T1, typename E, bool is_bij>
00058         struct helper_composed_;
00059 
00060 
00062         template <typename T2, typename T1, typename E>
00063         struct helper_composed_<T2,T1,E,true>
00064           : public fun::internal::x2x_linear_impl_<mln_result(T2), typename T2::data_t, E >,
00065             public Function_v2v<E>
00066         {
00067           typedef fun::internal::x2x_linear_impl_<typename T2::result, typename T2::data_t, E > super_;
00068 
00070           typedef typename T2::data_t data_t;
00071 
00072           using super_::dim;
00073 
00075           helper_composed_();
00077           helper_composed_(const T2& f, const T1& g);
00078 
00079           using super_::operator();
00080 
00082           const T2& second() const;
00084           const T1& first() const;
00085 
00087           void set_second(const T2& f);
00089           void set_first(const T1& g);
00090 
00092           typedef composed<mln_invert(T1),mln_invert(T2)> invert;
00094           invert inv() const;
00095 
00096           //protected:
00097 
00098           T2 f_;
00099           T1 g_;
00100         };
00101 
00103         template <typename T2, typename T1, typename E>
00104         struct helper_composed_<T2,T1,E,false>
00105           : public fun::internal::x2x_linear_impl_<mln_result(T2), typename T2::data_t, E >,
00106             public Function_v2v<E>
00107         {
00108           typedef fun::internal::x2x_linear_impl_<typename T2::result, typename T2::data_t, E > super_;
00109 
00110 
00112           typedef typename T2::data_t data_t;
00113 
00114           using super_::dim;
00115 
00117           helper_composed_();
00119           helper_composed_(const T2& f, const T1& g);
00120 
00121           using super_::operator();
00122 
00124           void set_second(const T2& f);
00126           void set_first(const T1& g);
00127 
00129           const T2& second() const;
00131           const T1& first() const;
00132 
00133           //protected:
00134 
00135           T2 f_;
00136           T1 g_;
00137         };
00138 
00139       } // end of namespace mln::fun::x2x::internal
00140 
00141 
00143       template <typename T2, typename T1>
00144       struct composed
00145         : public internal::helper_composed_< T2, T1, composed<T2,T1>,
00146                                              (mlc_is(T2, Function_v2v<T2>)::value &&
00147                                               mlc_is(T1, Function_v2v<T1>)::value) >,
00148           private metal::and_< metal::bool_<(T2::dim == T1::dim)>,
00149                                metal::is<mln_argument(T2), mln_result(T1)>
00150                                >::check_t
00151       {
00153         composed() {}
00154 
00156         composed(const T2& f, const T1& g)
00157           : internal::helper_composed_< T2, T1, composed<T2,T1>,
00158                                         (mlc_is(T2, Function_v2v<T2>)::value &&
00159                                          mlc_is(T1, Function_v2v<T1>)::value) >(f, g)
00160         {}
00161       };
00162 
00163     } // end of namespace mln::fun::x2x
00164 
00165   } // end of namespace mln::fun
00166 
00167 
00174   template <typename T2, typename T1>
00175   fun::x2x::composed<T2,T1> compose(T2 f, T1 g);
00176 
00177 # ifndef MLN_INCLUDE_ONLY
00178 
00179   namespace fun
00180   {
00181 
00182     namespace x2x
00183     {
00184 
00185       namespace internal
00186       {
00187 
00188         // Implementation of the bijective version.
00189 
00190         template <typename T2, typename T1, typename E>
00191         inline
00192         helper_composed_<T2,T1,E,true>::helper_composed_()
00193         {
00194         }
00195 
00196         template <typename T2, typename T1, typename E>
00197         inline
00198         helper_composed_<T2,T1,E,true>::helper_composed_(const T2& f, const T1& g)
00199           :f_(f),
00200            g_(g)
00201         {
00202           this->m_ = f_.mat() * g_.mat();
00203         }
00204 
00205         template <typename T2, typename T1, typename E>
00206         inline
00207         typename helper_composed_<T2,T1,E,true>::invert
00208         helper_composed_<T2,T1,E,true>::inv() const
00209         {
00210           return compose(g_.inv(), f_.inv());
00211         }
00212 
00213         template <typename T2, typename T1, typename E>
00214         inline
00215         void
00216         helper_composed_<T2,T1,E,true>::set_second(const T2& f)
00217         {
00218           this->f_ = f;
00219           this->m_ = this->f_.mat() * this->g_.mat();
00220         }
00221 
00222         template <typename T2, typename T1, typename E>
00223         inline
00224         void
00225         helper_composed_<T2,T1,E,true>::set_first(const T1& g)
00226         {
00227           this->g_ = g;
00228           this->m_ = this->f_.mat() * this->g_.mat();
00229         }
00230 
00231         template <typename T2, typename T1, typename E>
00232         inline
00233         const T2&
00234         helper_composed_<T2,T1,E,true>::second() const
00235         {
00236           return this->f_;
00237         }
00238 
00239         template <typename T2, typename T1, typename E>
00240         inline
00241         const T1&
00242         helper_composed_<T2,T1,E,true>::first() const
00243         {
00244           return this->g_;
00245         }
00246 
00247         // Implementation of the non bijective version.
00248         template <typename T2, typename T1, typename E>
00249         inline
00250         helper_composed_<T2,T1,E,false>::helper_composed_()
00251         {
00252         }
00253 
00254         template <typename T2, typename T1, typename E>
00255         inline
00256         helper_composed_<T2,T1,E,false>::helper_composed_(const T2& f, const T1& g)
00257           :f_(f),
00258            g_(g)
00259         {
00260           this->m_ = f_.mat() * g_.mat();
00261         }
00262 
00263         template <typename T2, typename T1, typename E>
00264         inline
00265         void
00266         helper_composed_<T2,T1,E,false>::set_second(const T2& f)
00267         {
00268           this->f_ = f;
00269           this->m_ = this->f_.mat() * this->g_.mat();
00270         }
00271 
00272         template <typename T2, typename T1, typename E>
00273         inline
00274         void
00275         helper_composed_<T2,T1,E,false>::set_first(const T1& g)
00276         {
00277           this->g_ = g;
00278           this->m_ = this->f_.mat() * this->g_.mat();
00279         }
00280 
00281         template <typename T2, typename T1, typename E>
00282         inline
00283         const T2&
00284         helper_composed_<T2,T1,E,false>::second() const
00285         {
00286           return this->f_;
00287         }
00288 
00289         template <typename T2, typename T1, typename E>
00290         inline
00291         const T1&
00292         helper_composed_<T2,T1,E,false>::first() const
00293         {
00294           return this->g_;
00295         }
00296 
00297 
00298       } // end of namespace mln::fun::x2x::internal
00299 
00300     } // end of namespace mln::fun::x2x
00301 
00302   } // end of namespace mln::fun
00303 
00304   template <typename T2, typename T1>
00305   inline
00306   fun::x2x::composed<T2,T1> compose(T2 f, T1 g)
00307   {
00308     trace::entering("fun::x2x::compose");
00309     fun::x2x::composed<T2,T1> comp(f, g);
00310     trace::exiting("fun::x2x::compose");
00311     return comp;
00312   }
00313 
00314 # endif // ! MLN_INCLUDE_ONLY
00315 
00316 } // end of namespace mln
00317 
00318 
00319 #endif // ! MLN_FUN_X2X_COMPOSED_HH

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