00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
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> 
00046 # include <mln/literal/zero.hh>
00047 # include <mln/convert/to.hh>
00048 
00049 
00050 namespace mln
00051 {
00052 
00053   
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     } 
00077 
00078   } 
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       
00088     };
00089 
00090   } 
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   
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   
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)) 
00260       
00261       return *this;
00262 
00263     
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     
00269     win_.insert(d);
00270     memo_wei_[d] = w;
00271 
00272     
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   
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           
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     
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
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     } 
00412 
00413   } 
00414 
00415 
00416   
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 } 
00448 
00449 
00450 # include <mln/make/w_window.hh>
00451 
00452 
00453 #endif // ! MLN_CORE_W_WINDOW_HH