Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
core/w_window.hh
1 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_CORE_W_WINDOW_HH
27 # define MLN_CORE_W_WINDOW_HH
28 
34 
35 # include <map>
36 
37 # include <mln/core/internal/weighted_window_base.hh>
38 # include <mln/core/concept/image.hh>
39 # include <mln/core/site_set/box.hh>
40 # include <mln/core/window.hh>
41 # include <mln/core/dpsites_piter.hh>
42 
43 # include <mln/value/ops.hh>
44 # include <mln/util/ord.hh>
45 # include <mln/geom/bbox.hh> // FIXME: We may have some dep trouble with this include.
46 # include <mln/literal/zero.hh>
47 # include <mln/convert/to.hh>
48 
49 
50 namespace mln
51 {
52 
53  // Forward declarations.
54  template <typename D, typename W> struct w_window;
55  template <typename It, typename W> struct with_w_;
56 
57 
58  namespace convert
59  {
60 
61  namespace over_load
62  {
63 
64  template <typename I, typename D, typename W>
65  void
66  from_to_(const Image<I>& from, w_window<D,W>& to);
67 
68  template <typename D, typename W, typename I>
69  void
70  from_to_(const w_window<D,W>& from, Image<I>& to);
71 
72  template <typename V, unsigned S, typename D, typename W>
73  void
74  from_to_(const V (&weight)[S], w_window<D,W>& to);
75 
76  } // end of namespace mln::convert::over_load
77 
78  } // end of namespace mln::convert
79 
80 
81  namespace trait
82  {
83 
84  template <typename D, typename W>
85  struct window_< mln::w_window<D,W> > : window_< mln::window<D> >
86  {
87  // Same traits as its corresponding window.
88  };
89 
90  } // end of namespace mln::trait
91 
92 
99  template <typename D, typename W>
100  struct w_window : public internal::weighted_window_base< mln::window<D>,
101  w_window<D,W> >
102  {
104  typedef D dpsite;
105 
107  typedef W weight;
108 
109 
111  typedef with_w_< dpsites_fwd_piter< w_window<D, W> >, W > fwd_qiter;
112 
114  typedef with_w_< dpsites_bkd_piter< w_window<D, W> >, W > bkd_qiter;
115 
116 
118  w_window();
119 
120 
122  w_window<D,W>& insert(const W& w, const D& d);
123 
124 
126  W w(unsigned i) const;
127 
129  const std::vector<W>& weights() const;
130 
131 
133  const std::vector<D>& std_vector() const;
134 
136  const mln::window<D>& win() const;
137 
138 
140  bool is_symmetric() const;
141 
143  void sym();
144 
146  void clear();
147 
148  protected:
149 
150  mln::window<D> win_;
151  std::vector<W> wei_;
152  };
153 
154 
157  template <typename D, typename W>
158  std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win);
159 
160 
163  template <typename D, typename Wl, typename Wr>
164  bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs);
165 
166 
167 
169  template <typename It, typename W>
170  struct with_w_ : public It
171  {
172 
173  template <typename Ds, typename P>
174  with_w_(const Ds& ds, const P& p);
175 
176  W w() const;
177 
178  protected:
179  const std::vector<W> wei_;
180  };
181 
182 
183 
184 # ifndef MLN_INCLUDE_ONLY
185 
186 
187  // with_w_<It,W>
188 
189  template <typename It, typename W>
190  template <typename Ds, typename P>
191  inline
192  with_w_<It,W>::with_w_(const Ds& ds,
193  const P& p)
194  : It(ds, p),
195  wei_(ds.weights())
196  {
197  }
198 
199  template <typename It, typename W>
200  inline
201  W
202  with_w_<It,W>::w() const
203  {
204  mln_precondition(this->i_ < wei_.size());
205  return wei_[this->i_];
206  }
207 
208 
209  // w_window<D,W>
210 
211  template <typename D, typename W>
212  inline
214  {
215  }
216 
217  template <typename D, typename W>
218  inline
219  const mln::window<D>&
221  {
222  return win_;
223  }
224 
225  template <typename D, typename W>
226  inline
227  const std::vector<D>&
229  {
230  return win_.std_vector();
231  }
232 
233  template <typename D, typename W>
234  inline
235  const std::vector<W>&
237  {
238  return wei_;
239  }
240 
241  template <typename D, typename W>
242  inline
243  W
244  w_window<D,W>::w(unsigned i) const
245  {
246  mln_precondition(i < wei_.size());
247  mln_invariant(wei_.size() == win_.size());
248  return wei_[i];
249  }
250 
251  template <typename D, typename W>
252  inline
254  w_window<D,W>::insert(const W& w, const D& d)
255  {
256  mln_invariant(wei_.size() == win_.size());
257  mln_precondition(! win_.has(d));
258 
259  if (w == W(0)) // FIXME: Implicit restriction "W scalar"...
260  // no-op
261  return *this;
262 
263  // memorization: d_i -> w_i
264  std::map<D, W, util::ord<D> > memo_wei_;
265  for (unsigned i = 0; i < win_.size(); ++i)
266  memo_wei_[win_.dp(i)] = wei_[i];
267 
268  // insertion of d and w:
269  win_.insert(d);
270  memo_wei_[d] = w;
271 
272  // re-mapping: w_i <- d_i
273  wei_.resize(win_.size());
274  for (unsigned i = 0; i < win_.size(); ++i)
275  wei_[i] = memo_wei_[win_.dp(i)];
276 
277  mln_invariant(wei_.size() == win_.size());
278  return *this;
279  }
280 
281  template <typename D, typename W>
282  inline
283  bool
285  {
286  if (! win_.is_symmetric())
287  return false;
288  w_window<D,W> tmp;
289  tmp.sym();
290  return *this == tmp;
291  }
292 
293  template <typename D, typename W>
294  inline
295  void
297  {
298  w_window<D,W> tmp;
299  unsigned n = this->size();
300  for (unsigned i = 0; i < n; ++i)
301  tmp.insert(this->w(i), - this->dp(i));
302  *this = tmp;
303  }
304 
305  template <typename D, typename W>
306  inline
307  void
309  {
310  win_.clear();
311  wei_.clear();
312  }
313 
314 
315  // convert::from_to_
316 
317  namespace convert
318  {
319 
320  namespace over_load
321  {
322 
323  template <typename I, typename D, typename W>
324  void
325  from_to_(const Image<I>& from_, w_window<D,W>& to)
326  {
327  mlc_converts_to(mln_deduce(I, psite, delta), D)::check();
328  mlc_converts_to(mln_value(I), W)::check();
329  const I& ima = exact(from_);
330  to.clear();
331  mln_value(I) zero = literal::zero;
332  mln_piter(I) p(ima.domain());
333  for_all(p)
334  if (ima(p) != zero)
335  to.insert(ima(p), convert::to<D>(p));
336  }
337 
338  template <typename D, typename W, typename I>
339  void
340  from_to_(const w_window<D,W>& w_win, Image<I>& ima_)
341  {
342  typedef mln_site(I) P;
343  mlc_converts_to(D, mln_delta(P))::check();
344  mlc_converts_to(W, mln_value(I))::check();
345 
346  I& ima = exact(ima_);
347  mln_precondition(! ima.is_valid());
348  mln_precondition(w_win.is_valid());
349 
350  ima.init_(geom::bbox(w_win));
351  {
352  // data::fill(ima, literal::zero) is:
353  mln_value(I) zero = literal::zero;
354  mln_piter(I) p(ima.domain());
355  for_all(p)
356  ima(p) = zero;
357  }
358 
359  unsigned n = w_win.size();
360  for (unsigned i = 0; i < n; ++i)
361  ima(convert::to<P>(w_win.dp(i))) = w_win.w(i);
362  }
363 
364  // FIXME: Sample code (below) to generalize the code above:
365 
366 // template <typename W>
367 // inline
368 // mln_image_from(W, mln_weight(W)) to_image(const Weighted_Window<W>& w_win_)
369 // {
370 // const W& w_win = exact(w_win_);
371 // mln_precondition(! w_win.is_empty());
372 
373 // typedef mln_psite(W) P;
374 // box<P> b = geom::bbox(w_win);
375 // mln_image_from(W, mln_weight(W)) ima(b);
376 // // Fill the image with zeros, as (weighted) windows are not
377 // // necessarily box-shaped (there might be holes corresponding to
378 // // null weights).
379 // data::fill(ima, literal::zero);
380 // P O = P::origin;
381 // mln_qiter(W) q(w_win, O);
382 // for_all(q)
383 // ima(q) = q.w();
384 // return ima;
385 // }
386 
387  template <typename V, unsigned S, typename D, typename W>
388  void
389  from_to_(const V (&weight)[S], w_window<D,W>& to)
390  {
391  mlc_bool(S != 0)::check();
392  mlc_converts_to(V, W)::check();
393  enum { d = D::dim,
394  s = mlc_root(d,S)::value / 2 };
395  metal::bool_<(mlc_pow_int(2 * s + 1, d) == S)>::check();
396  to.clear();
397  typedef mln_site(D) P;
398  box<P> b(all_to(-s), all_to(+s));
399  mln_fwd_piter(box<P>) p(b);
400  unsigned i = 0;
401  V zero = literal::zero;
402  for_all(p)
403  {
404  if (weight[i] != zero)
405  to.insert(weight[i], convert::to<D>(p));
406  ++i;
407  }
408 
409  }
410 
411  } // end of namespace mln::convert::over_load
412 
413  } // end of namespace mln::convert
414 
415 
416  // operators
417 
418  template <typename D, typename W>
419  inline
420  std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win)
421  {
422  ostr << '[';
423  for (unsigned i = 0; i < w_win.win().size(); ++i)
424  ostr << w_win.dp(i) << ':' << w_win.w(i) << ' ';
425  return ostr << ']';
426  }
427 
428  template <typename D, typename Wl, typename Wr>
429  inline
430  bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs)
431  {
432  if (lhs.size() != rhs.size())
433  return false;
434  if (lhs.win() != rhs.win())
435  return false;
436  const std::vector<Wl>& wl = lhs.weights();
437  const std::vector<Wr>& wr = rhs.weights();
438  mln_assertion(wl.size() == wr.size());
439  for (unsigned i = 0; i < wl.size(); ++i)
440  if (wr[i] != wl[i])
441  return false;
442  return true;
443  }
444 
445 # endif // ! MLN_INCLUDE_ONLY
446 
447 } // end of namespace mln
448 
449 
450 # include <mln/make/w_window.hh>
451 
452 
453 #endif // ! MLN_CORE_W_WINDOW_HH