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

composed.hh

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

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