Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
morpho/tree/data.hh
1 // Copyright (C) 2008, 2009, 2010, 2011 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_MORPHO_TREE_DATA_HH
28 # define MLN_MORPHO_TREE_DATA_HH
29 
34 
35 # include <mln/morpho/tree/compute_parent.hh>
36 # include <mln/core/site_set/p_array.hh>
37 # include <mln/core/internal/site_set_iterator_base.hh>
38 # include <mln/core/internal/piter_identity.hh>
39 
40 # include <deque>
41 # include <iostream>
42 
43 # define mln_up_site_piter(T) typename T::up_site_piter
44 # define mln_dn_site_piter(T) typename T::dn_site_piter
45 # define mln_up_node_piter(T) typename T::up_node_piter
46 # define mln_dn_node_piter(T) typename T::dn_node_piter
47 # define mln_up_leaf_piter(T) typename T::up_leaf_piter
48 # define mln_dn_leaf_piter(T) typename T::dn_leaf_piter
49 # define mln_site_piter(T) typename T::site_piter
50 # define mln_node_piter(T) typename T::node_piter
51 # define mln_leaf_piter(T) typename T::leaf_piter
52 # define mln_depth1st_piter(T) typename T::depth1st_piter
53 
54 # define mln_up_site_piter_(T) T::up_site_piter
55 # define mln_dn_site_piter_(T) T::dn_site_piter
56 # define mln_up_node_piter_(T) T::up_node_piter
57 # define mln_dn_node_piter_(T) T::dn_node_piter
58 # define mln_up_leaf_piter_(T) T::up_leaf_piter
59 # define mln_dn_leaf_piter_(T) T::dn_leaf_piter
60 # define mln_site_piter_(T) T::site_piter
61 # define mln_node_piter_(T) T::node_piter
62 # define mln_leaf_piter_(T) T::leaf_piter
63 # define mln_depth1st_piter_(T) T::depth1st_piter
64 
65 
66 namespace mln
67 {
68 
69  namespace morpho
70  {
71 
72  namespace tree
73  {
74 
75  // Forward declarations.
76 
78  template <typename T> struct up_site_piter;
79 
81  template <typename T> struct dn_site_piter;
82 
84  template <typename T> struct up_node_piter;
85 
87  template <typename T> struct dn_node_piter;
88 
90  template <typename T> struct up_leaf_piter;
91 
93  template <typename T> struct dn_leaf_piter;
94 
96  template <typename T> class depth1st_piter;
97 
98 
99  template <typename I, typename S>
100  class data
101  {
102  typedef data<I, S> self_;
103 
104  public:
106  typedef I function;
108  typedef mln_psite(I) psite;
109  typedef mln_site(I) site;
111  typedef S sites_t;
113  typedef p_array<mln_psite(I)> nodes_t;
115  typedef p_array<mln_psite(I)> leaves_t;
116 
118  typedef mln_ch_value(I, mln_psite(I)) parent_t;
119 
121  typedef mln_ch_value(I, nodes_t) children_t;
122 
123  // Iterate on all sites.
124  typedef mln::morpho::tree::up_site_piter<self_> up_site_piter;
125  typedef mln::morpho::tree::dn_site_piter<self_> dn_site_piter;
126  typedef up_site_piter site_piter;
127 
128  // Iterate on nodes only.
129  typedef mln::morpho::tree::up_node_piter<self_> up_node_piter;
130  typedef mln::morpho::tree::dn_node_piter<self_> dn_node_piter;
131  typedef up_node_piter node_piter;
132 
133  // Iterate on leaves only.
134  typedef mln::morpho::tree::up_leaf_piter<self_> up_leaf_piter;
135  typedef mln::morpho::tree::dn_leaf_piter<self_> dn_leaf_piter;
136  typedef up_leaf_piter leaf_piter;
137 
138  typedef mln::morpho::tree::depth1st_piter<self_> depth1st_piter;
139 
140 
142  template <typename N>
143  data(const Image<I>& f,
144  const Site_Set<S>& s,
145  const Neighborhood<N>& nbh);
146 
150  data(const Image<I>& f,
151  const parent_t& parent,
152  const Site_Set<S>& s);
153 
155 
156  mln_rvalue(I) f(const mln_psite(I)& p) const;
157  const I& f() const;
158 
160 
162 
163  mln_rvalue(parent_t) parent(const mln_psite(I)& p) const;
164  const parent_t& parent_image() const;
165 
167 
169 
170  mln_rvalue(children_t) children(const mln_psite(I)& p) const;
171  const mln_ch_value(I, nodes_t)& children_image() const;
172 
174 
176 
177  const p_array<mln_psite(I)>& nodes() const;
178 
180 
182 
183  const p_array<mln_psite(I)>& leaves() const;
184 
186 
188 
189  const S& domain() const;
190 
192 
193 
194 
196 
197  bool is_valid() const;
198  bool is_root(const mln_psite(I)& p) const;
199  bool is_a_node(const mln_psite(I)& p) const;
200  bool is_a_non_root_node(const mln_psite(I)& p) const;
201  bool is_a_leaf(const mln_psite(I)& p) const;
202 
204 
205  unsigned nroots() const;
206 
207  protected:
208  void compute_children_();
209 
210  protected:
211  mln_ch_value(I, mln_psite(I)) parent_; // Parent image.
212  mln_ch_value(I, nodes_t) children_; // Children image.
213 
214  function f_; // f image containing values of the tree nodes.
215  sites_t s_; // Sorted site set of the tree sites. (domain(f_) includes s_).
216 
217  nodes_t nodes_; // Sorted node set.
218  leaves_t leaves_; // Sorted leaf set.
219  unsigned nroots_; // For non-contigous domain image purpose.
220  };
221 
222 
223  /* Iterators */
224 
225  template <typename T>
226  struct up_site_piter
227  : public mln::internal::piter_identity_< typename T::sites_t::bkd_piter, // Adaptee.
228  up_site_piter<T> > // Exact.
229  {
230  private:
231  typedef typename T::sites_t::bkd_piter Pi_;
232  typedef mln::internal::piter_identity_< Pi_, up_site_piter<T> > super_;
233 
234  public:
235  up_site_piter(const T& t)
236  {
237  this->change_target(t.domain());
238  }
239 
240  up_site_piter(const Pi_& pi)
241  : super_(pi)
242  {
243  }
244  };
245 
246  template <typename T>
247  struct dn_site_piter
248  : public mln::internal::piter_identity_< typename T::sites_t::fwd_piter, // Adaptee.
249  dn_site_piter<T> > // Exact.
250  {
251  private:
252  typedef typename T::sites_t::fwd_piter Pi_;
253  typedef mln::internal::piter_identity_< Pi_, dn_site_piter<T> > super_;
254 
255  public:
256  dn_site_piter(const T& t)
257  {
258  this->change_target(t.domain());
259  }
260 
261  dn_site_piter(const Pi_& pi)
262  : super_(pi)
263  {
264  }
265  };
266 
267  template <typename T>
268  struct up_node_piter
269  : public mln::internal::piter_identity_< typename T::nodes_t::fwd_piter, // Adaptee.
270  up_node_piter<T> > // Exact.
271  {
272  private:
273  typedef typename T::nodes_t::fwd_piter Pi_;
274  typedef mln::internal::piter_identity_< Pi_, up_node_piter<T> > super_;
275 
276  public:
277  up_node_piter(const T& t)
278  {
279  this->change_target(t.nodes());
280  }
281 
282  up_node_piter(const Pi_& pi)
283  : super_(pi)
284  {
285  }
286  };
287 
288  template <typename T>
289  struct dn_node_piter
290  : public mln::internal::piter_identity_< typename T::nodes_t::bkd_piter, // Adaptee.
291  dn_node_piter<T> > // Exact.
292  {
293  private:
294  typedef typename T::nodes_t::bkd_piter Pi_;
295  typedef mln::internal::piter_identity_< Pi_, dn_node_piter<T> > super_;
296 
297  public:
298  dn_node_piter(const T& t)
299  {
300  this->change_target(t.nodes());
301  }
302 
303  dn_node_piter(const Pi_& pi)
304  : super_(pi)
305  {
306  }
307  };
308 
309  template <typename T>
310  struct up_leaf_piter
311  : public mln::internal::piter_identity_< typename T::leaves_t::fwd_piter, // Adaptee.
312  up_leaf_piter<T> > // Exact.
313  {
314  private:
315  typedef typename T::leaves_t::fwd_piter Pi_;
316  typedef mln::internal::piter_identity_< Pi_, up_leaf_piter<T> > super_;
317 
318  public:
319  up_leaf_piter(const T& t)
320  {
321  this->change_target(t.leaves());
322  }
323 
324  up_leaf_piter(const Pi_& pi)
325  : super_(pi)
326  {
327  }
328  };
329 
330  template <typename T>
331  struct dn_leaf_piter
332  : public mln::internal::piter_identity_< typename T::leaves_t::bkd_piter, // Adaptee.
333  dn_leaf_piter<T> > // Exact.
334  {
335  private:
336  typedef typename T::leaves_t::bkd_piter Pi_;
337  typedef mln::internal::piter_identity_< Pi_, dn_leaf_piter<T> > super_;
338 
339  public:
340  dn_leaf_piter(const T& t)
341  {
342  this->change_target(t.leaves());
343  }
344 
345  dn_leaf_piter(const Pi_& pi)
346  : super_(pi)
347  {
348  }
349  };
350 
351  template <typename T>
352  class depth1st_piter
353  : public mln::internal::site_set_iterator_base< T, depth1st_piter<T> >
354  {
355  typedef depth1st_piter<T> self_;
356  typedef mln::internal::site_set_iterator_base<T, self_> super_;
357 
358  public:
359 
361  depth1st_piter();
362 
364  depth1st_piter(const T& t);
365 
366 
367  depth1st_piter(const T& t,
368  const mln_psite(T::function)& p);
369 
371  bool is_valid_() const;
372 
374  void invalidate_();
375 
377  void start_();
378 
380  void next_();
381 
383  void skip_children();
384 
385  protected:
386  using super_::p_;
387  using super_::s_;
388  std::deque<mln_psite(T::function)> stack_; // FIXME: implement p_stack.
389  const mln_psite(T::function)* root_;
390  };
391 
392  } // end of namespace mln::morpho::tree
393 
394  } // end of namespace mln::morpho
395 
396  template <typename I, typename S>
397  inline
398  std::ostream&
399  operator<< (std::ostream& os, const morpho::tree::data<I, S>& t);
400 
401 
402 # ifndef MLN_INCLUDE_ONLY
403 
404  namespace morpho
405  {
406 
407  namespace tree
408  {
409 
410  template <typename I, typename S>
411  inline
412  data<I, S>::data(const Image<I>& f,
413  const mln_ch_value(I, mln_psite(I))& parent,
414  const Site_Set<S>& s)
415  : parent_ (parent),
416  f_ (exact(f)),
417  s_ (exact(s))
418  {
419  compute_children_();
420  }
421 
422 
423 
424  template <typename I, typename S>
425  template <typename N>
426  inline
427  data<I,S>::data(const Image<I>& f,
428  const Site_Set<S>& s,
429  const Neighborhood<N>& nbh)
430  : f_(exact(f)),
431  s_(exact(s))
432  {
433  // Compute parent image.
434  const N& nbh_ = exact(nbh);
435  parent_ = morpho::tree::compute_parent(f_, nbh_, s_);
436 
437  compute_children_();
438  }
439 
440  template <typename I, typename S>
441  inline
442  void
444  {
445  initialize(children_, f_);
446 
447  // Store tree nodes.
448  nroots_ = 0;
449  mln_bkd_piter(S) p(s_);
450  for_all(p)
451  {
452  if (f_(parent_(p)) != f_(p))
453  {
454  nodes_.insert(p);
455  children_(parent_(p)).insert(p);
456  if (is_a_leaf(p))
457  leaves_.insert(p);
458  }
459  else if (parent_(p) == p) //it's a root.
460  {
461  nodes_.insert(p);
462  if (is_a_leaf(p)) // One pixel image...
463  leaves_.insert(p);
464  ++nroots_;
465  }
466  }
467  mln_assertion(leaves_.nsites() > 0);
468  }
469 
470 
471  template <typename I, typename S>
472  inline
473  mln_rvalue_(mln_ch_value(I, mln_psite(I)))
474  data<I,S>::parent(const mln_psite(I)& p) const
475  {
476  mln_precondition(parent_.domain().has(p));
477  return parent_(p);
478  }
479 
480  template <typename I, typename S>
481  inline
482  const mln_ch_value(I, mln_psite(I))&
484  {
485  mln_precondition(is_valid());
486  return parent_;
487  }
488 
489  template <typename I, typename S>
490  inline
491  bool
492  data<I,S>::is_valid() const
493  {
494  return parent_.is_valid(); // FIXME: and... (?)
495  }
496 
497  template <typename I, typename S>
498  inline
499  bool
500  data<I,S>::is_root(const mln_psite(I)& p) const
501  {
502  mln_precondition(is_valid());
503  mln_precondition(parent_.domain().has(p));
504  return parent_(p) == p;
505  }
506 
507 
508  template <typename I, typename S>
509  inline
510  bool
511  data<I,S>::is_a_node(const mln_psite(I)& p) const
512  {
513  mln_precondition(is_valid());
514  mln_precondition(parent_.domain().has(p));
515  return parent_(p) == p || f_(parent_(p)) != f_(p);
516  }
517 
518  template <typename I, typename S>
519  inline
520  bool
521  data<I,S>::is_a_non_root_node(const mln_psite(I)& p) const
522  {
523  mln_precondition(is_valid());
524  mln_precondition(parent_.domain().has(p));
525  return f_(parent_(p)) != f_(p);
526  }
527 
528 
529  template <typename I, typename S>
530  inline
531  bool
532  data<I,S>::is_a_leaf(const mln_psite(I)& p) const
533  {
534  mln_precondition(is_valid());
535  mln_precondition(children_.domain().has(p));
536  return children_(p).nsites() == 0;
537  }
538 
539  template <typename I, typename S>
540  inline
541  const p_array<mln_psite(I)>&
542  data<I,S>::nodes() const
543  {
544  mln_precondition(is_valid());
545  return nodes_;
546  }
547 
548  template <typename I, typename S>
549  inline
550  const p_array<mln_psite(I)>&
551  data<I,S>::leaves() const
552  {
553  mln_precondition(is_valid());
554  return leaves_;
555  }
556 
557  template <typename I, typename S>
558  inline
559  const S&
560  data<I,S>::domain() const
561  {
562  return s_;
563  }
564 
565  template <typename I, typename S>
566  inline
567  unsigned
568  data<I,S>::nroots() const
569  {
570  return nroots_;
571  }
572 
573  template <typename I, typename S>
574  inline
575  const I&
576  data<I,S>::f() const
577  {
578  return f_;
579  }
580 
581  template <typename I, typename S>
582  inline
583  mln_rvalue(I)
584  data<I,S>::f(const mln_psite(I)& p) const
585  {
586  return f_(p);
587  }
588 
589  template <typename I, typename S>
590  inline
591  mln_rvalue_(mln_ch_value(I, p_array<mln_psite(I)>))
592  data<I,S>::children(const mln_psite(I)& p) const
593  {
594  mln_precondition(is_a_node(p));
595  return children_(p);
596  }
597 
598  template <typename I, typename S>
599  inline
600  const mln_ch_value(I, p_array<mln_psite(I)>)&
602  {
603  return children_;
604  }
605 
606 
607 
608  // Iterators.
609 
610 
611  template <typename T>
612  inline
614  : root_ (0)
615  {
616  }
617 
618  template <typename T>
619  inline
621  : root_ (0)
622  {
623  this->change_target(t);
624  }
625 
626  template <typename T>
627  inline
629  const mln_psite(T::function)& p)
630  : root_ (&p)
631  {
632  mln_assertion(t.is_a_node(p));
633  this->change_target(t);
634  }
635 
636  template <typename T>
637  inline
638  bool
640  {
641  return !stack_.empty();
642  }
643 
644  template <typename T>
645  inline
646  void
648  {
649  stack_.clear();
650  }
651 
652  template <typename T>
653  inline
654  void
656  {
657  this->invalidate();
658  stack_.push_back(mln_psite(T::function)()); // needed for last element.
659 
660  if (root_)
661  stack_.push_back(*root_);
662  else
663  {
664  mln_dn_node_piter(T) n(*s_);
665  unsigned roots = 0;
666  for (n.start(); n.is_valid() && roots < s_->nroots(); n.next())
667  if (s_->is_root(n))
668  {
669  stack_.push_back(n);
670  roots++;
671  }
672  }
673 
674  this->next();
675  }
676 
677  template <typename T>
678  inline
679  void
681  {
682  p_ = stack_.back();
683  stack_.pop_back();
684  if (! this->is_valid())
685  return;
686 
687  // mln_invariant(p_.is_valid());
688  // std::cout << "children(p).size = " << s_->children(p_).nsites() << std::endl;
689  // if (s_->children(p_).nsites() != 0)
690  // {
691  // std::cout << "elt[0] = " << s_->children(p_)[0].to_site().graph().data_hook_() << std::endl;
692  // std::cout << "elt[0] = " << s_->children(p_)[0] << std::endl;
693  // }
694  // std::cout << s_->children(p_) << std::endl;
695 
696  mln_fwd_piter(T::nodes_t) child(s_->children(p_));
697  for_all(child)
698  {
699  // std::cout << child.to_site().graph().data_hook_() << std::endl;
700  // mln_invariant(s_->parent(child) == p_);
701  stack_.push_back(child);
702  }
703  }
704 
705  template <typename T>
706  inline
707  void
709  {
710  while (stack_.size() != 1 && s_->parent(stack_.back()) == p_)
711  stack_.pop_back();
712  }
713 
714  } // end of namespace mln::morpho::tree
715 
716  } // end of namespace mln::morpho
717 
718  template <typename I, typename S>
719  inline
720  std::ostream&
721  operator<< (std::ostream& os, const morpho::tree::data<I, S>& t)
722  {
723  typedef morpho::tree::data<I, S> self_t;
724 
725  {
726  typedef p_array<mln_psite(self_t)> A;
727 
728  mln_ch_value(typename self_t::function, A) content;
729  initialize(content, t.f());
730 
731  os << "Nodes:\tValue:\tPoints" << std::endl;
732 
733  mln_up_site_piter(self_t) p(t);
734  for_all(p)
735  if (t.is_a_node(p))
736  {
737  os << p << "\t" << t.f(p) << "\t" << content(p) << std::endl;
738  content(p).clear();
739  }
740  else
741  content(t.parent(p)).insert(p);
742  }
743 
744  {
745  typename self_t::depth1st_piter n(t);
746  mln_psite(self_t) old;
747 
748  os << std::endl << "Hierarchy: " << std::endl;
749  n.start();
750 
751  if (!n.is_valid())
752  return os;
753 
754  for (old = n, n.next(); n.is_valid(); old = n, n.next())
755  {
756  if (old == t.parent(n))
757  os << old << " <- ";
758  else
759  os << old << std::endl
760  << "\t" << t.parent(n) << " <- ";
761  }
762 
763  os << old << std::endl;
764  return os;
765  }
766 
767  }
768 
769 # endif // ! MLN_INCLUDE_ONLY
770 
771 } // end of namespace mln
772 
773 
774 #endif // ! MLN_MORPHO_TREE_DATA_HH