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