- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# cyclic_semiring.hxx

    00001 // tropical_semiring.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, 2011 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_SEMIRING_CYCLIC_SEMIRING_HXX
    00018 # define VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_CYCLIC_SEMIRING_HXX
    00019 # include <vaucanson/config/system.hh>
    00020 # include <vaucanson/algebra/implementation/semiring/cyclic_semiring.hh>
    00021 # include <vaucanson/misc/random.hh>
    00022 # include <vaucanson/misc/limits.hh>
    00023 # include <boost/swap.hpp>
    00024 # include <boost/tuple/tuple.hpp>
    00025
    00026 namespace vcsn {
    00027
    00028   namespace algebra {
    00029
    00039     inline
    00040     boost::tuple<unsigned int, int, int>
    00041     ext_gcd (unsigned int a, unsigned int b)
    00042     {
    00043       unsigned int q, r;
    00044       int x1 = 0;
    00045       int x2 = 1;
    00046       int y1 = 1;
    00047       int y2 = 0;
    00048       int x, y;
    00049
    00050       if (a < b)
    00051         {
    00052           boost::swap (a, b);
    00053           boost::swap (x1, x2);
    00054           boost::swap (y1, y2);
    00055         }
    00056
    00057       if (b == 0)
    00058         return boost::tuple<unsigned int, int, int> (a, 1, 0);
    00059
    00060       while (b > 0)
    00061         {
    00062           q = a / b;
    00063           r = a - q * b;
    00064           x = x2 - q * x1;
    00065           y = y2 - q * y1;
    00066           a = b;
    00067           b = r;
    00068           x2 = x1;
    00069           x1 = x;
    00070           y2 = y1;
    00071           y1 = y;
    00072         }
    00073
    00074       return boost::tuple<unsigned int, int, int> (a, x2, y2);
    00075     }
    00076
    00077     /*---------------.
    00078     | Identity value |
    00079     `---------------*/
    00080
    00081     template<unsigned int n, typename T>
    00082     T identity_value(SELECTOR(algebra::CyclicSemiring<n>), SELECTOR(T))
    00083     {
    00084       return T(1);
    00085     }
    00086
    00087     template<unsigned int n, typename T>
    00088     bool show_identity_value(SELECTOR(algebra::CyclicSemiring<n>),
    00089                              SELECTOR(T))
    00090     {
    00091       return false;
    00092     }
    00093
    00094     template<unsigned int n, typename T>
    00095     bool
    00096     is_positive_semiring(SELECTOR(algebra::CyclicSemiring<n>), SELECTOR(T))
    00097     {
    00098       return false;
    00099     }
    00100
    00101     template<unsigned int n, typename T>
    00102     T zero_value(SELECTOR(algebra::CyclicSemiring<n>), SELECTOR(T))
    00103     {
    00104       return T(0);
    00105     }
    00106
    00107     /*------------.
    00108     | op_contains |
    00109     `------------*/
    00110     template<unsigned int n, typename T>
    00111     bool op_contains(const algebra::CyclicSemiring<n>&, T c)
    00112     {
    00113       return true;
    00114     }
    00115
    00116     /*---------------.
    00117     | Multiplication |
    00118     `---------------*/
    00119     template<unsigned int n, typename T, typename U>
    00120     void op_in_mul(const algebra::CyclicSemiring<n>&,
    00121                    T& dst, U arg)
    00122     {
    00123       dst = (dst * arg) % n;
    00124       dst = (dst < 0) ? dst + n : dst;
    00125     }
    00126
    00127     template<unsigned int n, typename T, typename U>
    00128     T op_mul(const algebra::CyclicSemiring<n>&, T a, U b)
    00129     {
    00130       T res = (a * b) % n;
    00131       return ((res < 0) ? res + n : res);
    00132     }
    00133
    00134     /*-----------------------.
    00135     | Mutiplication for Z/2Z |
    00136     `-----------------------*/
    00137
    00138     inline
    00139     void op_in_mul(const algebra::CyclicSemiring<2>&,
    00140                                   bool& dst, bool arg)
    00141     {
    00142       dst = dst && arg;
    00143     }
    00144
    00145     inline
    00146     bool op_mul(const algebra::CyclicSemiring<2>&, bool a, bool b)
    00147     {
    00148       return (a && b);
    00149     }
    00150
    00151     /*---------.
    00152     | Addition |
    00153     `---------*/
    00154     template<unsigned int n, typename T, typename U>
    00155     void op_in_add(const algebra::CyclicSemiring<n>&,
    00156                    T& dst, U arg)
    00157     {
    00158       dst = ((dst + arg) + (2 * n)) % n;
    00159     }
    00160
    00161     template<unsigned int n, typename T, typename U>
    00162     T op_add(const algebra::CyclicSemiring<n>&, T a, U b)
    00163     {
    00164       return ((a + b) + (2 * n)) % n;
    00165     }
    00166
    00167     /*------------------.
    00168     | Addition for Z/2Z |
    00169     `------------------*/
    00170
    00171     inline
    00172     void op_in_add(const algebra::CyclicSemiring<2>&,
    00173                                   bool& dst, bool arg)
    00174     {
    00175       dst = dst ^ arg;
    00176     }
    00177
    00178     inline
    00179     bool op_add(const algebra::CyclicSemiring<2>&, bool a, bool b)
    00180     {
    00181       return a ^ b;
    00182     }
    00183
    00184     /*---------.
    00185     | Division |
    00186     `---------*/
    00187
    00188     template<unsigned int n, typename T, typename U>
    00189     void op_in_div (const algebra::CyclicSemiring<n>& s1,
    00190                     T& dst, U arg)
    00191     {
    00192       boost::tuple<unsigned int , int, int> res = ext_gcd (dst, arg);
    00193       if (res.get<0> () == 1)
    00194         {
    00195           op_in_mul (s1, dst, res.get<2> ());
    00196           return;
    00197         }
    00198
    00199       assertion(! "tried to divide by a number"
    00200                 " without multiplicative inverse.");
    00201     }
    00202
    00203     template<unsigned int n, typename T, typename U>
    00204     T op_div (const algebra::CyclicSemiring<n>& s, T a, U b)
    00205     {
    00206       boost::tuple<unsigned int , int, int> res = ext_gcd (a, b);
    00207       if (res.get<0> () == 1)
    00208         return (op_mul (s, a, res.get<2> ()));
    00209
    00210       assertion(! "tried to divide by a number"
    00211                 " without multiplicative inverse.");
    00212     }
    00213
    00214     /*------------------.
    00215     | Division for Z/2Z |
    00216     `------------------*/
    00217
    00218     inline
    00219     void op_in_div (const algebra::CyclicSemiring<2>& s1,
    00220                                    bool& dst, bool arg)
    00221     {
    00222       if (arg == 1)
    00223         return;
    00224       assertion (! "Division by zero.");
    00225     }
    00226
    00227     inline
    00228     bool op_div (const algebra::CyclicSemiring<2>& s, bool a, bool b)
    00229     {
    00230       if (b == 1)
    00231         return (a);
    00232       assertion(! "Division by zero.");
    00233     }
    00234
    00235     /*-------------.
    00236     | Substraction |
    00237     `-------------*/
    00238
    00239     template<unsigned int n, typename T, typename U>
    00240     void op_in_sub(const algebra::CyclicSemiring<n>& s1,
    00241                    T& dst, U arg)
    00242     {
    00243       dst = (dst - arg) % n;
    00244       dst = (dst < 0) ? dst + n : dst;
    00245     }
    00246
    00247     template<unsigned int n, typename T, typename U>
    00248     T op_sub(const algebra::CyclicSemiring<n>& s,
    00249              T a, U b)
    00250     {
    00251       T res = (a - b) % n;
    00252       return ((res < 0) ? res + n : res);
    00253     }
    00254
    00255     /*----------------------.
    00256     | Substraction for Z/2Z |
    00257     `----------------------*/
    00258
    00259     inline
    00260     void op_in_sub(const algebra::CyclicSemiring<2>& s1,
    00261                                    bool& dst, bool arg)
    00262     {
    00263       dst = dst ^ arg;
    00264     }
    00265
    00266     inline
    00267     bool op_sub(const algebra::CyclicSemiring<2>& s,
    00268                 bool a, bool b)
    00269     {
    00270       return (a ^ b);
    00271     }
    00272
    00273     /*-----.
    00274     | Star |
    00275     `-----*/
    00276
    00277     template <unsigned int n, typename T>
    00278     bool
    00279     op_starable(const algebra::CyclicSemiring<n>&, T b)
    00280     {
    00281       if (b == T(0))
    00282         return true;
    00283       return false;
    00284     }
    00285
    00286     template <unsigned int n, class T>
    00287     void
    00288     op_in_star(const algebra::CyclicSemiring<n>&, T& b)
    00289     {
    00290       if (b == T(0))
    00291         {
    00292           b = T(1);
    00293           return;
    00294         }
    00295       assertion(! "star not defined.");
    00296     }
    00297
    00298     template <unsigned int n, class T>
    00299     Element<algebra::CyclicSemiring<n>, T>
    00300     op_choose(const algebra::CyclicSemiring<n>& set, SELECTOR(T))
    00301     {
    00302       return Element<algebra::CyclicSemiring<n>, T>
    00303         (set, misc::random::generate<T>());
    00304     }
    00305
    00306     template <unsigned int n, typename T>
    00307     bool
    00308     op_can_choose_non_starable(const algebra::CyclicSemiring<n>&,
    00309                                SELECTOR(T))
    00310     {
    00311       return true;
    00312     }
    00313
    00314     template <unsigned int n, class T>
    00315     Element<algebra::CyclicSemiring<n>, T>
    00316     op_choose_starable(const algebra::CyclicSemiring<n>& set,
    00317                        SELECTOR(T))
    00318     {
    00319       T r;
    00320       do
    00321         r = op_choose(set, SELECT(T));
    00322       while (!op_starable(set, r));
    00323       return r;
    00324     }
    00325
    00326     template <unsigned int n, class T>
    00327     Element<algebra::CyclicSemiring<n>, T>
    00328     op_choose_non_starable(const algebra::CyclicSemiring<n>& set,
    00329                            SELECTOR(T))
    00330     {
    00331       T r;
    00332       do
    00333         r = op_choose(set, SELECT(T));
    00334       while (op_starable(set, r));
    00335       return r;
    00336     }
    00337
    00338     /*---------------.
    00339     | Pretty printer |
    00340     `---------------*/
    00341     template<unsigned int n, typename St, typename T>
    00342     St& op_rout(const algebra::CyclicSemiring<n>&, St& st, const T& v)
    00343     {
    00344       st << v;
    00345       return st;
    00346     }
    00347
    00348   } // algebra
    00349
    00350 } // vcsn
    00351
    00352 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_CYCLIC_SEMIRING_HXX