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 # include <vaucanson/misc/random.hh>
00024 # include <vaucanson/misc/limits.hh>
00025 # include <vaucanson/misc/contract.hh>
00026 
00027 namespace vcsn {
00028 
00029   namespace algebra {
00030 
00031     template<typename T>
00032     bool op_contains(const algebra::NumericalSemiring&, T)
00033     {
00034       return true;
00035     }
00036 
00037     template<typename T, typename U>
00038     void op_in_mul(const algebra::NumericalSemiring&,
00039                    T& dst, U arg)
00040     {
00041       dst *= arg;
00042     }
00043 
00044     template<typename T, typename U>
00045     void op_in_add(const algebra::NumericalSemiring&,
00046                    T& dst, U arg)
00047     {
00048       dst += arg;
00049     }
00050 
00051     
00052     
00053     
00054 
00055     template<typename T, typename U>
00056     T op_mul(const algebra::NumericalSemiring&, T a, U b)
00057     {
00058       return a * b;
00059     }
00060 
00061     template<typename T, typename U>
00062     T op_add(const algebra::NumericalSemiring&, T a, U b)
00063     {
00064       return a + b;
00065     }
00066 
00067     template<typename T>
00068     T identity_value(SELECTOR(algebra::NumericalSemiring), SELECTOR(T))
00069     {
00070       return T(1);
00071     }
00072 
00073     template<typename T>
00074     T zero_value(SELECTOR(algebra::NumericalSemiring), SELECTOR(T))
00075     {
00076       return T(0);
00077     }
00078 
00079     template <class T>
00080     Element<algebra::NumericalSemiring, T>
00081     op_choose(const algebra::NumericalSemiring& set, SELECTOR(T))
00082     {
00083       return
00084         Element<algebra::NumericalSemiring, T>
00085           (set, misc::random::generate<T>());
00086     }
00087 
00088     
00089 
00090 
00091 
00092     inline
00093     bool
00094     op_can_choose_non_starable(const algebra::NumericalSemiring&,
00095                                 SELECTOR(int))
00096     {
00097       return true; 
00098     }
00099 
00100     inline
00101     Element<algebra::NumericalSemiring, int>
00102     op_choose_starable(const algebra::NumericalSemiring& set, SELECTOR(int))
00103     {
00104       
00105       return Element<algebra::NumericalSemiring, int>(set, 0);
00106     }
00107 
00108     inline
00109     Element<algebra::NumericalSemiring, int>
00110     op_choose_non_starable(const algebra::NumericalSemiring& set,
00111                            SELECTOR(int))
00112     {
00113       int r = misc::random::generate<int>();
00114       if (!r)
00115         r = 1;
00116       return Element<algebra::NumericalSemiring, int>(set, r);
00117     }
00118 
00119     
00120 
00121 
00122     template<typename T>
00123     void op_in_mul(const algebra::NumericalSemiring&,
00124                           bool& dst, bool src)
00125     {
00126       dst = dst && src;
00127     }
00128 
00129     inline bool op_mul(const algebra::NumericalSemiring&, bool a, bool b)
00130     {
00131       return a && b;
00132     }
00133 
00134     inline void op_in_add(const algebra::NumericalSemiring&,
00135                           bool& dst, bool src)
00136     {
00137       dst = dst || src;
00138     }
00139 
00140     inline bool op_add(const algebra::NumericalSemiring&, bool a, bool b)
00141     {
00142       return a || b;
00143     }
00144 
00145     inline bool identity_value(SELECTOR(algebra::NumericalSemiring),
00146                                SELECTOR(bool))
00147     {
00148       return true;
00149     }
00150 
00151     inline bool zero_value(SELECTOR(algebra::NumericalSemiring),
00152                            SELECTOR(bool))
00153     {
00154       return false;
00155     }
00156 
00157     inline bool op_starable(const algebra::NumericalSemiring&, bool)
00158     {
00159       return true;
00160     }
00161 
00162     inline void op_in_star(const algebra::NumericalSemiring&, bool& b)
00163     {
00164       b = true;
00165     }
00166 
00167     inline
00168     Element<algebra::NumericalSemiring, bool>
00169     op_choose_starable(const algebra::NumericalSemiring& set, SELECTOR(bool))
00170     {
00171       
00172       return op_choose(set, SELECT(bool));
00173     }
00174 
00175     inline
00176     Element<algebra::NumericalSemiring, bool>
00177     op_choose_non_starable(const algebra::NumericalSemiring& set,
00178                            SELECTOR(bool))
00179     {
00180       assertion_(false, "Cannot choose non-starable boolean: all boolean are starable.");
00181       return Element<algebra::NumericalSemiring, bool>(set, false);
00182     }
00183 
00184     
00185 
00186 
00187 
00188     template<typename T>
00189     bool op_starable(const algebra::NumericalSemiring&, T v)
00190     {
00191       return v == 0;
00192     }
00193 
00194     inline bool op_starable(const algebra::NumericalSemiring&,
00195                              const float& f)
00196     {
00197       return (-1.0 < f) && (f < 1.0);
00198     }
00199 
00200     inline bool op_starable(const algebra::NumericalSemiring&,
00201                              const double& f)
00202     {
00203       return (-1.0 < f) && (f < 1.0);
00204     }
00205 
00206     inline void op_in_star(const algebra::NumericalSemiring&, float& f)
00207     {
00208       static_assertion(misc::limits<float>::has_infinity,
00209                        float_has_infinity);
00210       if (f < 1.0)
00211         f = (1.0 / (1.0 - f));
00212       else
00213         f = misc::limits<float>::infinity();
00214     }
00215 
00216     inline void op_in_star(const algebra::NumericalSemiring&, double& f)
00217     {
00218       if (f < 1.0)
00219         f = (1.0 / (1.0 - f));
00220       else
00221         assertion(! "star not defined.");
00222     }
00223 
00224     inline
00225     bool
00226     op_can_choose_non_starable(const algebra::NumericalSemiring&,
00227                                 SELECTOR(float))
00228     {
00229       return true; 
00230                    
00231     }
00232 
00233     inline
00234     Element<algebra::NumericalSemiring, float>
00235     op_choose_starable(const algebra::NumericalSemiring& set,
00236                        SELECTOR(float))
00237     {
00238       float res = misc::random::generate<float>(-1, 1);
00239 
00240       while (res == -1)
00241         res = misc::random::generate<float>(-1, 1);
00242       return
00243         Element<algebra::NumericalSemiring, float>
00244           (set, res);
00245     }
00246 
00247     inline
00248     Element<algebra::NumericalSemiring, float>
00249     op_choose_non_starable(const algebra::NumericalSemiring& set,
00250                            SELECTOR(float))
00251     {
00252       float res = misc::random::generate<float>() * 1000.;
00253       while (op_starable(set, res))
00254         res = misc::random::generate<float>() * 1000.;
00255       return Element<algebra::NumericalSemiring, float>(set, res);
00256     }
00257 
00258     inline
00259     bool
00260     op_can_choose_non_starable(const algebra::NumericalSemiring&,
00261                                 SELECTOR(double))
00262     {
00263       return true; 
00264                    
00265     }
00266 
00267     inline
00268     Element<algebra::NumericalSemiring, double>
00269     op_choose_starable(const algebra::NumericalSemiring& set,
00270                        SELECTOR(double))
00271     {
00272       double res = misc::random::generate<double>(-1, 1);
00273 
00274       while (res == -1)
00275         res = misc::random::generate<double>(-1, 1);
00276       return
00277         Element<algebra::NumericalSemiring, double>
00278           (set, res);
00279     }
00280 
00281     inline
00282     Element<algebra::NumericalSemiring, double>
00283     op_choose_non_starable(const algebra::NumericalSemiring& set,
00284                            SELECTOR(double))
00285     {
00286       double res = misc::random::generate<double>() * 1000.;
00287       while (op_starable(set, res))
00288         res = misc::random::generate<double>() * 1000.;
00289       return Element<algebra::NumericalSemiring, double>(set, res);
00290     }
00291     
00292 
00293 
00294     
00295 
00296 
00297 
00298     inline algebra::RationalNumber
00299     identity_value(SELECTOR(algebra::NumericalSemiring),
00300                    SELECTOR(algebra::RationalNumber))
00301     {
00302       return algebra::RationalNumber(1);
00303     }
00304 
00305     inline algebra::RationalNumber
00306     zero_value(SELECTOR(algebra::NumericalSemiring),
00307                SELECTOR(algebra::RationalNumber))
00308     {
00309       return algebra::RationalNumber(0);
00310     }
00311 
00312     inline bool op_starable(const algebra::NumericalSemiring&,
00313                             const algebra::RationalNumber& r)
00314     {
00315       int denom = r.denom();
00316       return abs(r.num()) < denom;
00317     }
00318 
00319     inline void op_in_star(const algebra::NumericalSemiring&,
00320                            algebra::RationalNumber& r)
00321     {
00322       int denom = r.denom();
00323       algebra::RationalNumber one = algebra::RationalNumber(1, 1);
00324       if (denom > abs(r.num()))
00325         r = (one / (r - one));
00326       else
00327         assertion(! "star not defined.");
00328     }
00329 
00330     inline
00331     bool
00332     op_can_choose_non_starable(const algebra::NumericalSemiring&,
00333                                 SELECTOR(algebra::RationalNumber))
00334     {
00335       return true; 
00336                    
00337     }
00338 
00339     inline
00340     Element<algebra::NumericalSemiring, algebra::RationalNumber>
00341     op_choose_starable(const algebra::NumericalSemiring& set,
00342                        SELECTOR(algebra::RationalNumber))
00343     {
00344       algebra::RationalNumber min = algebra::RationalNumber(-1, 1);
00345       algebra::RationalNumber max = algebra::RationalNumber(1, 1);
00346       return
00347         Element<algebra::NumericalSemiring, algebra::RationalNumber>
00348           (set, misc::random::generate<algebra::RationalNumber>(min, max));
00349     }
00350 
00351     inline
00352     Element<algebra::NumericalSemiring, algebra::RationalNumber>
00353     op_choose_non_starable(const algebra::NumericalSemiring& set,
00354                            SELECTOR(algebra::RationalNumber))
00355     {
00356       algebra::RationalNumber res = algebra::RationalNumber(1, 1);
00357       int denom;
00358       do
00359         {
00360           res = misc::random::generate<algebra::RationalNumber>();
00361           denom = res.denom();
00362         }
00363       while (denom > abs(res.num()));
00364       return
00365         Element<algebra::NumericalSemiring, algebra::RationalNumber>
00366         (set, res);
00367     }
00368 
00369   } 
00370 
00371 } 
00372 
00373 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_NUMERICAL_SEMIRING_HXX