27 #ifndef MLN_MORPHO_TREE_IMLP_DUAL_UNION_FIND_HH
28 # define MLN_MORPHO_TREE_IMLP_DUAL_UNION_FIND_HH
42 # include <mln/data/fill.hh>
44 # include <mln/geom/nsites.hh>
45 # include <mln/geom/translate.hh>
47 # include <mln/morpho/tree/data.hh>
49 # include <mln/util/timer.hh>
76 template <
typename I,
typename S,
typename N>
88 # ifndef MLN_INCLUDE_ONLY
99 mln_psite(I) find_root(I& zpar,
100 const mln_psite(I)&
p)
106 mln_psite(I) x = zpar(p);
111 for (mln_psite(I) y = p; y != x; y = tmp)
121 template <
typename I>
124 update_m_parent(
const I& f,
125 mln_ch_value(I, mln_psite(I))& parent,
126 mln_ch_value(I,
bool)& deja_vu,
128 const mln_domain(I)& d_ext,
129 const mln_psite(I)& p)
131 typedef mln_psite(I) P;
136 mln_assertion(d_ext.has(q));
138 while (d_ext.has(x) && f(q) == f(x) && q != x)
146 if (f(x) == f(parent(x)))
147 x = (parent(q) = parent(x));
163 update_m_parent(f, parent, deja_vu, sset, d_ext, q);
173 for (P i = p, tmp = parent(i); i != q; i = tmp, tmp = parent(i))
186 template <
typename I,
typename S,
typename N>
190 const Site_Set<S>& s_f_,
191 const Site_Set<S>& s_m_,
192 const Neighborhood<N>& nbh_)
194 mln_trace(
"morpho::tree::impl::generic::dual_union_find");
198 internal::t_prop.reset();
200 typedef mln_psite(I) P;
203 const I& f =
exact(f_);
204 const I& m =
exact(m_);
205 const S& s_f =
exact(s_f_);
206 const S& s_m =
exact(s_m_);
207 const N& nbh =
exact(nbh_);
210 mln_psite(I)::
delta dp(literal::zero);
211 mln_domain(I) d_f = f.domain();
212 mln_domain(I) d_ext = f.domain();
213 mln_domain(I) d = f.domain();
216 dp[0] = d.pmax()[0] - d.pmin()[0] + 1;
222 mln_concrete(I) fext;
223 mln_ch_value(I, P) parent;
224 p_array<mln_psite(I)> s;
227 fext = geom::
translate(m, dp.to_vec(), f, d);
229 s.reserve(geom::
nsites(fext));
234 mln_ch_value(I,
bool) deja_vu;
235 mln_ch_value(I, P) zpar;
241 mln_bkd_piter(S) p_f(s_f);
242 mln_bkd_piter(S) p_m(s_m);
247 while (p_m.is_valid() || p_f.is_valid())
249 mln_bkd_piter(S)& it = (!p_f.is_valid() || (p_m.is_valid() && f(p_f) <= m(p_m))) ? p_m : p_f;
254 mln_assertion(!(deja_vu(p) && deja_vu(ext)));
257 mln_assertion(m(p) >= f(p));
262 P r = internal::find_root(zpar, ext);
270 mln_assertion(f(p) > m(p));
276 mln_niter(N) n(nbh, ext);
278 if (d_ext.has(n) && deja_vu(n))
280 P r = internal::find_root(zpar, n);
289 else if (f(p) <= m(p))
292 mln_niter(N) n(nbh, ext);
294 if (d_ext.has(n) && deja_vu(n))
296 P r = internal::find_root(zpar, n);
316 mln_ch_value(I,
bool) deja_vu(d_ext);
318 mln_fwd_piter(S) p(s_f);
322 if (!f.domain().has(q))
323 internal::update_m_parent(fext, parent, deja_vu, s, d_ext, p);
324 else if (fext(parent(q)) == f(q))
325 parent(p) = parent(q);
328 mln_assertion((q = parent(p)) == parent(q) || fext(q) != fext(parent(q)));
334 tree::data<I, p_array<mln_psite(I)> > tree(fext, parent, s);
343 # endif // ! MLN_INCLUDE_ONLY
351 #endif // !MLN_MORPHO_TREE_IMLP_DUAL_UNION_FIND_HH