00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
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     
00053     
00054     
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 
00097 
00098 
00099     inline
00100     bool
00101     op_can_choose_non_starable(const algebra::NumericalSemiring&,
00102                                 SELECTOR(int))
00103     {
00104       return true; 
00105     }
00106 
00107     inline
00108     Element<algebra::NumericalSemiring, int>
00109     op_choose_starable(const algebra::NumericalSemiring& set, SELECTOR(int))
00110     {
00111       
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 
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       
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 
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; 
00266                    
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; 
00300                    
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     
00328 
00329 
00330     
00331 
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; 
00394                    
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   } 
00424 
00425 } 
00426 
00427 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_NUMERICAL_SEMIRING_HXX