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

- File List
- File Members

# numerical_semiring.hxx

    00001 // numerical_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, 2008, 2009, 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_NUMERICAL_SEMIRING_HXX
    00018 # define VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_NUMERICAL_SEMIRING_HXX
    00019
    00020 # include <cmath>
    00021 # include <vaucanson/algebra/concept/semiring_base.hh>
    00022 # include <vaucanson/algebra/implementation/semiring/numerical_semiring.hh>
    00023
    00024 # include <vaucanson/misc/random.hh>
    00025 # include <vaucanson/misc/limits.hh>
    00026 # include <vaucanson/misc/contract.hh>
    00027
    00028 namespace vcsn {
    00029
    00030   namespace algebra {
    00031
    00032     template<typename T>
    00033     bool op_contains(const algebra::NumericalSemiring&, T)
    00034     {
    00035       return true;
    00036     }
    00037
    00038     template<typename T, typename U>
    00039     void op_in_mul(const algebra::NumericalSemiring&,
    00040                    T& dst, U arg)
    00041     {
    00042       dst *= arg;
    00043     }
    00044
    00045     template<typename T, typename U>
    00046     void op_in_add(const algebra::NumericalSemiring&,
    00047                    T& dst, U arg)
    00048     {
    00049       dst += arg;
    00050     }
    00051
    00052     // FIXME: there should be specializations of op_add_traits and
    00053     // op_mul_traits giving the type of the result depending on the
    00054     // type of the arguments.
    00055
    00056     template<typename T, typename U>
    00057     T op_mul(const algebra::NumericalSemiring&, T a, U b)
    00058     {
    00059       return a * b;
    00060     }
    00061
    00062     template<typename T, typename U>
    00063     T op_add(const algebra::NumericalSemiring&, T a, U b)
    00064     {
    00065       return a + b;
    00066     }
    00067
    00068     template<typename T>
    00069     T identity_value(SELECTOR(algebra::NumericalSemiring), SELECTOR(T))
    00070     {
    00071       return T(1);
    00072     }
    00073
    00074     template<typename T>
    00075     bool show_identity_value(SELECTOR(algebra::NumericalSemiring), SELECTOR(T))
    00076     {
    00077       return false;
    00078     }
    00079
    00080     template<typename T>
    00081     T zero_value(SELECTOR(algebra::NumericalSemiring), SELECTOR(T))
    00082     {
    00083       return T(0);
    00084     }
    00085
    00086     template <class T>
    00087     Element<algebra::NumericalSemiring, T>
    00088     op_choose(const algebra::NumericalSemiring& set, SELECTOR(T))
    00089     {
    00090       return
    00091         Element<algebra::NumericalSemiring, T>
    00092           (set, misc::random::generate<T>());
    00093     }
    00094
    00095     /*-----------------------------.
    00096     | specializations for integers |
    00097     `-----------------------------*/
    00098
    00099     inline
    00100     bool
    00101     op_can_choose_non_starable(const algebra::NumericalSemiring&,
    00102                                 SELECTOR(int))
    00103     {
    00104       return true; // Every integer excepted Zero is non-starable
    00105     }
    00106
    00107     inline
    00108     Element<algebra::NumericalSemiring, int>
    00109     op_choose_starable(const algebra::NumericalSemiring& set, SELECTOR(int))
    00110     {
    00111       // 0 is the only one integer to be starable. So we have no choice !
    00112       return Element<algebra::NumericalSemiring, int>(set, 0);
    00113     }
    00114
    00115     inline
    00116     Element<algebra::NumericalSemiring, int>
    00117     op_choose_non_starable(const algebra::NumericalSemiring& set,
    00118                            SELECTOR(int))
    00119     {
    00120       int r = misc::random::generate<int>();
    00121       if (!r)
    00122         r = 1;
    00123       return Element<algebra::NumericalSemiring, int>(set, r);
    00124     }
    00125
    00126     /*-----------------------------.
    00127     | specializations for Booleans |
    00128     `-----------------------------*/
    00129     template <typename T>
    00130     void op_in_mul(const algebra::NumericalSemiring&, bool& dst, bool src)
    00131     {
    00132       dst = dst && src;
    00133     }
    00134
    00135     inline bool op_mul(const algebra::NumericalSemiring&, bool a, bool b)
    00136     {
    00137       return a && b;
    00138     }
    00139
    00140     inline void op_in_add(const algebra::NumericalSemiring&,
    00141                           bool& dst, bool src)
    00142     {
    00143       dst = dst || src;
    00144     }
    00145
    00146     inline bool op_add(const algebra::NumericalSemiring&, bool a, bool b)
    00147     {
    00148       return a || b;
    00149     }
    00150
    00151     inline bool identity_value(SELECTOR(algebra::NumericalSemiring),
    00152                                SELECTOR(bool))
    00153     {
    00154       return true;
    00155     }
    00156
    00157     inline bool zero_value(SELECTOR(algebra::NumericalSemiring),
    00158                            SELECTOR(bool))
    00159     {
    00160       return false;
    00161     }
    00162
    00163     inline bool op_starable(const algebra::NumericalSemiring&, bool)
    00164     {
    00165       return true;
    00166     }
    00167
    00168     inline void op_in_star(const algebra::NumericalSemiring&, bool& b)
    00169     {
    00170       b = true;
    00171     }
    00172
    00173     inline
    00174     Element<algebra::NumericalSemiring, bool>
    00175     op_choose_starable(const algebra::NumericalSemiring& set, SELECTOR(bool))
    00176     {
    00177       // Every Boolean is starable !
    00178       return op_choose(set, SELECT(bool));
    00179     }
    00180
    00181     inline
    00182     Element<algebra::NumericalSemiring, bool>
    00183     op_choose_non_starable(const algebra::NumericalSemiring& set,
    00184                            SELECTOR(bool))
    00185     {
    00186       assertion_(false, "Cannot choose non-starable boolean: all boolean are starable.");
    00187       return Element<algebra::NumericalSemiring, bool>(set, false);
    00188     }
    00189
    00190     /*--------------------------------------------.
    00191     | specialization for floating point numbers.  |
    00192     `--------------------------------------------*/
    00193
    00194     inline float op_sub(const algebra::NumericalSemiring&, const float& a, const float& b)
    00195     {
    00196       return a - b;
    00197     }
    00198
    00199     inline double op_sub(const algebra::NumericalSemiring&, const double& a, const double& b)
    00200     {
    00201       return a - b;
    00202     }
    00203
    00204     inline float op_div(const algebra::NumericalSemiring&, const float& a, const float& b)
    00205     {
    00206       return a / b;
    00207     }
    00208
    00209     inline double op_div(const algebra::NumericalSemiring&, const double& a, const double& b)
    00210     {
    00211       return a / b;
    00212     }
    00213
    00214     inline bool op_eq(const algebra::NumericalSemiring&, float& a, float& b)
    00215     {
    00216       return std::abs(a - b) < 0.00001;
    00217     }
    00218
    00219     inline bool op_eq(const algebra::NumericalSemiring&, double& a, double& b)
    00220     {
    00221       return std::abs(a - b) < 0.00001;
    00222     }
    00223
    00224     template<typename T>
    00225     bool op_starable(const algebra::NumericalSemiring&, T v)
    00226     {
    00227       return v == 0;
    00228     }
    00229
    00230     inline bool op_starable(const algebra::NumericalSemiring&,
    00231                              const float& f)
    00232     {
    00233       return (-1.0 < f) && (f < 1.0);
    00234     }
    00235
    00236     inline bool op_starable(const algebra::NumericalSemiring&,
    00237                              const double& f)
    00238     {
    00239       return (-1.0 < f) && (f < 1.0);
    00240     }
    00241
    00242     inline void op_in_star(const algebra::NumericalSemiring&, float& f)
    00243     {
    00244       static_assertion(misc::limits<float>::has_infinity,
    00245                        float_has_infinity);
    00246       if (f < 1.0)
    00247         f = (1.0 / (1.0 - f));
    00248       else
    00249         f = misc::limits<float>::infinity();
    00250     }
    00251
    00252     inline void op_in_star(const algebra::NumericalSemiring&, double& f)
    00253     {
    00254       if (f < 1.0)
    00255         f = (1.0 / (1.0 - f));
    00256       else
    00257         assertion(! "star not defined.");
    00258     }
    00259
    00260     inline
    00261     bool
    00262     op_can_choose_non_starable(const algebra::NumericalSemiring&,
    00263                                 SELECTOR(float))
    00264     {
    00265       return true; // Every float which is less than -1 or greater than 1 is
    00266                    // non-starable.
    00267     }
    00268
    00269     inline
    00270     Element<algebra::NumericalSemiring, float>
    00271     op_choose_starable(const algebra::NumericalSemiring& set,
    00272                        SELECTOR(float))
    00273     {
    00274       float res = misc::random::generate<float>(-1, 1);
    00275
    00276       while (res == -1)
    00277         res = misc::random::generate<float>(-1, 1);
    00278       return
    00279         Element<algebra::NumericalSemiring, float>
    00280           (set, res);
    00281     }
    00282
    00283     inline
    00284     Element<algebra::NumericalSemiring, float>
    00285     op_choose_non_starable(const algebra::NumericalSemiring& set,
    00286                            SELECTOR(float))
    00287     {
    00288       float res = misc::random::generate<float>() * 1000.;
    00289       while (op_starable(set, res))
    00290         res = misc::random::generate<float>() * 1000.;
    00291       return Element<algebra::NumericalSemiring, float>(set, res);
    00292     }
    00293
    00294     inline
    00295     bool
    00296     op_can_choose_non_starable(const algebra::NumericalSemiring&,
    00297                                 SELECTOR(double))
    00298     {
    00299       return true; // Every float which is less than -1 or greater than 1 is
    00300                    // non-starable.
    00301     }
    00302
    00303     inline
    00304     Element<algebra::NumericalSemiring, double>
    00305     op_choose_starable(const algebra::NumericalSemiring& set,
    00306                        SELECTOR(double))
    00307     {
    00308       double res = misc::random::generate<double>(-1, 1);
    00309
    00310       while (res == -1)
    00311         res = misc::random::generate<double>(-1, 1);
    00312       return
    00313         Element<algebra::NumericalSemiring, double>
    00314           (set, res);
    00315    }
    00316
    00317     inline
    00318     Element<algebra::NumericalSemiring, double>
    00319     op_choose_non_starable(const algebra::NumericalSemiring& set,
    00320                            SELECTOR(double))
    00321     {
    00322       double res = misc::random::generate<double>() * 1000.;
    00323       while (op_starable(set, res))
    00324         res = misc::random::generate<double>() * 1000.;
    00325       return Element<algebra::NumericalSemiring, double>(set, res);
    00326     }
    00327     // FIXME: add some more operators as syntactic sugar
    00328
    00329
    00330     /*------------------------------------.
    00331     | specialization for rational numbers |
    00332      `------------------------------------*/
    00333
    00334
    00335     inline RationalNumber
    00336     op_sub(const algebra::NumericalSemiring&, const RationalNumber& a, const RationalNumber& b)
    00337     {
    00338       return a - b;
    00339     }
    00340
    00341     inline RationalNumber
    00342     op_div(const algebra::NumericalSemiring&, const RationalNumber& a, const RationalNumber& b)
    00343     {
    00344       return a / b;
    00345     }
    00346
    00347
    00348     inline algebra::RationalNumber
    00349     identity_value(SELECTOR(algebra::NumericalSemiring),
    00350                    SELECTOR(algebra::RationalNumber))
    00351     {
    00352       return algebra::RationalNumber(1);
    00353     }
    00354
    00355     inline algebra::RationalNumber
    00356     zero_value(SELECTOR(algebra::NumericalSemiring),
    00357                SELECTOR(algebra::RationalNumber))
    00358     {
    00359       return algebra::RationalNumber(0);
    00360     }
    00361
    00362     inline bool
    00363     op_starable(const algebra::NumericalSemiring&,
    00364                 const algebra::RationalNumber& r)
    00365     {
    00366       return std::abs(r.num_get()) < r.den_get ();
    00367     }
    00368
    00369     inline bool
    00370     op_starable(const algebra::NumericalSemiring&,
    00371                 algebra::RationalNumber& r)
    00372     {
    00373       return std::abs(r.num_get()) < r.den_get ();
    00374     }
    00375
    00376     inline void op_in_star(const algebra::NumericalSemiring&,
    00377                            algebra::RationalNumber& r)
    00378     {
    00379       if (std::abs(r.num_get()) < r.den_get ())
    00380       {
    00381         algebra::RationalNumber one = algebra::RationalNumber(1);
    00382         r = one / (one - r);
    00383       }
    00384       else
    00385         assertion(! "vcsn::algebra::RationalNumber: star not defined.");
    00386     }
    00387
    00388     inline
    00389     bool
    00390     op_can_choose_non_starable(const algebra::NumericalSemiring&,
    00391                                 SELECTOR(algebra::RationalNumber))
    00392     {
    00393       return true; // Every rational number which is greater than 1 and
    00394                    // less than -1 is non-starable
    00395     }
    00396
    00397     inline
    00398     Element<algebra::NumericalSemiring, algebra::RationalNumber>
    00399     op_choose_starable(const algebra::NumericalSemiring& set,
    00400                        SELECTOR(algebra::RationalNumber))
    00401     {
    00402       algebra::RationalNumber min = algebra::RationalNumber(-1, 1);
    00403       algebra::RationalNumber max = algebra::RationalNumber(1, 1);
    00404       return
    00405         Element<algebra::NumericalSemiring, algebra::RationalNumber>
    00406         (set, misc::random::generate<algebra::RationalNumber>(min, max));
    00407    }
    00408
    00409     inline
    00410     Element<algebra::NumericalSemiring, algebra::RationalNumber>
    00411     op_choose_non_starable(const algebra::NumericalSemiring& set,
    00412                            SELECTOR(algebra::RationalNumber))
    00413     {
    00414       algebra::RationalNumber res;
    00415       do
    00416         {
    00417           res = misc::random::generate<algebra::RationalNumber> ();
    00418         }
    00419       while (res.den_get () >= std::abs(res.num_get ()));
    00420       return Element<algebra::NumericalSemiring, algebra::RationalNumber> (set, res);
    00421     }
    00422
    00423   } // algebra
    00424
    00425 } // vcsn
    00426
    00427 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_NUMERICAL_SEMIRING_HXX