26 #ifndef MLN_MORPHO_TREE_IMLP_DUAL_UNION_FIND_HH
27 # define MLN_MORPHO_TREE_IMLP_DUAL_UNION_FIND_HH
41 # include <mln/data/fill.hh>
43 # include <mln/geom/nsites.hh>
44 # include <mln/geom/translate.hh>
46 # include <mln/morpho/tree/data.hh>
48 # include <mln/util/timer.hh>
75 template <
typename I,
typename S,
typename N>
77 dual_union_find(
const Image<I>& f,
79 const Site_Set<S>& s_f,
80 const Site_Set<S>& s_m,
81 const Neighborhood<N>& nbh);
87 # ifndef MLN_INCLUDE_ONLY
93 static util::timer t_prop;
98 mln_psite(I) find_root(I& zpar,
99 const mln_psite(I)& p)
105 mln_psite(I) x = zpar(p);
110 for (mln_psite(I) y = p; y != x; y = tmp)
120 template <
typename I>
123 update_m_parent(
const I& f,
124 mln_ch_value(I, mln_psite(I))& parent,
125 mln_ch_value(I,
bool)& deja_vu,
126 p_array< mln_psite(I) >& sset,
127 const mln_domain(I)& d_ext,
128 const mln_psite(I)& p)
130 typedef mln_psite(I) P;
135 mln_assertion(d_ext.has(q));
137 while (d_ext.has(x) && f(q) == f(x) && q != x)
145 if (f(x) == f(parent(x)))
146 x = (parent(q) = parent(x));
162 update_m_parent(f, parent, deja_vu, sset, d_ext, q);
172 for (P i = p, tmp = parent(i); i != q; i = tmp, tmp = parent(i))
185 template <
typename I,
typename S,
typename N>
187 dual_union_find(
const Image<I>& f_,
189 const Site_Set<S>& s_f_,
190 const Site_Set<S>& s_m_,
191 const Neighborhood<N>& nbh_)
193 trace::entering(
"morpho::tree::impl::generic::dual_union_find");
197 internal::t_prop.reset();
199 typedef mln_psite(I) P;
202 const I& f = exact(f_);
203 const I& m = exact(m_);
204 const S& s_f = exact(s_f_);
205 const S& s_m = exact(s_m_);
206 const N& nbh = exact(nbh_);
209 mln_psite(I)::delta dp(literal::zero);
210 mln_domain(I) d_f = f.domain();
211 mln_domain(I) d_ext = f.domain();
212 mln_domain(I) d = f.domain();
215 dp[0] = d.pmax()[0] - d.pmin()[0] + 1;
221 mln_concrete(I) fext;
222 mln_ch_value(I, P) parent;
223 p_array<mln_psite(I)> s;
226 fext = geom::translate(m, dp.to_vec(), f, d);
227 initialize(parent, fext);
228 s.reserve(geom::nsites(fext));
233 mln_ch_value(I,
bool) deja_vu;
234 mln_ch_value(I, P) zpar;
236 initialize(deja_vu, fext);
237 initialize(zpar, fext);
238 mln::
data::fill(deja_vu, false);
240 mln_bkd_piter(S) p_f(s_f);
241 mln_bkd_piter(S) p_m(s_m);
246 while (p_m.is_valid() || p_f.is_valid())
248 mln_bkd_piter(S)& it = (!p_f.is_valid() || (p_m.is_valid() && f(p_f) <= m(p_m))) ? p_m : p_f;
259 mln_assertion(!(deja_vu(p) && deja_vu(ext)));
262 mln_assertion(m(p) >= f(p));
267 P r = internal::find_root(zpar, ext);
275 mln_assertion(f(p) > m(p));
281 mln_niter(N) n(nbh, ext);
283 if (d_ext.has(n) && deja_vu(n))
285 P r = internal::find_root(zpar, n);
295 else if (f(p) <= m(p))
298 mln_niter(N) n(nbh, ext);
300 if (d_ext.has(n) && deja_vu(n))
302 P r = internal::find_root(zpar, n);
318 std::cout <<
">> MAJ zpar: " << internal::t_prop <<
" s" << std::endl;
319 std::cout <<
"Parent construction: " << tm <<
" s" << std::endl;
324 mln_ch_value(I,
bool) deja_vu(d_ext);
325 mln::
data::fill(deja_vu, false);
326 mln_fwd_piter(S) p(s_f);
330 if (!f.domain().has(q))
331 internal::update_m_parent(fext, parent, deja_vu, s, d_ext, p);
332 else if (fext(parent(q)) == f(q))
333 parent(p) = parent(q);
336 mln_assertion((q = parent(p)) == parent(q) || fext(q) != fext(parent(q)));
339 std::cout <<
"Canonization: " << tm <<
" s" << std::endl;
343 tree::data<I, p_array<mln_psite(I)> > tree(fext, parent, s);
344 trace::exiting(
"morpho::tree::impl::generic::dual_union_find");
353 # endif // ! MLN_INCLUDE_ONLY
361 #endif // !MLN_MORPHO_TREE_IMLP_DUAL_UNION_FIND_HH