polynoms.hxx

00001 // polynoms.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SERIES_POLYNOMS_HXX
00018 # define VCSN_ALGEBRA_IMPLEMENTATION_SERIES_POLYNOMS_HXX
00019 
00020 # include <sstream>
00021 
00022 # include <vaucanson/algebra/implementation/series/polynoms.hh>
00023 # include <vaucanson/algebra/concept/freemonoid_base.hh>
00024 
00025 # include <vaucanson/misc/contract.hh>
00026 # include <vaucanson/misc/escaper.hh>
00027 
00028 namespace vcsn {
00029 
00030   namespace algebra {
00031 
00032     /*----------------.
00033     | polynom<Tm, Tw> |
00034     `----------------*/
00035 
00036     template<typename Tm, typename Tw>
00037     template<typename M, typename W>
00038     polynom<Tm, Tw>::polynom(SELECTOR(M), SELECTOR(W))
00039     {
00040       map_.insert(std::make_pair(identity_value(SELECT(M), SELECT(Tm)),
00041                                  identity_value(SELECT(W), SELECT(Tw))));
00042     }
00043 
00044     template<typename Tm, typename Tw>
00045     polynom<Tm, Tw>::polynom(const polynom& other) : map_(other.map_)
00046     {}
00047 
00048     template<typename Tm, typename Tw>
00049     polynom<Tm, Tw>::polynom() : map_()
00050     {}
00051 
00052     template<typename Tm, typename Tw>
00053     size_t
00054     polynom<Tm, Tw>::size() const
00055     {
00056       return map_.size();
00057     }
00058 
00059     template<typename Tm, typename Tw>
00060     bool polynom<Tm, Tw>::empty() const
00061     {
00062       return map_.empty();
00063     }
00064 
00065     template<typename Tm, typename Tw>
00066     typename polynom<Tm, Tw>::iterator
00067     polynom<Tm, Tw>::begin()
00068     {
00069       return map_.begin();
00070     }
00071 
00072     template<typename Tm, typename Tw>
00073     typename polynom<Tm, Tw>::const_iterator
00074     polynom<Tm, Tw>::begin() const
00075     {
00076       return map_.begin();
00077     }
00078 
00079     template<typename Tm, typename Tw>
00080     typename polynom<Tm, Tw>::iterator
00081     polynom<Tm, Tw>::end()
00082     {
00083       return map_.end();
00084     }
00085 
00086     template<typename Tm, typename Tw>
00087     typename polynom<Tm, Tw>::const_iterator
00088     polynom<Tm, Tw>::end() const
00089     {
00090       return map_.end();
00091     }
00092 
00093     template<typename Tm, typename Tw>
00094     typename polynom<Tm, Tw>::iterator
00095     polynom<Tm, Tw>::find(const Tm& m)
00096     {
00097       return map_.find(m);
00098     }
00099 
00100     template<typename Tm, typename Tw>
00101     typename polynom<Tm, Tw>::const_iterator
00102     polynom<Tm, Tw>::find(const Tm& m) const
00103     {
00104       return map_.find(m);
00105     }
00106 
00107     template<typename Tm, typename Tw>
00108     template<typename W>
00109     Tw& polynom<Tm, Tw>::make_get(SELECTOR(W), const Tm& m)
00110     {
00111       std::pair<iterator, bool> i =
00112         map_.insert(std::make_pair(m, zero_value(SELECT(W), SELECT(Tw))));
00113       return i.first->second;
00114     }
00115 
00116     template<typename Tm, typename Tw>
00117     template<typename W>
00118     Tw polynom<Tm, Tw>::get(SELECTOR(W), const Tm& m) const
00119     {
00120       const_iterator i;
00121       if ((i = map_.find(m)) == map_.end())
00122         return zero_value(SELECT(W), SELECT(Tw));
00123       return i->second;
00124     }
00125 
00126     template<typename Tm, typename Tw>
00127     void polynom<Tm, Tw>::insert(const Tm& m, const Tw& w)
00128     {
00129       map_.insert(std::make_pair(m, w));
00130     }
00131 
00132     template<typename Tm, typename Tw>
00133     template<typename W>
00134     void polynom<Tm, Tw>::add(const W& semiring, const Tm& m, const Tw& w)
00135     {
00136       Tw& o = make_get(SELECT(W), m);
00137       op_in_add(semiring, o, w);
00138     }
00139 
00140     template<typename Tm, typename Tw>
00141     void polynom<Tm, Tw>::erase(iterator i)
00142     {
00143       map_.erase(i);
00144     }
00145 
00146     template<typename Tm, typename Tw>
00147     void polynom<Tm, Tw>::clear()
00148     {
00149       map_.clear();
00150     }
00151 
00152     template<typename Tm, typename Tw>
00153     void polynom<Tm, Tw>::swap(polynom<Tm, Tw>& other)
00154     {
00155       map_.swap(other.map_);
00156     }
00157 
00158     template<typename Tm, typename Tw>
00159     const std::map<Tm, Tw>&
00160     polynom<Tm, Tw>::as_map() const
00161     {
00162       return map_;
00163     }
00164 
00165     template<typename Tm, typename Tw>
00166     const Tw&
00167     polynom<Tm, Tw>::operator [] (const Tm& m) const
00168     {
00169       const_iterator i = map_.find(m);
00170 
00171       postcondition_ (i != map_.end(),
00172                       "Word is not in the support");
00173 
00174       return i->second;
00175     }
00176 
00177     template<typename Tm, typename Tw>
00178     Tw&
00179     polynom<Tm, Tw>::operator [] (const Tm& m)
00180     {
00181       return map_[m];
00182     }
00183 
00184     template <class Series, class Tm, class Tw>
00185     polynom<Tm,Tw>
00186     DefaultTransposeFun<Series, polynom<Tm,Tw> >::
00187     operator()(const Series& s,const polynom<Tm,Tw>& t) const
00188     {
00189       typedef typename polynom<Tm, Tw>::const_iterator  const_iterator;
00190       typedef typename Series::monoid_t                 monoid_t;
00191       typedef Element<monoid_t, Tm>                     monoid_elt_t;
00192 
00193       polynom<Tm, Tw> p;
00194 
00195       for (const_iterator i = t.begin(); i != t.end(); ++i)
00196         {
00197           monoid_elt_t m (s.monoid(), i->first);
00198           m.mirror();
00199           p[m.value()] = transpose(s.semiring(), i->second);
00200         }
00201       return p;
00202     }
00203 
00204     template <class Series, class Tm, class Tw>
00205     template <class S>
00206     Tw
00207     DefaultTransposeFun<Series, polynom<Tm,Tw> >::
00208     transpose(const SeriesBase<S>& s, const Tw& t)
00209     {
00210       Element<S, Tw> e (s.self(), t);
00211       e.transpose();
00212       return e.value();
00213     }
00214 
00215     template <class Series, class Tm, class Tw>
00216     template <class S>
00217     Tw
00218     DefaultTransposeFun<Series, polynom<Tm,Tw> >::
00219     transpose(const SemiringBase<S>&, const Tw& t)
00220     {
00221       return t;
00222     }
00223 
00224 
00225     template <class Tm, class Tw>
00226     bool operator==(const polynom<Tm, Tw>& lhs, const polynom<Tm, Tw>& rhs)
00227     {
00228       return lhs.as_map() == rhs.as_map();
00229     }
00230 
00231     template <class Tm, class Tw>
00232     bool operator!=(const polynom<Tm, Tw>& lhs, const polynom<Tm, Tw>& rhs)
00233     {
00234       return !(lhs == rhs);
00235     }
00236 
00237 
00238     template <class Tm, class Tw>
00239     bool operator<(const polynom<Tm, Tw>& lhs, const polynom<Tm, Tw>& rhs)
00240     {
00241       return lhs.as_map() < rhs.as_map();
00242     }
00243 
00244     template <class Tm, class Tw>
00245     bool operator>(const polynom<Tm, Tw>& lhs, const polynom<Tm, Tw>& rhs)
00246     {
00247       return lhs.as_map() > rhs.as_map();
00248     }
00249 
00250     template <class Tm, class Tw>
00251     bool operator<=(const polynom<Tm, Tw>& lhs, const polynom<Tm, Tw>& rhs)
00252     {
00253       return lhs.as_map() <= rhs.as_map();
00254     }
00255 
00256     template <class Tm, class Tw>
00257     bool operator>=(const polynom<Tm, Tw>& lhs, const polynom<Tm, Tw>& rhs)
00258     {
00259       return lhs.as_map() >= rhs.as_map();
00260     }
00261 
00262 
00263 
00264     /*-------------------.
00265     | External functions |
00266     `-------------------*/
00267 
00268     template<typename W, typename M, typename Tm, typename Tw>
00269     bool op_contains(const algebra::Series<W, M>& s,
00270                      const algebra::polynom<Tm, Tw>& m)
00271     {
00272       for (typename algebra::polynom<Tm, Tw>::const_iterator i = m.begin();
00273            i != m.end();
00274            ++i)
00275         if (!s.monoid().contains(i->first)
00276             || !s.semiring().contains(i->second))
00277           return false;
00278       return true;
00279     }
00280 
00281     template<typename Self, typename Tm, typename Tw>
00282     void op_in_star(const algebra::SeriesBase<Self>&,
00283                     algebra::polynom<Tm, Tw>& m)
00284     {
00285       if (m.size() == 0)
00286         {
00287           Tw val (zero_value(SELECT(typename Self::semiring_t), SELECT(Tw)));
00288           op_in_star(SELECT(typename Self::semiring_t), val);
00289           m.insert(identity_value(SELECT(typename Self::monoid_t), SELECT(Tm)),
00290                    val);
00291         }
00292       else
00293         {
00294           typename std::pair<Tm, Tw> elt = *m.as_map().begin();
00295           assertion_ (!(m.size() > 1 ||
00296                       elt.first != identity_value(SELECT(typename
00297                                                          Self::monoid_t),
00298                                                   SELECT(Tm))),
00299                       "Support is not empty, star cannot be computed.");
00300 
00301           op_in_star(SELECT(typename Self::semiring_t), elt.second);
00302           m.clear();
00303           m.insert(elt.first, elt.second);
00304         }
00305     }
00306 
00307     template<typename W, typename M, typename Tm, typename Tw>
00308     bool op_is_finite_app(const algebra::Series<W, M>&,
00309                           const algebra::polynom<Tm, Tw>&)
00310     {
00311       return true;
00312     }
00313 
00314     template<typename W, typename M, typename Tm, typename Tw>
00315     typename algebra::series_traits<algebra::polynom<Tm, Tw> >::support_t
00316     op_support(const algebra::Series<W, M>&, const algebra::polynom<Tm, Tw>& m)
00317     {
00318       return typename algebra::series_traits<algebra::polynom<Tm, Tw> >
00319         ::support_t(m.as_map());
00320     }
00321 
00322     template<typename W, typename M, typename Tm, typename Tw>
00323     const algebra::polynom<Tm, Tw>&
00324     identity_value(SELECTOR2(algebra::Series<W, M>),
00325                    SELECTOR2(algebra::polynom<Tm, Tw>))
00326     {
00327       static const algebra::polynom<Tm, Tw> instance =
00328         algebra::polynom<Tm, Tw>(SELECT(M), SELECT(W));
00329       return instance;
00330     }
00331 
00332     template<typename W, typename M, typename Tm, typename Tw>
00333     const algebra::polynom<Tm, Tw>&
00334     zero_value(SELECTOR2(algebra::Series<W, M>),
00335                SELECTOR2(algebra::polynom<Tm, Tw>))
00336     {
00337       static const algebra::polynom<Tm, Tw> instance;
00338       return instance;
00339     }
00340 
00341     template<typename W, typename M, typename Tm, typename Tw>
00342     void op_in_add(const algebra::Series<W, M>& s,
00343                    algebra::polynom<Tm, Tw>& dst,
00344                    const algebra::polynom<Tm, Tw>& arg)
00345     {
00346       typename algebra::polynom<Tm, Tw>::iterator p;
00347       Tw zero = zero_value(SELECT(W), SELECT(Tw));
00348       Tw w;
00349 
00350       for (typename algebra::polynom<Tm, Tw>::const_iterator i = arg.begin();
00351            i != arg.end();
00352            ++i)
00353         if (i->second != zero)
00354           {
00355             p = dst.find(i->first);
00356             if (p != dst.end())
00357               {
00358                 w = i->second;
00359                 op_in_add(s.semiring(), w, p->second);
00360                 if (w == zero_value(SELECT(W), SELECT(Tw)))
00361                   dst.erase(p);
00362                 else
00363                   p->second = w;
00364               }
00365             else
00366               dst.insert(i->first, i->second);
00367           }
00368     }
00369 
00370     template<typename W, typename M, typename Tm, typename Tw>
00371     algebra::polynom<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00372                                     const algebra::polynom<Tm, Tw>& a,
00373                                     const algebra::polynom<Tm, Tw>& b)
00374     {
00375       algebra::polynom<Tm, Tw> ret(a);
00376       op_in_add(s, ret, b);
00377       return ret;
00378     }
00379 
00380     /*-----------------.
00381     | cauchy's product |
00382     `-----------------*/
00383     template<typename W, typename M, typename Tm, typename Tw>
00384     algebra::polynom<Tm, Tw> op_mul(const algebra::Series<W, M>& s,
00385                                     const algebra::polynom<Tm, Tw>& a,
00386                                     const algebra::polynom<Tm, Tw>& b)
00387     {
00388       algebra::polynom<Tm, Tw> ret;
00389       for (typename algebra::polynom<Tm, Tw>::const_iterator i = a.begin();
00390            i != a.end();
00391            ++i)
00392         for (typename algebra::polynom<Tm, Tw>::const_iterator j = b.begin();
00393              j != b.end();
00394              ++j)
00395           {
00396             Tw w = op_mul(s.semiring(), i->second, j->second);
00397             if (w != zero_value(SELECT(W), SELECT(Tw)))
00398               ret.add(s.semiring(),
00399                       op_mul(s.monoid(), i->first, j->first),
00400                       w);
00401           }
00402       return ret;
00403     }
00404 
00405     template<typename W, typename M, typename Tm, typename Tw>
00406     void op_in_mul(const algebra::Series<W, M>& s,
00407                    algebra::polynom<Tm, Tw>& dst,
00408                    const algebra::polynom<Tm, Tw>& arg)
00409     {
00410       op_assign(s, dst, op_mul(s, dst, arg));
00411     }
00412 
00413     /*---------------------.
00414     | foreign constructors |
00415     `---------------------*/
00416 
00417     template <typename Tm, typename Tw, typename W, typename M>
00418     algebra::polynom<Tm, Tw> op_convert(SELECTOR2(algebra::Series<W, M>),
00419                                         SELECTOR2(algebra::polynom<Tm, Tw>),
00420                                         const Tm& m_value)
00421     {
00422       algebra::polynom<Tm, Tw> p(SELECT(M), SELECT(W));
00423       p.insert(m_value, identity_value(SELECT(W), SELECT(Tw)));
00424       return p;
00425     }
00426 
00427     template<typename Tm, typename Tw, typename W, typename M, typename oTm>
00428     algebra::polynom<Tm, Tw> op_convert(const algebra::Series<W, M>& s,
00429                                         SELECTOR2(algebra::polynom<Tm, Tw>),
00430                                         SELECTOR(algebra::MonoidBase<M>),
00431                                         const oTm& m_value)
00432     {
00433       const M&  monoid = s.monoid();
00434       const W&  semiring = s.semiring();
00435 
00436       algebra::polynom<Tm, Tw> ret;
00437       ret.insert(op_convert(monoid, SELECT(Tm), m_value),
00438                  identity_value(semiring, SELECT(Tw)));
00439       return ret;
00440     }
00441 
00442     template<typename Tm, typename Tw, typename W, typename M, typename oTw>
00443     algebra::polynom<Tm, Tw> op_convert(SELECTOR2(algebra::Series<W, M>),
00444                                         SELECTOR2(algebra::polynom<Tm, Tw>),
00445                                         SELECTOR(algebra::SemiringBase<W>),
00446                                         const oTw& w_value)
00447     {
00448       algebra::polynom<Tm, Tw> ret;
00449       if (w_value != zero_value(SELECT(W), SELECT(oTw)))
00450         ret.insert(identity_value(SELECT(M), SELECT(Tm)),
00451                    op_convert(SELECT(W), SELECT(Tw), w_value));
00452       return ret;
00453     }
00454 
00455     template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00456     void op_assign(const algebra::Series<W, M>&,
00457                    const algebra::MonoidBase<M>&,
00458                    algebra::polynom<Tm, Tw>& dst,
00459                    const oTm& src)
00460     {
00461       dst.clear();
00462       dst.insert(op_convert(SELECT(M), SELECT(Tm), src),
00463                  identity_value(SELECT(W), SELECT(Tw)));
00464     }
00465 
00466     template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00467     void op_assign(const algebra::Series<W, M>& s,
00468                    const algebra::SemiringBase<W>&,
00469                    algebra::polynom<Tm, Tw>& dst,
00470                    const oTw& src)
00471     {
00472       dst.clear();
00473       if (src != zero_value(SELECT(W), SELECT(oTw)))
00474         dst.insert(identity_value(SELECT(M), SELECT(Tm)),
00475                    op_convert(SELECT(W), SELECT(Tw), src));
00476     }
00477 
00478     /*--------------------------------------.
00479     | foreign addition with monoid elements |
00480     `--------------------------------------*/
00481 
00482     template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00483     void op_in_add(const algebra::Series<W, M>& s,
00484                    const algebra::MonoidBase<M>& monoid,
00485                    algebra::polynom<Tm, Tw>& dst,
00486                    const oTm& src)
00487     {
00488       precondition(& s.monoid() == & monoid);
00489       dst.add(s.semiring(),
00490               op_convert(SELECT(M), SELECT(Tm), src),
00491               identity_value(SELECT(W), SELECT(Tw)));
00492     }
00493 
00494     template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00495     algebra::polynom<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00496                                     const algebra::MonoidBase<M>& monoid,
00497                                     const algebra::polynom<Tm, Tw>& a,
00498                                     const oTm& b)
00499     {
00500       algebra::polynom<Tm, Tw> ret(a);
00501       op_in_add(s, monoid, ret, b);
00502       return ret;
00503     }
00504 
00505     template<typename M, typename W, typename oTm, typename Tm, typename Tw>
00506     algebra::polynom<Tm, Tw> op_add(const algebra::MonoidBase<M>& monoid,
00507                                     const algebra::Series<W, M>& s,
00508                                     const oTm& a,
00509                                     const algebra::polynom<Tm, Tw>& b)
00510     {
00511       algebra::polynom<Tm, Tw> ret(b);
00512       op_in_add(s, monoid, ret, a);
00513       return ret;
00514     }
00515 
00516     /*----------------------------------------.
00517     | foreign addition with semiring elements |
00518     `----------------------------------------*/
00519 
00520     template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00521     void op_in_add(const algebra::Series<W, M>& s,
00522                    const algebra::SemiringBase<W>& semiring,
00523                    algebra::polynom<Tm, Tw>& dst,
00524                    const oTw& src)
00525     {
00526       precondition(& s.semiring() == & semiring);
00527       if (src != zero_value(SELECT(W), SELECT(oTw)))
00528         dst.add(s.semiring(),
00529                 identity_value(SELECT(M), SELECT(Tm)),
00530                 op_convert(SELECT(W), SELECT(Tw), src));
00531     }
00532 
00533     template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00534     algebra::polynom<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00535                                     const algebra::SemiringBase<W>& semiring,
00536                                     const algebra::polynom<Tm, Tw>& a,
00537                                     const oTw& b)
00538     {
00539       algebra::polynom<Tm, Tw> ret(a);
00540       op_in_add(s, semiring, ret, b);
00541       return ret;
00542     }
00543 
00544     template<typename W, typename M, typename oTw, typename Tm, typename Tw>
00545     algebra::polynom<Tm, Tw> op_add(const algebra::SemiringBase<W>& semiring,
00546                                     const algebra::Series<W, M>& s,
00547                                     const oTw& a,
00548                                     const algebra::polynom<Tm, Tw>& b)
00549     {
00550       algebra::polynom<Tm, Tw> ret(b);
00551       op_in_add(s, semiring, ret, a);
00552       return ret;
00553     }
00554 
00555     /*--------------------------------------------.
00556     | foreign multiplication by semiring elements |
00557     `--------------------------------------------*/
00558 
00559     template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00560     void op_in_mul(const algebra::Series<W, M>& s,
00561                    const algebra::SemiringBase<W>& semiring,
00562                    algebra::polynom<Tm, Tw>& dst,
00563                    const oTw& src)
00564     {
00565       precondition(& s.semiring() == & semiring);
00566       (void) s; (void) semiring;
00567 
00568       typename algebra::polynom<Tm, Tw>::iterator p;
00569       for (typename algebra::polynom<Tm, Tw>::iterator i = dst.begin();
00570            i != dst.end();
00571            )
00572         {
00573           p = i++;
00574           op_in_mul(s.semiring(), p->second, src);
00575           if (p->second == zero_value(SELECT(W), SELECT(Tw)))
00576             dst.erase(p);
00577         }
00578     }
00579 
00580     template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00581     algebra::polynom<Tm, Tw> op_mul(const algebra::Series<W, M>& s,
00582                                     const algebra::SemiringBase<W>& semiring,
00583                                     const algebra::polynom<Tm, Tw>& a,
00584                                     const oTw& b)
00585     {
00586       algebra::polynom<Tm, Tw> ret(a);
00587       op_in_mul(s, semiring, ret, b);
00588       return ret;
00589     }
00590 
00591     template<typename W, typename M, typename oTw, typename Tm, typename Tw>
00592     algebra::polynom<Tm, Tw> op_mul(const algebra::SemiringBase<W>& semiring,
00593                                     const algebra::Series<W, M>& s,
00594                                     const oTw& a,
00595                                     const algebra::polynom<Tm, Tw>& b)
00596     {
00597       precondition(& s.semiring() == & semiring);
00598       (void) s; (void) semiring;
00599 
00600       algebra::polynom<Tm, Tw> ret(b);
00601 
00602       typename algebra::polynom<Tm, Tw>::iterator p;
00603       for (typename algebra::polynom<Tm, Tw>::iterator i = ret.begin();
00604            i != ret.end();)
00605         {
00606           p = i++;
00607           p->second = op_mul(s.semiring(), a, p->second);
00608           if (p->second == zero_value(SELECT(W), SELECT(Tw)))
00609             ret.erase(p);
00610         }
00611       return ret;
00612     }
00613 
00614       /*-------------.
00615       | input-output |
00616       `-------------*/
00617 
00618     template<typename W, typename M, typename St, typename Tm, typename Tw>
00619     St& op_rout(const algebra::Series<W, M>& s,
00620                 St& st,
00621                 const algebra::polynom<Tm, Tw>& p)
00622     {
00623       typename algebra::polynom<Tm, Tw>::const_iterator i = p.begin();
00624 
00625       while(i != p.end())
00626         {
00627           if (i != p.begin())
00628             st << "+";
00629 
00630           if (i->second != identity_value(SELECT(W), SELECT(Tw)))
00631           {
00632             st << "(";
00633             op_rout(s.semiring(), st, i->second);
00634             st << " ";
00635           }
00636 
00637           if (i->first != identity_value(SELECT(M), SELECT(Tm)))
00638             op_rout(s.monoid(), st, i->first);
00639           else
00640             st << "1";
00641 
00642           if (i->second != identity_value(SELECT(W), SELECT(Tw)))
00643             st << ")";
00644 
00645           ++i;
00646         }
00647       if (i == p.begin()) /* case zero */
00648         op_rout(s.semiring(), st, zero_value(SELECT(W), SELECT(Tw)));
00649       return st;
00650     }
00651 
00652     /*---------------.
00653     | specialization |
00654     `---------------*/
00655 
00656     /*---------------------------------.
00657     | design_pattern series operations |
00658     `---------------------------------*/
00659 
00660 
00661     template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00662     Tw op_series_get(const algebra::Series<W, M>& s,
00663                      const algebra::polynom<Tm, Tw>& p,
00664                      const oTm& m)
00665     {
00666       return p.get(s.semiring(), op_convert(s.semiring(), SELECT(Tm), m));
00667     }
00668 
00669     template <typename W, typename M,
00670               typename Tm, typename Tw,
00671               typename oTm, typename oTw>
00672     void op_series_set(const algebra::Series<W, M>& s,
00673                        algebra::polynom<Tm, Tw>& p,
00674                        const oTm& m,
00675                        const oTw& w)
00676     {
00677       const M&  monoid = s.monoid();
00678       const W&  semiring = s.semiring();
00679 
00680       typename misc::static_if
00681         <misc::static_eq<Tm, oTm>::value, const Tm&, Tm>::t
00682         new_m = op_convert(monoid, SELECT(Tm), m);
00683       typename misc::static_if
00684         <misc::static_eq<Tw, oTw>::value, const Tw&, Tw>::t
00685         new_w = op_convert(semiring, SELECT(Tw), w);
00686 
00687       typename algebra::polynom<Tm, Tw>::iterator i = p.find(new_m);
00688       if (new_w == zero_value(semiring, new_w))
00689         {
00690           if (i != p.end())
00691             p.erase(i);
00692         }
00693       else if (i == p.end())
00694         p.insert(new_m, new_w);
00695       else
00696         i->second = new_w;
00697     }
00698 
00699 
00700     template <class W, class M, class Tm, class Tw>
00701     Tm op_choose_from_supp(const algebra::Series<W, M>&,
00702                            const algebra::polynom<Tm, Tw>& p)
00703     {
00704       typedef typename algebra::polynom<Tm, Tw>::const_iterator const_iterator;
00705 
00706       const unsigned size = p.size();
00707 
00708       if (size == 0)
00709         return Tm();
00710 
00711       const_iterator i = p.begin();
00712 
00713       // No need to call rand in this case
00714       if (size == 1)
00715         return i->first;
00716 
00717       unsigned index = rand() % size;
00718       while (index > 0)
00719       {
00720         --index;
00721         ++i;
00722       }
00723       return i->first;
00724     }
00725 
00726 
00727     template <class W, class M, class Tm, class Tw>
00728     Element<algebra::Series<W,M>, algebra::polynom<Tm,Tw> >
00729     op_choose(const algebra::Series<W,M>& s,
00730               SELECTOR2(algebra::polynom<Tm,Tw>))
00731     {
00732       algebra::polynom<Tm, Tw> p;
00733       // FIXME: add global constants to define this !
00734       unsigned nb_monome = rand() * 10 / RAND_MAX;
00735       for (unsigned i = 0; i < nb_monome; ++i)
00736         p[s.monoid().choose()] = s.semiring().choose();
00737       return Element<algebra::Series<W,M>, algebra::polynom<Tm,Tw> >(s, p);
00738     }
00739 
00740     /*----------.
00741     | transpose |
00742     `----------*/
00743     template <typename W, typename M, typename Tm, typename Tw>
00744     void  op_in_transpose(const algebra::Series<W, M>& s,
00745                           algebra::polynom<Tm, Tw>& t)
00746     {
00747       algebra::DefaultTransposeFun<algebra::Series<W, M>,
00748                                    algebra::polynom<Tm, Tw> > f;
00749       t = f(s, t);
00750     }
00751 
00752   } // algebra
00753 
00754 } // vcsn
00755 
00756 namespace std {
00757 
00758   // FIXME: Must this operator exist ?
00759   template <class Tm, class Tw>
00760   std::ostream& operator<<(std::ostream& out,
00761                            const vcsn::algebra::polynom<Tm, Tw>& p)
00762   {
00763     typename vcsn::algebra::polynom<Tm, Tw>::const_iterator i = p.begin();
00764 
00765     while (i != p.end())
00766       {
00767         if (i != p.begin())
00768           out << "+";
00769         out << "(" << i->second << " "
00770             << vcsn::misc::make_escaper(i->first) << ")";
00771         ++i;
00772       }
00773 
00774     if (i == p.begin()) /* case zero */
00775       out << "0";
00776 
00777     return out;
00778   }
00779 
00780 } // std
00781 
00782 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_POLYNOMS_HXX

Generated on Thu Dec 13 16:03:01 2007 for Vaucanson by  doxygen 1.5.4