• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

min_h.hh

00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_ACCU_STAT_MIN_H_HH
00027 # define MLN_ACCU_STAT_MIN_H_HH
00028 
00032 
00033 # include <mln/accu/internal/base.hh>
00034 # include <mln/accu/histo.hh>
00035 # include <mln/value/set.hh>
00036 # include <mln/util/pix.hh>
00037 
00038 
00039 namespace mln
00040 {
00041 
00042   namespace accu
00043   {
00044 
00045     namespace stat
00046     {
00047 
00048       // Forward declaration.
00049       template <typename V>
00050       struct min_h;
00051 
00052     } // end of namespace mln::accu::stat
00053 
00054     namespace meta
00055     {
00056 
00057       namespace stat
00058       {
00059 
00061         struct min_h : public Meta_Accumulator< min_h >
00062         {
00063           template <typename T>
00064           struct with
00065           {
00066             typedef accu::stat::min_h<T> ret;
00067           };
00068         };
00069 
00070       } // end of namespace mln::meta::stat
00071 
00072     } // end of namespace mln::meta
00073 
00074 
00075     namespace stat
00076     {
00077 
00082       //
00083       template <typename V>
00084       struct min_h : public mln::accu::internal::base< const V& , min_h<V> >
00085       {
00086         typedef V argument;
00087 
00088         min_h();
00089 
00092         void init();
00093         void   take(const argument& t);
00094         void   take_as_init_(const argument& t);
00095         void   take(const min_h<V>& other);
00096         void untake(const argument& t);
00098 
00099         unsigned card() const { return h_.sum(); }
00100 
00102         const argument& to_result() const;
00103 
00104         const accu::histo<V>& histo() const;
00105 
00108         bool is_valid() const;
00109 
00110         void debug_print_() const;
00111 
00112       protected:
00113 
00114         mutable accu::histo<V> h_;
00115         const value::set<V>& s_; // derived from h_
00116 
00117         mutable unsigned sum_;
00118         mutable bool valid_;
00119         mutable unsigned i_; // the min index
00120         mutable argument t_;    // the min value
00121 
00122         // Auxiliary methods
00123         void update_() const;
00124         void go_minus_() const;
00125         void go_plus_() const;
00126       };
00127 
00128 
00129 
00130       template <typename I> struct min_h< util::pix<I> >;
00131 
00132 
00133 # ifndef MLN_INCLUDE_ONLY
00134 
00135       template <typename V>
00136       inline
00137       min_h<V>::min_h()
00138         : h_(),
00139           s_(h_.vset())
00140       {
00141         init();
00142       }
00143 
00144       template <typename V>
00145       inline
00146       void
00147       min_h<V>::take(const argument& t)
00148       {
00149         if (h_.sum() == 0)
00150           {
00151             this->take_as_init_(t);
00152             return;
00153           }
00154         h_.take(t);
00155         if (t < t_)
00156           {
00157             ++sum_;
00158             valid_ = false;
00159           }
00160       }
00161 
00162       template <typename V>
00163       inline
00164       void
00165       min_h<V>::take(const min_h<V>& other)
00166       {
00167         // h_
00168         h_.take(other.h_);
00169         for (unsigned i = 0; i < i_; ++i)
00170           sum_ += other.h_[i];
00171         valid_ = false;
00172         // FIXME: Optimize.
00173       }
00174 
00175       template <typename V>
00176       inline
00177       void
00178       min_h<V>::untake(const argument& t)
00179       {
00180         mln_precondition(h_(t) != 0);
00181         h_.untake(t);
00182         if (h_.sum() == 0)
00183           {
00184             init();
00185             return;
00186           }
00187         if (t < t_)
00188           {
00189             mln_invariant(sum_ >= 1);
00190             --sum_;
00191             valid_ = false;
00192           }
00193         else
00194           if (t == t_ && h_[i_] == 0)
00195             valid_ = false;
00196       }
00197 
00198       template <typename V>
00199       inline
00200       void
00201       min_h<V>::update_() const
00202       {
00203         if (sum_ != 0)
00204           go_minus_();
00205         else
00206           if (h_[i_] == 0)
00207             go_plus_();
00208         valid_ = true;
00209       }
00210 
00211       template <typename V>
00212       inline
00213       void
00214       min_h<V>::go_minus_() const
00215       {
00216         do
00217           {
00218             --i_;
00219             if (h_[i_] != 0)
00220               sum_ -= h_[i_];
00221           }
00222         while (sum_ != 0);
00223         t_ = s_[i_];
00224       }
00225 
00226       template <typename V>
00227       inline
00228       void
00229       min_h<V>::go_plus_() const
00230       {
00231         do
00232           ++i_;
00233         while (h_[i_] == 0);
00234         t_ = s_[i_];
00235       }
00236 
00237       template <typename V>
00238       inline
00239       void
00240       min_h<V>::init()
00241       {
00242         h_.init();
00243         sum_ = 0;
00244         i_ = mln_max(argument);
00245         t_ = s_[i_];
00246         valid_ = true;
00247       }
00248 
00249       template <typename V>
00250       inline
00251       void
00252       min_h<V>::take_as_init_(const argument& t)
00253       {
00254         h_.take(t);
00255         sum_ = 0;
00256         i_ = s_.index_of(t);
00257         t_ = t;
00258         valid_ = true;
00259       }
00260 
00261       template <typename V>
00262       inline
00263       const typename min_h<V>::argument&
00264       min_h<V>::to_result() const
00265       {
00266         if (! valid_)
00267           update_();
00268         return t_;
00269       }
00270 
00271       template <typename V>
00272       inline
00273       const accu::histo<V>&
00274       min_h<V>::histo() const
00275       {
00276         return h_;
00277       }
00278 
00279       template <typename V>
00280       inline
00281       bool
00282       min_h<V>::is_valid() const
00283       {
00284         return true;
00285       }
00286 
00287 
00288       template <typename V>
00289       inline
00290       void
00291       min_h<V>::debug_print_() const
00292       {
00293         std::cout << "h={" << h_ << "} ";
00294         std::cout << "sum=" << sum_ << ' '
00295                   << "valid=" << valid_ << ' '
00296                   << "i=" << i_ << ' '
00297                   << "t=" << t_ << std::endl;
00298       }
00299 
00300       template <typename V>
00301       inline
00302       std::ostream& operator<<(std::ostream& ostr, const min_h<V>& m)
00303       {
00304         return ostr << m.to_result();
00305       }
00306 
00307 # endif // ! MLN_INCLUDE_ONLY
00308 
00309 
00310     } // end of namespace mln::accu::stat
00311 
00312   } // end of namespace mln::accu
00313 
00314 } // end of namespace mln
00315 
00316 #endif // ! MLN_ACCU_STAT_MIN_H_HH

Generated on Thu Sep 8 2011 18:32:07 for Milena (Olena) by  doxygen 1.7.1