00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
00126
00127 T2 f_;
00128 T1 g_;
00129 };
00130
00131 }
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 }
00156
00157 }
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
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
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 }
00291
00292 }
00293
00294 }
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 }
00309
00310
00311 #endif // ! MLN_FUN_X2X_COMPOSED_HH