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

max_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_MAX_H_HH
00027 # define MLN_ACCU_STAT_MAX_H_HH
00028 
00032 
00033 # include <mln/accu/internal/base.hh>
00034 # include <mln/core/concept/meta_accumulator.hh>
00035 # include <mln/accu/histo.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 max_h;
00051 
00052     } // end of namespace mln::accu::stat
00053 
00054     namespace meta
00055     {
00056 
00057       namespace stat
00058       {
00059 
00061         struct max_h : public Meta_Accumulator< max_h >
00062         {
00063           template <typename T>
00064           struct with
00065           {
00066             typedef accu::stat::max_h<T> ret;
00067           };
00068         };
00069 
00070       } // end of namespace mln::accu::meta::stat
00071 
00072     } // end of namespace mln::accu::meta
00073 
00074 
00075     namespace stat
00076     {
00077 
00082       //
00083       template <typename V>
00084       struct max_h : public mln::accu::internal::base< const V&, max_h<V> >
00085       {
00086         typedef V argument;
00087 
00088         max_h();
00089 
00092         void init();
00093         void   take(const argument& t);
00094         void   take_as_init_(const argument& t);
00095         void   take(const max_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 max index
00120         mutable argument t_;       // the max argument
00121 
00122         // Auxiliary methods
00123         void update_() const;
00124         void go_minus_() const;
00125         void go_plus_() const;
00126       };
00127 
00128 
00129       template <typename I> struct max_h< util::pix<I> >;
00130 
00131 # ifndef MLN_INCLUDE_ONLY
00132 
00133       template <typename V>
00134       inline
00135       max_h<V>::max_h()
00136         : h_(),
00137           s_(h_.vset())
00138       {
00139         init();
00140       }
00141 
00142       template <typename V>
00143       inline
00144       void
00145       max_h<V>::take(const argument& t)
00146       {
00147         if (h_.sum() == 0)
00148           {
00149             this->take_as_init_(t);
00150             return;
00151           }
00152         h_.take(t);
00153         if (t > t_)
00154           {
00155             ++sum_;
00156             valid_ = false;
00157           }
00158       }
00159 
00160       template <typename V>
00161       inline
00162       void
00163       max_h<V>::take(const max_h<V>& other)
00164       {
00165         // h_
00166         h_.take(other.h_);
00167         for (unsigned i = this->card() - 1; i > i_; --i)
00168           sum_ += other.h_[i];
00169         valid_ = false;
00170         // FIXME: Optimize.
00171       }
00172 
00173       template <typename V>
00174       inline
00175       void
00176       max_h<V>::untake(const argument& t)
00177       {
00178         mln_precondition(h_(t) != 0);
00179         h_.untake(t);
00180         if (h_.sum() == 0)
00181           {
00182             init();
00183             return;
00184           }
00185         if (t > t_)
00186           {
00187             mln_invariant(sum_ >= 1);
00188             --sum_;
00189             valid_ = false;
00190           }
00191         else
00192           if (t == t_ && h_[i_] == 0)
00193             valid_ = false;
00194       }
00195 
00196       template <typename V>
00197       inline
00198       void
00199       max_h<V>::update_() const
00200       {
00201         if (sum_ != 0)
00202           go_plus_();
00203         else
00204           if (h_[i_] == 0)
00205             go_minus_();
00206         valid_ = true;
00207       }
00208 
00209       template <typename V>
00210       inline
00211       void
00212       max_h<V>::go_plus_() const
00213       {
00214         do
00215           {
00216             ++i_;
00217             if (h_[i_] != 0)
00218               sum_ -= h_[i_];
00219           }
00220         while (sum_ != 0);
00221         t_ = s_[i_];
00222       }
00223 
00224       template <typename V>
00225       inline
00226       void
00227       max_h<V>::go_minus_() const
00228       {
00229         do
00230           --i_;
00231         while (h_[i_] == 0);
00232         t_ = s_[i_];
00233       }
00234 
00235       template <typename V>
00236       inline
00237       void
00238       max_h<V>::init()
00239       {
00240         h_.init();
00241         sum_ = 0;
00242         i_ = mln_min(argument);
00243         t_ = s_[i_];
00244         valid_ = true;
00245       }
00246 
00247       template <typename V>
00248       inline
00249       void
00250       max_h<V>::take_as_init_(const argument& t)
00251       {
00252         h_.take(t);
00253         sum_ = 0;
00254         i_ = s_.index_of(t);
00255         t_ = t;
00256         valid_ = true;
00257       }
00258 
00259       template <typename V>
00260       inline
00261       const typename max_h<V>::argument&
00262       max_h<V>::to_result() const
00263       {
00264         if (! valid_)
00265           update_();
00266         return t_;
00267       }
00268 
00269       template <typename V>
00270       inline
00271       const accu::histo<V>&
00272       max_h<V>::histo() const
00273       {
00274         return h_;
00275       }
00276 
00277       template <typename V>
00278       inline
00279       bool
00280       max_h<V>::is_valid() const
00281       {
00282         return true;
00283       }
00284 
00285       template <typename V>
00286       inline
00287       void
00288       max_h<V>::debug_print_() const
00289       {
00290         std::cout << "h={" << h_ << "} ";
00291         std::cout << "sum=" << sum_ << ' '
00292                   << "valid=" << valid_ << ' '
00293                   << "i=" << i_ << ' '
00294                   << "t=" << t_ << std::endl;
00295       }
00296 
00297       template <typename V>
00298       inline
00299       std::ostream& operator<<(std::ostream& ostr, const max_h<V>& m)
00300       {
00301         return ostr << m.to_result();
00302       }
00303 
00304 # endif // ! MLN_INCLUDE_ONLY
00305 
00306     } // end of namespace mln::accu::stat
00307 
00308   } // end of namespace mln::accu
00309 
00310 } // end of namespace mln
00311 
00312 
00313 #endif // ! MLN_ACCU_STAT_MAX_H_HH

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