Milena (Olena)
User documentation 2.0a Id
|
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