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 #ifndef MLN_MORPHO_TREE_DATA_HH
00027 # define MLN_MORPHO_TREE_DATA_HH
00028
00033
00034 # include <mln/morpho/tree/compute_parent.hh>
00035 # include <mln/core/site_set/p_array.hh>
00036 # include <mln/core/internal/site_set_iterator_base.hh>
00037 # include <mln/core/internal/piter_identity.hh>
00038
00039 # include <deque>
00040 # include <iostream>
00041
00042 # define mln_up_site_piter(T) typename T::up_site_piter
00043 # define mln_dn_site_piter(T) typename T::dn_site_piter
00044 # define mln_up_node_piter(T) typename T::up_node_piter
00045 # define mln_dn_node_piter(T) typename T::dn_node_piter
00046 # define mln_up_leaf_piter(T) typename T::up_leaf_piter
00047 # define mln_dn_leaf_piter(T) typename T::dn_leaf_piter
00048 # define mln_site_piter(T) typename T::site_piter
00049 # define mln_node_piter(T) typename T::node_piter
00050 # define mln_leaf_piter(T) typename T::leaf_piter
00051 # define mln_depth1st_piter(T) typename T::depth1st_piter
00052
00053 # define mln_up_site_piter_(T) T::up_site_piter
00054 # define mln_dn_site_piter_(T) T::dn_site_piter
00055 # define mln_up_node_piter_(T) T::up_node_piter
00056 # define mln_dn_node_piter_(T) T::dn_node_piter
00057 # define mln_up_leaf_piter_(T) T::up_leaf_piter
00058 # define mln_dn_leaf_piter_(T) T::dn_leaf_piter
00059 # define mln_site_piter_(T) T::site_piter
00060 # define mln_node_piter_(T) T::node_piter
00061 # define mln_leaf_piter_(T) T::leaf_piter
00062 # define mln_depth1st_piter_(T) T::depth1st_piter
00063
00064
00065 namespace mln
00066 {
00067
00068 namespace morpho
00069 {
00070
00071 namespace tree
00072 {
00073
00074
00075
00077 template <typename T> struct up_site_piter;
00078
00080 template <typename T> struct dn_site_piter;
00081
00083 template <typename T> struct up_node_piter;
00084
00086 template <typename T> struct dn_node_piter;
00087
00089 template <typename T> struct up_leaf_piter;
00090
00092 template <typename T> struct dn_leaf_piter;
00093
00095 template <typename T> struct depth1st_piter;
00096
00097
00098 template <typename I, typename S>
00099 class data
00100 {
00101 typedef data<I, S> self_;
00102
00103 public:
00105 typedef I function;
00107 typedef mln_psite(I) psite;
00108 typedef mln_site(I) site;
00110 typedef S sites_t;
00112 typedef p_array<mln_psite(I)> nodes_t;
00114 typedef p_array<mln_psite(I)> leaves_t;
00115
00117 typedef mln_ch_value(I, mln_psite(I)) parent_t;
00118
00120 typedef mln_ch_value(I, nodes_t) children_t;
00121
00122
00123 typedef mln::morpho::tree::up_site_piter<self_> up_site_piter;
00124 typedef mln::morpho::tree::dn_site_piter<self_> dn_site_piter;
00125 typedef up_site_piter site_piter;
00126
00127
00128 typedef mln::morpho::tree::up_node_piter<self_> up_node_piter;
00129 typedef mln::morpho::tree::dn_node_piter<self_> dn_node_piter;
00130 typedef up_node_piter node_piter;
00131
00132
00133 typedef mln::morpho::tree::up_leaf_piter<self_> up_leaf_piter;
00134 typedef mln::morpho::tree::dn_leaf_piter<self_> dn_leaf_piter;
00135 typedef up_leaf_piter leaf_piter;
00136
00137 typedef mln::morpho::tree::depth1st_piter<self_> depth1st_piter;
00138
00139
00141 template <typename N>
00142 data(const Image<I>& f,
00143 const Site_Set<S>& s,
00144 const Neighborhood<N>& nbh);
00145
00149 data(const Image<I>& f,
00150 const parent_t& parent,
00151 const Site_Set<S>& s);
00152
00154
00155 mln_rvalue(I) f(const mln_psite(I)& p) const;
00156 const I& f() const;
00157
00159
00161
00162 mln_rvalue(parent_t) parent(const mln_psite(I)& p) const;
00163 const parent_t& parent_image() const;
00164
00166
00168
00169 mln_rvalue(children_t) children(const mln_psite(I)& p) const;
00170 const mln_ch_value(I, nodes_t)& children_image() const;
00171
00173
00175
00176 const p_array<mln_psite(I)>& nodes() const;
00177
00179
00181
00182 const p_array<mln_psite(I)>& leaves() const;
00183
00185
00187
00188 const S& domain() const;
00189
00191
00192
00193
00195
00196 bool is_valid() const;
00197 bool is_root(const mln_psite(I)& p) const;
00198 bool is_a_node(const mln_psite(I)& p) const;
00199 bool is_a_non_root_node(const mln_psite(I)& p) const;
00200 bool is_a_leaf(const mln_psite(I)& p) const;
00201
00203
00204 unsigned nroots() const;
00205
00206 protected:
00207 void compute_children_();
00208
00209 protected:
00210 mln_ch_value(I, mln_psite(I)) parent_;
00211 mln_ch_value(I, nodes_t) children_;
00212
00213 function f_;
00214 sites_t s_;
00215
00216 nodes_t nodes_;
00217 leaves_t leaves_;
00218 unsigned nroots_;
00219 };
00220
00221
00222
00223
00224 template <typename T>
00225 struct up_site_piter
00226 : public mln::internal::piter_identity_< typename T::sites_t::bkd_piter,
00227 up_site_piter<T> >
00228 {
00229 private:
00230 typedef typename T::sites_t::bkd_piter Pi_;
00231 typedef mln::internal::piter_identity_< Pi_, up_site_piter<T> > super_;
00232
00233 public:
00234 up_site_piter(const T& t)
00235 {
00236 this->change_target(t.domain());
00237 }
00238
00239 up_site_piter(const Pi_& pi)
00240 : super_(pi)
00241 {
00242 }
00243 };
00244
00245 template <typename T>
00246 struct dn_site_piter
00247 : public mln::internal::piter_identity_< typename T::sites_t::fwd_piter,
00248 dn_site_piter<T> >
00249 {
00250 private:
00251 typedef typename T::sites_t::fwd_piter Pi_;
00252 typedef mln::internal::piter_identity_< Pi_, dn_site_piter<T> > super_;
00253
00254 public:
00255 dn_site_piter(const T& t)
00256 {
00257 this->change_target(t.domain());
00258 }
00259
00260 dn_site_piter(const Pi_& pi)
00261 : super_(pi)
00262 {
00263 }
00264 };
00265
00266 template <typename T>
00267 struct up_node_piter
00268 : public mln::internal::piter_identity_< typename T::nodes_t::fwd_piter,
00269 up_node_piter<T> >
00270 {
00271 private:
00272 typedef typename T::nodes_t::fwd_piter Pi_;
00273 typedef mln::internal::piter_identity_< Pi_, up_node_piter<T> > super_;
00274
00275 public:
00276 up_node_piter(const T& t)
00277 {
00278 this->change_target(t.nodes());
00279 }
00280
00281 up_node_piter(const Pi_& pi)
00282 : super_(pi)
00283 {
00284 }
00285 };
00286
00287 template <typename T>
00288 struct dn_node_piter
00289 : public mln::internal::piter_identity_< typename T::nodes_t::bkd_piter,
00290 dn_node_piter<T> >
00291 {
00292 private:
00293 typedef typename T::nodes_t::bkd_piter Pi_;
00294 typedef mln::internal::piter_identity_< Pi_, dn_node_piter<T> > super_;
00295
00296 public:
00297 dn_node_piter(const T& t)
00298 {
00299 this->change_target(t.nodes());
00300 }
00301
00302 dn_node_piter(const Pi_& pi)
00303 : super_(pi)
00304 {
00305 }
00306 };
00307
00308 template <typename T>
00309 struct up_leaf_piter
00310 : public mln::internal::piter_identity_< typename T::leaves_t::fwd_piter,
00311 up_leaf_piter<T> >
00312 {
00313 private:
00314 typedef typename T::leaves_t::fwd_piter Pi_;
00315 typedef mln::internal::piter_identity_< Pi_, up_leaf_piter<T> > super_;
00316
00317 public:
00318 up_leaf_piter(const T& t)
00319 {
00320 this->change_target(t.leaves());
00321 }
00322
00323 up_leaf_piter(const Pi_& pi)
00324 : super_(pi)
00325 {
00326 }
00327 };
00328
00329 template <typename T>
00330 struct dn_leaf_piter
00331 : public mln::internal::piter_identity_< typename T::leaves_t::bkd_piter,
00332 dn_leaf_piter<T> >
00333 {
00334 private:
00335 typedef typename T::leaves_t::bkd_piter Pi_;
00336 typedef mln::internal::piter_identity_< Pi_, dn_leaf_piter<T> > super_;
00337
00338 public:
00339 dn_leaf_piter(const T& t)
00340 {
00341 this->change_target(t.leaves());
00342 }
00343
00344 dn_leaf_piter(const Pi_& pi)
00345 : super_(pi)
00346 {
00347 }
00348 };
00349
00350 template <typename T>
00351 class depth1st_piter
00352 : public mln::internal::site_set_iterator_base< T, depth1st_piter<T> >
00353 {
00354 typedef depth1st_piter<T> self_;
00355 typedef mln::internal::site_set_iterator_base<T, self_> super_;
00356
00357 public:
00358
00360 depth1st_piter();
00361
00363 depth1st_piter(const T& t);
00364
00365
00366 depth1st_piter(const T& t,
00367 const mln_psite(T::function)& p);
00368
00370 bool is_valid_() const;
00371
00373 void invalidate_();
00374
00376 void start_();
00377
00379 void next_();
00380
00382 void skip_children();
00383
00384 protected:
00385 using super_::p_;
00386 using super_::s_;
00387 std::deque<mln_psite(T::function)> stack_;
00388 const mln_psite(T::function)* root_;
00389 };
00390
00391 }
00392
00393 }
00394
00395 template <typename I, typename S>
00396 inline
00397 std::ostream&
00398 operator<< (std::ostream& os, const morpho::tree::data<I, S>& t);
00399
00400
00401 # ifndef MLN_INCLUDE_ONLY
00402
00403 namespace morpho
00404 {
00405
00406 namespace tree
00407 {
00408
00409 template <typename I, typename S>
00410 inline
00411 data<I, S>::data(const Image<I>& f,
00412 const mln_ch_value(I, mln_psite(I))& parent,
00413 const Site_Set<S>& s)
00414 : parent_ (parent),
00415 f_ (exact(f)),
00416 s_ (exact(s))
00417 {
00418 compute_children_();
00419 }
00420
00421
00422
00423 template <typename I, typename S>
00424 template <typename N>
00425 inline
00426 data<I,S>::data(const Image<I>& f,
00427 const Site_Set<S>& s,
00428 const Neighborhood<N>& nbh)
00429 : f_(exact(f)),
00430 s_(exact(s))
00431 {
00432
00433 const N& nbh_ = exact(nbh);
00434 parent_ = morpho::tree::compute_parent(f_, nbh_, s_);
00435
00436 compute_children_();
00437 }
00438
00439 template <typename I, typename S>
00440 inline
00441 void
00442 data<I, S>::compute_children_()
00443 {
00444 initialize(children_, f_);
00445
00446
00447 nroots_ = 0;
00448 mln_bkd_piter(S) p(s_);
00449 for_all(p)
00450 {
00451 if (f_(parent_(p)) != f_(p))
00452 {
00453 nodes_.insert(p);
00454 children_(parent_(p)).insert(p);
00455 if (is_a_leaf(p))
00456 leaves_.insert(p);
00457 }
00458 else if (parent_(p) == p)
00459 {
00460 nodes_.insert(p);
00461 if (is_a_leaf(p))
00462 leaves_.insert(p);
00463 ++nroots_;
00464 }
00465 }
00466 mln_assertion(leaves_.nsites() > 0);
00467 }
00468
00469
00470 template <typename I, typename S>
00471 inline
00472 mln_rvalue_(mln_ch_value(I, mln_psite(I)))
00473 data<I,S>::parent(const mln_psite(I)& p) const
00474 {
00475 mln_precondition(parent_.domain().has(p));
00476 return parent_(p);
00477 }
00478
00479 template <typename I, typename S>
00480 inline
00481 const mln_ch_value(I, mln_psite(I))&
00482 data<I,S>::parent_image() const
00483 {
00484 mln_precondition(is_valid());
00485 return parent_;
00486 }
00487
00488 template <typename I, typename S>
00489 inline
00490 bool
00491 data<I,S>::is_valid() const
00492 {
00493 return parent_.is_valid();
00494 }
00495
00496 template <typename I, typename S>
00497 inline
00498 bool
00499 data<I,S>::is_root(const mln_psite(I)& p) const
00500 {
00501 mln_precondition(is_valid());
00502 mln_precondition(parent_.domain().has(p));
00503 return parent_(p) == p;
00504 }
00505
00506
00507 template <typename I, typename S>
00508 inline
00509 bool
00510 data<I,S>::is_a_node(const mln_psite(I)& p) const
00511 {
00512 mln_precondition(is_valid());
00513 mln_precondition(parent_.domain().has(p));
00514 return parent_(p) == p || f_(parent_(p)) != f_(p);
00515 }
00516
00517 template <typename I, typename S>
00518 inline
00519 bool
00520 data<I,S>::is_a_non_root_node(const mln_psite(I)& p) const
00521 {
00522 mln_precondition(is_valid());
00523 mln_precondition(parent_.domain().has(p));
00524 return f_(parent_(p)) != f_(p);
00525 }
00526
00527
00528 template <typename I, typename S>
00529 inline
00530 bool
00531 data<I,S>::is_a_leaf(const mln_psite(I)& p) const
00532 {
00533 mln_precondition(is_valid());
00534 mln_precondition(children_.domain().has(p));
00535 return children_(p).nsites() == 0;
00536 }
00537
00538 template <typename I, typename S>
00539 inline
00540 const p_array<mln_psite(I)>&
00541 data<I,S>::nodes() const
00542 {
00543 mln_precondition(is_valid());
00544 return nodes_;
00545 }
00546
00547 template <typename I, typename S>
00548 inline
00549 const p_array<mln_psite(I)>&
00550 data<I,S>::leaves() const
00551 {
00552 mln_precondition(is_valid());
00553 return leaves_;
00554 }
00555
00556 template <typename I, typename S>
00557 inline
00558 const S&
00559 data<I,S>::domain() const
00560 {
00561 return s_;
00562 }
00563
00564 template <typename I, typename S>
00565 inline
00566 unsigned
00567 data<I,S>::nroots() const
00568 {
00569 return nroots_;
00570 }
00571
00572 template <typename I, typename S>
00573 inline
00574 const I&
00575 data<I,S>::f() const
00576 {
00577 return f_;
00578 }
00579
00580 template <typename I, typename S>
00581 inline
00582 mln_rvalue(I)
00583 data<I,S>::f(const mln_psite(I)& p) const
00584 {
00585 return f_(p);
00586 }
00587
00588 template <typename I, typename S>
00589 inline
00590 mln_rvalue_(mln_ch_value(I, p_array<mln_psite(I)>))
00591 data<I,S>::children(const mln_psite(I)& p) const
00592 {
00593 mln_precondition(is_a_node(p));
00594 return children_(p);
00595 }
00596
00597 template <typename I, typename S>
00598 inline
00599 const mln_ch_value(I, p_array<mln_psite(I)>)&
00600 data<I,S>::children_image() const
00601 {
00602 return children_;
00603 }
00604
00605
00606
00607
00608
00609
00610 template <typename T>
00611 inline
00612 depth1st_piter<T>::depth1st_piter()
00613 : root_ (0)
00614 {
00615 }
00616
00617 template <typename T>
00618 inline
00619 depth1st_piter<T>::depth1st_piter(const T& t)
00620 : root_ (0)
00621 {
00622 this->change_target(t);
00623 }
00624
00625 template <typename T>
00626 inline
00627 depth1st_piter<T>::depth1st_piter(const T& t,
00628 const mln_psite(T::function)& p)
00629 : root_ (&p)
00630 {
00631 mln_assertion(t.is_a_node(p));
00632 this->change_target(t);
00633 }
00634
00635 template <typename T>
00636 inline
00637 bool
00638 depth1st_piter<T>::is_valid_() const
00639 {
00640 return !stack_.empty();
00641 }
00642
00643 template <typename T>
00644 inline
00645 void
00646 depth1st_piter<T>::invalidate_()
00647 {
00648 stack_.clear();
00649 }
00650
00651 template <typename T>
00652 inline
00653 void
00654 depth1st_piter<T>::start_()
00655 {
00656 this->invalidate();
00657 stack_.push_back(mln_psite(T::function)());
00658
00659 if (root_)
00660 stack_.push_back(*root_);
00661 else
00662 {
00663 mln_dn_node_piter(T) n(*s_);
00664 unsigned roots = 0;
00665 for (n.start(); n.is_valid() && roots < s_->nroots(); n.next())
00666 if (s_->is_root(n))
00667 {
00668 stack_.push_back(n);
00669 roots++;
00670 }
00671 }
00672
00673 this->next();
00674 }
00675
00676 template <typename T>
00677 inline
00678 void
00679 depth1st_piter<T>::next_()
00680 {
00681 p_ = stack_.back();
00682 stack_.pop_back();
00683 if (! this->is_valid())
00684 return;
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 mln_fwd_piter(T::nodes_t) child(s_->children(p_));
00696 for_all(child)
00697 {
00698
00699
00700 stack_.push_back(child);
00701 }
00702 }
00703
00704 template <typename T>
00705 inline
00706 void
00707 depth1st_piter<T>::skip_children()
00708 {
00709 while (stack_.size() != 1 && s_->parent(stack_.back()) == p_)
00710 stack_.pop_back();
00711 }
00712
00713 }
00714
00715 }
00716
00717 template <typename I, typename S>
00718 inline
00719 std::ostream&
00720 operator<< (std::ostream& os, const morpho::tree::data<I, S>& t)
00721 {
00722 typedef morpho::tree::data<I, S> self_t;
00723
00724 {
00725 typedef p_array<mln_psite(self_t)> A;
00726
00727 mln_ch_value(typename self_t::function, A) content;
00728 initialize(content, t.f());
00729
00730 os << "Nodes:\tValue:\tPoints" << std::endl;
00731
00732 mln_up_site_piter(self_t) p(t);
00733 for_all(p)
00734 if (t.is_a_node(p))
00735 {
00736 os << p << "\t" << t.f(p) << "\t" << content(p) << std::endl;
00737 content(p).clear();
00738 }
00739 else
00740 content(t.parent(p)).insert(p);
00741 }
00742
00743 {
00744 typename self_t::depth1st_piter n(t);
00745 mln_psite(self_t) old;
00746
00747 std::cout << std::endl << "Hierarchy: " << std::endl;
00748 n.start();
00749
00750 if (!n.is_valid())
00751 return os;
00752
00753 for (old = n, n.next(); n.is_valid(); old = n, n.next())
00754 {
00755 if (old == t.parent(n))
00756 os << old << " <- ";
00757 else
00758 os << old << std::endl
00759 << "\t" << t.parent(n) << " <- ";
00760 }
00761
00762 os << old << std::endl;
00763 return os;
00764 }
00765
00766 }
00767
00768 # endif // ! MLN_INCLUDE_ONLY
00769
00770 }
00771
00772
00773 #endif // ! MLN_MORPHO_TREE_DATA_HH