Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
composed.hh
1 // Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_FUN_X2X_COMPOSED_HH
28 # define MLN_FUN_X2X_COMPOSED_HH
29 
33 
34 # include <mln/core/concept/function.hh>
35 # include <mln/fun/internal/x2x_linear_impl.hh>
36 # include <mln/algebra/vec.hh>
37 # include <mln/metal/is.hh>
38 # include <mln/metal/bexpr.hh>
39 # include <mln/algebra/h_mat.hh>
40 
41 
42 namespace mln
43 {
44 
45  namespace fun
46  {
47 
48  namespace x2x
49  {
50 
51  // Forward declaration.
52  template <typename T2, typename T1>
53  struct composed;
54 
55  namespace internal
56  {
57  template <typename T2, typename T1, typename E, bool is_bij>
58  struct helper_composed_;
59 
60 
62  template <typename T2, typename T1, typename E>
63  struct helper_composed_<T2,T1,E,true>
64  : public fun::internal::x2x_linear_impl_<mln_result(T2), typename T2::data_t, E >,
65  public Function_v2v<E>
66  {
67  typedef fun::internal::x2x_linear_impl_<typename T2::result, typename T2::data_t, E > super_;
68 
70  typedef typename T2::data_t data_t;
71 
72  using super_::dim;
73 
75  helper_composed_();
77  helper_composed_(const T2& f, const T1& g);
78 
79  using super_::operator();
80 
82  const T2& second() const;
84  const T1& first() const;
85 
87  void set_second(const T2& f);
89  void set_first(const T1& g);
90 
92  typedef composed<mln_invert(T1),mln_invert(T2)> invert;
94  invert inv() const;
95 
96  //protected:
97 
98  T2 f_;
99  T1 g_;
100  };
101 
103  template <typename T2, typename T1, typename E>
104  struct helper_composed_<T2,T1,E,false>
105  : public fun::internal::x2x_linear_impl_<mln_result(T2), typename T2::data_t, E >,
106  public Function_v2v<E>
107  {
108  typedef fun::internal::x2x_linear_impl_<typename T2::result, typename T2::data_t, E > super_;
109 
110 
112  typedef typename T2::data_t data_t;
113 
114  using super_::dim;
115 
117  helper_composed_();
119  helper_composed_(const T2& f, const T1& g);
120 
121  using super_::operator();
122 
124  void set_second(const T2& f);
126  void set_first(const T1& g);
127 
129  const T2& second() const;
131  const T1& first() const;
132 
133  //protected:
134 
135  T2 f_;
136  T1 g_;
137  };
138 
139  } // end of namespace mln::fun::x2x::internal
140 
141 
143  template <typename T2, typename T1>
144  struct composed
145  : public internal::helper_composed_< T2, T1, composed<T2,T1>,
146  (mlc_is(T2, Function_v2v<T2>)::value &&
147  mlc_is(T1, Function_v2v<T1>)::value) >,
148  private metal::and_< metal::bool_<(T2::dim == T1::dim)>,
149  metal::is<mln_argument(T2), mln_result(T1)>
150  >::check_t
151  {
153  composed() {}
154 
156  composed(const T2& f, const T1& g)
157  : internal::helper_composed_< T2, T1, composed<T2,T1>,
158  (mlc_is(T2, Function_v2v<T2>)::value &&
159  mlc_is(T1, Function_v2v<T1>)::value) >(f, g)
160  {}
161  };
162 
163  } // end of namespace mln::fun::x2x
164 
165  } // end of namespace mln::fun
166 
167 
174  template <typename T2, typename T1>
175  fun::x2x::composed<T2,T1> compose(T2 f, T1 g);
176 
177 # ifndef MLN_INCLUDE_ONLY
178 
179  namespace fun
180  {
181 
182  namespace x2x
183  {
184 
185  namespace internal
186  {
187 
188  // Implementation of the bijective version.
189 
190  template <typename T2, typename T1, typename E>
191  inline
192  helper_composed_<T2,T1,E,true>::helper_composed_()
193  {
194  }
195 
196  template <typename T2, typename T1, typename E>
197  inline
198  helper_composed_<T2,T1,E,true>::helper_composed_(const T2& f, const T1& g)
199  :f_(f),
200  g_(g)
201  {
202  this->m_ = f_.mat() * g_.mat();
203  }
204 
205  template <typename T2, typename T1, typename E>
206  inline
207  typename helper_composed_<T2,T1,E,true>::invert
208  helper_composed_<T2,T1,E,true>::inv() const
209  {
210  return compose(g_.inv(), f_.inv());
211  }
212 
213  template <typename T2, typename T1, typename E>
214  inline
215  void
216  helper_composed_<T2,T1,E,true>::set_second(const T2& f)
217  {
218  this->f_ = f;
219  this->m_ = this->f_.mat() * this->g_.mat();
220  }
221 
222  template <typename T2, typename T1, typename E>
223  inline
224  void
225  helper_composed_<T2,T1,E,true>::set_first(const T1& g)
226  {
227  this->g_ = g;
228  this->m_ = this->f_.mat() * this->g_.mat();
229  }
230 
231  template <typename T2, typename T1, typename E>
232  inline
233  const T2&
234  helper_composed_<T2,T1,E,true>::second() const
235  {
236  return this->f_;
237  }
238 
239  template <typename T2, typename T1, typename E>
240  inline
241  const T1&
242  helper_composed_<T2,T1,E,true>::first() const
243  {
244  return this->g_;
245  }
246 
247  // Implementation of the non bijective version.
248  template <typename T2, typename T1, typename E>
249  inline
250  helper_composed_<T2,T1,E,false>::helper_composed_()
251  {
252  }
253 
254  template <typename T2, typename T1, typename E>
255  inline
256  helper_composed_<T2,T1,E,false>::helper_composed_(const T2& f, const T1& g)
257  :f_(f),
258  g_(g)
259  {
260  this->m_ = f_.mat() * g_.mat();
261  }
262 
263  template <typename T2, typename T1, typename E>
264  inline
265  void
266  helper_composed_<T2,T1,E,false>::set_second(const T2& f)
267  {
268  this->f_ = f;
269  this->m_ = this->f_.mat() * this->g_.mat();
270  }
271 
272  template <typename T2, typename T1, typename E>
273  inline
274  void
275  helper_composed_<T2,T1,E,false>::set_first(const T1& g)
276  {
277  this->g_ = g;
278  this->m_ = this->f_.mat() * this->g_.mat();
279  }
280 
281  template <typename T2, typename T1, typename E>
282  inline
283  const T2&
284  helper_composed_<T2,T1,E,false>::second() const
285  {
286  return this->f_;
287  }
288 
289  template <typename T2, typename T1, typename E>
290  inline
291  const T1&
292  helper_composed_<T2,T1,E,false>::first() const
293  {
294  return this->g_;
295  }
296 
297 
298  } // end of namespace mln::fun::x2x::internal
299 
300  } // end of namespace mln::fun::x2x
301 
302  } // end of namespace mln::fun
303 
304  template <typename T2, typename T1>
305  inline
307  {
308  trace::entering("fun::x2x::compose");
309  fun::x2x::composed<T2,T1> comp(f, g);
310  trace::exiting("fun::x2x::compose");
311  return comp;
312  }
313 
314 # endif // ! MLN_INCLUDE_ONLY
315 
316 } // end of namespace mln
317 
318 
319 #endif // ! MLN_FUN_X2X_COMPOSED_HH