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

w_window.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_CORE_W_WINDOW_HH
00027 # define MLN_CORE_W_WINDOW_HH
00028 
00034 
00035 # include <map>
00036 
00037 # include <mln/core/internal/weighted_window_base.hh>
00038 # include <mln/core/concept/image.hh>
00039 # include <mln/core/site_set/box.hh>
00040 # include <mln/core/window.hh>
00041 # include <mln/core/dpsites_piter.hh>
00042 
00043 # include <mln/value/ops.hh>
00044 # include <mln/util/ord.hh>
00045 # include <mln/geom/bbox.hh> // FIXME: We may have some dep trouble with this include.
00046 # include <mln/literal/zero.hh>
00047 # include <mln/convert/to.hh>
00048 
00049 
00050 namespace mln
00051 {
00052 
00053   // Forward declarations.
00054   template <typename D,  typename W> struct w_window;
00055   template <typename It, typename W> struct with_w_;
00056 
00057 
00058   namespace convert
00059   {
00060 
00061     namespace over_load
00062     {
00063 
00064       template <typename I, typename D, typename W>
00065       void
00066       from_to_(const Image<I>& from, w_window<D,W>& to);
00067 
00068       template <typename D, typename W, typename I>
00069       void
00070       from_to_(const w_window<D,W>& from, Image<I>& to);
00071 
00072       template <typename V, unsigned S, typename D, typename W>
00073       void
00074       from_to_(const V (&weight)[S], w_window<D,W>& to);
00075 
00076     } // end of namespace mln::convert::over_load
00077 
00078   } // end of namespace mln::convert
00079 
00080 
00081   namespace trait
00082   {
00083 
00084     template <typename D, typename W>
00085     struct window_< mln::w_window<D,W> > : window_< mln::window<D> >
00086     {
00087       // Same traits as its corresponding window.
00088     };
00089 
00090   } // end of namespace mln::trait
00091 
00092 
00099   template <typename D, typename W>
00100   struct w_window : public internal::weighted_window_base< mln::window<D>,
00101                                                            w_window<D,W> >
00102   {
00104     typedef D dpsite;
00105 
00107     typedef W weight;
00108 
00109 
00111     typedef with_w_< dpsites_fwd_piter< w_window<D, W> >, W > fwd_qiter;
00112 
00114     typedef with_w_< dpsites_bkd_piter< w_window<D, W> >, W > bkd_qiter;
00115 
00116 
00118     w_window();
00119 
00120 
00122     w_window<D,W>& insert(const W& w, const D& d);
00123 
00124 
00126     W w(unsigned i) const;
00127 
00129     const std::vector<W>& weights() const;
00130 
00131 
00133     const std::vector<D>& std_vector() const;
00134 
00136     const mln::window<D>& win() const;
00137 
00138 
00140     bool is_symmetric() const;
00141 
00143     void sym();
00144 
00146     void clear();
00147 
00148   protected:
00149 
00150     mln::window<D> win_;
00151     std::vector<W> wei_;
00152   };
00153 
00154 
00157   template <typename D, typename W>
00158   std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win);
00159 
00160 
00163   template <typename D, typename Wl, typename Wr>
00164   bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs);
00165 
00166 
00167 
00169   template <typename It, typename W>
00170   struct with_w_ : public It
00171   {
00172 
00173     template <typename Ds, typename P>
00174     with_w_(const Ds& ds, const P& p);
00175 
00176     W w() const;
00177 
00178   protected:
00179     const std::vector<W> wei_;
00180   };
00181 
00182 
00183 
00184 # ifndef MLN_INCLUDE_ONLY
00185 
00186 
00187   // with_w_<It,W>
00188 
00189   template <typename It, typename W>
00190   template <typename Ds, typename P>
00191   inline
00192   with_w_<It,W>::with_w_(const Ds& ds,
00193                          const P&  p)
00194     : It(ds, p),
00195       wei_(ds.weights())
00196   {
00197   }
00198   
00199   template <typename It, typename W>
00200   inline
00201   W
00202   with_w_<It,W>::w() const
00203   {
00204     mln_precondition(this->i_ < wei_.size());
00205     return wei_[this->i_];
00206   }
00207 
00208 
00209   // w_window<D,W>
00210 
00211   template <typename D, typename W>
00212   inline
00213   w_window<D,W>::w_window()
00214   {
00215   }
00216 
00217   template <typename D, typename W>
00218   inline
00219   const mln::window<D>&
00220   w_window<D,W>::win() const
00221   {
00222     return win_;
00223   }
00224 
00225   template <typename D, typename W>
00226   inline
00227   const std::vector<D>&
00228   w_window<D,W>::std_vector() const
00229   {
00230     return win_.std_vector();
00231   }
00232 
00233   template <typename D, typename W>
00234   inline
00235   const std::vector<W>&
00236   w_window<D,W>::weights() const
00237   {
00238     return wei_;
00239   }
00240 
00241   template <typename D, typename W>
00242   inline
00243   W
00244   w_window<D,W>::w(unsigned i) const
00245   {
00246     mln_precondition(i < wei_.size());
00247     mln_invariant(wei_.size() == win_.size());
00248     return wei_[i];
00249   }
00250 
00251   template <typename D, typename W>
00252   inline
00253   w_window<D,W>&
00254   w_window<D,W>::insert(const W& w, const D& d)
00255   {
00256     mln_invariant(wei_.size() == win_.size());
00257     mln_precondition(! win_.has(d));
00258 
00259     if (w == W(0)) // FIXME: Implicit restriction "W scalar"...
00260       // no-op
00261       return *this;
00262 
00263     // memorization: d_i -> w_i
00264     std::map<D, W, util::ord<D> > memo_wei_;
00265     for (unsigned i = 0; i < win_.size(); ++i)
00266       memo_wei_[win_.dp(i)] = wei_[i];
00267 
00268     // insertion of d and w:
00269     win_.insert(d);
00270     memo_wei_[d] = w;
00271 
00272     // re-mapping: w_i <- d_i
00273     wei_.resize(win_.size());
00274     for (unsigned i = 0; i < win_.size(); ++i)
00275       wei_[i] = memo_wei_[win_.dp(i)];
00276 
00277     mln_invariant(wei_.size() == win_.size());
00278     return *this;
00279   }
00280 
00281   template <typename D, typename W>
00282   inline
00283   bool
00284   w_window<D,W>::is_symmetric() const
00285   {
00286     if (! win_.is_symmetric())
00287       return false;
00288     w_window<D,W> tmp;
00289     tmp.sym();
00290     return *this == tmp;
00291   }
00292 
00293   template <typename D, typename W>
00294   inline
00295   void
00296   w_window<D,W>::sym()
00297   {
00298     w_window<D,W> tmp;
00299     unsigned n = this->size();
00300     for (unsigned i = 0; i < n; ++i)
00301       tmp.insert(this->w(i), - this->dp(i));
00302     *this = tmp;
00303   }
00304 
00305   template <typename D, typename W>
00306   inline
00307   void
00308   w_window<D,W>::clear()
00309   {
00310     win_.clear();
00311     wei_.clear();
00312   }
00313 
00314 
00315   // convert::from_to_
00316 
00317   namespace convert
00318   {
00319 
00320     namespace over_load
00321     {
00322 
00323       template <typename I, typename D, typename W>
00324       void
00325       from_to_(const Image<I>& from_, w_window<D,W>& to)
00326       {
00327         mlc_converts_to(mln_deduce(I, psite, delta), D)::check();
00328         mlc_converts_to(mln_value(I), W)::check();
00329         const I& ima = exact(from_);
00330         to.clear();
00331         mln_value(I) zero = literal::zero;
00332         mln_piter(I) p(ima.domain());
00333         for_all(p)
00334           if (ima(p) != zero)
00335             to.insert(ima(p), convert::to<D>(p));
00336       }
00337 
00338       template <typename D, typename W, typename I>
00339       void
00340       from_to_(const w_window<D,W>& w_win, Image<I>& ima_)
00341       {
00342         typedef mln_site(I) P;
00343         mlc_converts_to(D, mln_delta(P))::check();
00344         mlc_converts_to(W, mln_value(I))::check();
00345 
00346         I& ima = exact(ima_);
00347         mln_precondition(! ima.is_valid());
00348         mln_precondition(w_win.is_valid());
00349 
00350         ima.init_(geom::bbox(w_win));
00351         {
00352           // data::fill(ima, literal::zero) is:
00353           mln_value(I) zero = literal::zero;
00354           mln_piter(I) p(ima.domain());
00355           for_all(p)
00356             ima(p) = zero;
00357         }
00358 
00359         unsigned n = w_win.size();
00360         for (unsigned i = 0; i < n; ++i)
00361           ima(convert::to<P>(w_win.dp(i))) = w_win.w(i);
00362       }
00363 
00364     // FIXME: Sample code (below) to generalize the code above:
00365 
00366 //     template <typename W>
00367 //     inline
00368 //     mln_image_from(W, mln_weight(W)) to_image(const Weighted_Window<W>& w_win_)
00369 //     {
00370 //       const W& w_win = exact(w_win_);
00371 //       mln_precondition(! w_win.is_empty());
00372 
00373 //       typedef mln_psite(W) P;
00374 //       box<P> b = geom::bbox(w_win);
00375 //       mln_image_from(W, mln_weight(W)) ima(b);
00376 //       // Fill the image with zeros, as (weighted) windows are not
00377 //       // necessarily box-shaped (there might be holes corresponding to
00378 //       // null weights).
00379 //       data::fill(ima, literal::zero);
00380 //       P O = P::origin;
00381 //       mln_qiter(W) q(w_win, O);
00382 //       for_all(q)
00383 //      ima(q) = q.w();
00384 //       return ima;
00385 //     }
00386 
00387       template <typename V, unsigned S, typename D, typename W>
00388       void
00389       from_to_(const V (&weight)[S], w_window<D,W>& to)
00390       {
00391         mlc_bool(S != 0)::check();
00392         mlc_converts_to(V, W)::check();
00393         enum { d = D::dim,
00394           s = mlc_root(d,S)::value / 2 };
00395         metal::bool_<(mlc_pow_int(2 * s + 1, d) == S)>::check();
00396         to.clear();
00397         typedef mln_site(D) P;
00398         box<P> b(all_to(-s), all_to(+s));
00399         mln_fwd_piter(box<P>) p(b);
00400         unsigned i = 0;
00401         V zero = literal::zero;
00402         for_all(p)
00403         {
00404           if (weight[i] != zero)
00405             to.insert(weight[i], convert::to<D>(p));
00406           ++i;
00407         }
00408 
00409       }
00410 
00411     } // end of namespace mln::convert::over_load
00412 
00413   } // end of namespace mln::convert
00414 
00415 
00416   // operators
00417 
00418   template <typename D, typename W>
00419   inline
00420   std::ostream& operator<<(std::ostream& ostr, const w_window<D,W>& w_win)
00421   {
00422     ostr << '[';
00423     for (unsigned i = 0; i < w_win.win().size(); ++i)
00424       ostr << w_win.dp(i) << ':' << w_win.w(i) << ' ';
00425     return ostr << ']';
00426   }
00427 
00428   template <typename D, typename Wl, typename Wr>
00429   inline
00430   bool operator==(const w_window<D,Wl>& lhs, const w_window<D,Wr>& rhs)
00431   {
00432     if (lhs.size() != rhs.size())
00433       return false;
00434     if (lhs.win() != rhs.win())
00435       return false;
00436     const std::vector<Wl>& wl = lhs.weights();
00437     const std::vector<Wr>& wr = rhs.weights();
00438     mln_assertion(wl.size() == wr.size());
00439     for (unsigned i = 0; i < wl.size(); ++i)
00440       if (wr[i] != wl[i])
00441         return false;
00442     return true;
00443   }
00444 
00445 # endif // ! MLN_INCLUDE_ONLY
00446 
00447 } // end of namespace mln
00448 
00449 
00450 # include <mln/make/w_window.hh>
00451 
00452 
00453 #endif // ! MLN_CORE_W_WINDOW_HH

Generated on Tue Oct 4 2011 15:25:09 for Milena (Olena) by  doxygen 1.7.1