attribute_union_find.hh

00001 // Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016 // Boston, MA 02110-1301, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef OLENA_ATTRIBUTE_UNION_FIND_HH
00029 # define OLENA_ATTRIBUTE_UNION_FIND_HH
00030 
00031 #include <oln/level/fill.hh>
00032 
00033 #include <ntg/bin.hh>
00034 
00035 #include <vector>
00036 #include <oln/utils/histogram.hh>
00037 #include <oln/utils/qsort.hh>
00038 #include <oln/morpho/attributes.hh>
00039 
00040 namespace oln {
00041   namespace morpho {
00042     namespace fast {
00043       namespace tarjan {
00044 
00056         template<class T, class ATTRIBUTE, class Env = attr_env_type(ATTRIBUTE)>
00057         struct tarjan_set
00058         {
00059           typedef oln_point_type(T)                     point_type; 
00060           typedef oln_value_type(T)                     data_type; 
00061           typedef oln_concrete_type(T)                  image_type; 
00062           typedef typename ATTRIBUTE::lambda_type       lambda_type; 
00063           typedef Env                                   env_type; 
00064 
00070           tarjan_set(const image_type& ima, const env_type &env) : input_(ima),
00071                                                                    parent_(ima.size()),
00072                                                                    aux_data_(ima.size()),
00073                                                                    env_(env)
00074           {
00075             level::fill(parent_, INACTIVE());
00076           }
00077 
00086           template<bool closing, class N>
00087           image_type
00088           get_comptute(const lambda_type & lambda,
00089                        const abstract::neighborhood<N>& Ng)
00090           {
00091             lambda_ = &lambda;
00092 
00093             std::vector<point_type>     I;//(/*input_.npoints()*/);
00094 
00095             // FIXME: make both version avialble: qsort and dsort
00096             //      oln::utils::select_distrib_sort<closing>()(input_, I);
00097             oln::utils::select_q_sort<closing>()(input_, I);
00098 
00099             level::fill(aux_data_, ntg_sup_val(lambda_type));
00100             aux_data_.border_adapt_assign(Ng.delta(), ntg_sup_val(lambda_type));
00101 
00102             // We are ready to perform stuff
00103             for (unsigned int p = 0; p < I.size(); ++p)
00104               {
00105                 point_type p_p = I[p];
00106                 make_set(p_p);
00107                 oln_neighb_type(N) Q_prime(Ng, p_p);
00108                 for_all (Q_prime)
00109                   if (is_proc(Q_prime))
00110                     uni(Q_prime.cur(), p_p);
00111               }
00112 
00113             // Resolving phase
00114             image_type output(input_.size());
00115             for (int p = I.size() - 1; p >= 0; --p)
00116               {
00117                 point_type p_p = I[p];
00118                 if ((parent_[p_p] == ACTIVE()) ||  (parent_[p_p] == INACTIVE()))
00119                   output[p_p] = input_[p_p];
00120                 else
00121                   output[p_p] = output[parent_[p_p]];
00122                 // this code is equivalent to
00123                 //      output[I[p].first] = input_[find_root(I[p].first)];
00124 
00125               }
00126             return output;
00127           }
00128 
00129         protected:
00133           static const point_type&
00134           ACTIVE()
00135           {
00136             static struct foo_def
00137             {
00138               point_type elt;
00139               foo_def()
00140               {
00141                 const unsigned dim = point_type::dim;
00142                 for (unsigned i = 0; i < dim; ++i )
00143                   elt.nth(i) = -1;
00144               }
00145             } tmp;
00146 
00147             return tmp.elt;
00148           }
00149 
00153           static const point_type&
00154           INACTIVE()
00155           {
00156             static struct foo_def
00157             {
00158               point_type elt;
00159               foo_def() {
00160                 const unsigned dim = point_type::dim;
00161                 for (unsigned i = 0; i < dim; ++i )
00162                   elt.nth(i) = -2;
00163               }
00164             } tmp;
00165 
00166             return tmp.elt;
00167           }
00168 
00173           void
00174           make_set(const point_type& x)
00175           {
00176             precondition(parent_[x] == INACTIVE());
00177             parent_[x] = ACTIVE();
00178             aux_data_[x] = ATTRIBUTE(input_, x, env_);
00179           }
00180 
00185           point_type
00186           find_root(const point_type& x)
00187           {
00188             if ((parent_[x] != ACTIVE()) && (parent_[x] != INACTIVE()))
00189               {
00190                 parent_[x] = find_root(parent_[x]);
00191                 return parent_[x];
00192               }
00193             else
00194               return x;
00195           }
00196 
00202           bool
00203           criterion(const point_type& x, const point_type& y)
00204           {
00205             precondition((parent_[x] == ACTIVE()) || (parent_[x] == INACTIVE()));
00206             precondition((parent_[y] == ACTIVE()) || (parent_[y] == INACTIVE()));
00207             return ( (input_[x] == input_[y]) || (aux_data_[x] < *lambda_));
00208           }
00209 
00215           void
00216           uni(const point_type& n, const point_type& p)
00217           {
00218             point_type r = find_root(n);
00219             if (r != p)
00220               if (criterion(r,p))
00221                 {
00222                   aux_data_[p] += aux_data_[r];
00223                   parent_[r] = p;
00224                 }
00225               else
00226                 {
00227                   aux_data_[p] = *lambda_;
00228                 }
00229           }
00230 
00234           bool is_proc(const point_type &p) const
00235           {
00236             //FIXME: odd way to call !=,  but it is to help the compiler
00237             //to find the good one  when ATTRIBUTE is templeted by types
00238             //in other namespaces.
00239 
00240             // return aux_data_[p] != ntg_max_val(lambda_type);
00241             return aux_data_[p].operator!=(ntg_sup_val(lambda_type));
00242           };
00243 
00244 
00245           const image_type                      &input_; 
00246           typename mute<T, point_type>::ret     parent_; 
00247           typename mute<T, ATTRIBUTE>::ret      aux_data_; 
00248           const lambda_type                     *lambda_; 
00249           const env_type                        env_; 
00250         };
00251       } // !tarjan
00252     } // !fast
00253   } // !morph
00254 } // !oln
00255 #endif

Generated on Tue Feb 20 20:18:01 2007 for Olena by  doxygen 1.5.1