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