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
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
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
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
00134
00135 T2 f_;
00136 T1 g_;
00137 };
00138
00139 }
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 }
00164
00165 }
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
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
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 }
00299
00300 }
00301
00302 }
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 }
00317
00318
00319 #endif // ! MLN_FUN_X2X_COMPOSED_HH