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&, bool& dst, bool src)
00124 {
00125 dst = dst && src;
00126 }
00127
00128 inline bool op_mul(const algebra::NumericalSemiring&, bool a, bool b)
00129 {
00130 return a && b;
00131 }
00132
00133 inline void op_in_add(const algebra::NumericalSemiring&,
00134 bool& dst, bool src)
00135 {
00136 dst = dst || src;
00137 }
00138
00139 inline bool op_add(const algebra::NumericalSemiring&, bool a, bool b)
00140 {
00141 return a || b;
00142 }
00143
00144 inline bool identity_value(SELECTOR(algebra::NumericalSemiring),
00145 SELECTOR(bool))
00146 {
00147 return true;
00148 }
00149
00150 inline bool zero_value(SELECTOR(algebra::NumericalSemiring),
00151 SELECTOR(bool))
00152 {
00153 return false;
00154 }
00155
00156 inline bool op_starable(const algebra::NumericalSemiring&, bool)
00157 {
00158 return true;
00159 }
00160
00161 inline void op_in_star(const algebra::NumericalSemiring&, bool& b)
00162 {
00163 b = true;
00164 }
00165
00166 inline
00167 Element<algebra::NumericalSemiring, bool>
00168 op_choose_starable(const algebra::NumericalSemiring& set, SELECTOR(bool))
00169 {
00170
00171 return op_choose(set, SELECT(bool));
00172 }
00173
00174 inline
00175 Element<algebra::NumericalSemiring, bool>
00176 op_choose_non_starable(const algebra::NumericalSemiring& set,
00177 SELECTOR(bool))
00178 {
00179 assertion_(false, "Cannot choose non-starable boolean: all boolean are starable.");
00180 return Element<algebra::NumericalSemiring, bool>(set, false);
00181 }
00182
00183
00184
00185
00186
00187 inline float op_sub(const algebra::NumericalSemiring&, const float& a, const float& b)
00188 {
00189 return a - b;
00190 }
00191
00192 inline double op_sub(const algebra::NumericalSemiring&, const double& a, const double& b)
00193 {
00194 return a - b;
00195 }
00196
00197 inline float op_div(const algebra::NumericalSemiring&, const float& a, const float& b)
00198 {
00199 return a / b;
00200 }
00201
00202 inline double op_div(const algebra::NumericalSemiring&, const double& a, const double& b)
00203 {
00204 return a / b;
00205 }
00206
00207 inline bool op_eq(const algebra::NumericalSemiring&, float& a, float& b)
00208 {
00209 return std::abs(a - b) < 0.00001;
00210 }
00211
00212 inline bool op_eq(const algebra::NumericalSemiring&, double& a, double& b)
00213 {
00214 return std::abs(a - b) < 0.00001;
00215 }
00216
00217 template<typename T>
00218 bool op_starable(const algebra::NumericalSemiring&, T v)
00219 {
00220 return v == 0;
00221 }
00222
00223 inline bool op_starable(const algebra::NumericalSemiring&,
00224 const float& f)
00225 {
00226 return (-1.0 < f) && (f < 1.0);
00227 }
00228
00229 inline bool op_starable(const algebra::NumericalSemiring&,
00230 const double& f)
00231 {
00232 return (-1.0 < f) && (f < 1.0);
00233 }
00234
00235 inline void op_in_star(const algebra::NumericalSemiring&, float& f)
00236 {
00237 static_assertion(misc::limits<float>::has_infinity,
00238 float_has_infinity);
00239 if (f < 1.0)
00240 f = (1.0 / (1.0 - f));
00241 else
00242 f = misc::limits<float>::infinity();
00243 }
00244
00245 inline void op_in_star(const algebra::NumericalSemiring&, double& f)
00246 {
00247 if (f < 1.0)
00248 f = (1.0 / (1.0 - f));
00249 else
00250 assertion(! "star not defined.");
00251 }
00252
00253 inline
00254 bool
00255 op_can_choose_non_starable(const algebra::NumericalSemiring&,
00256 SELECTOR(float))
00257 {
00258 return true;
00259
00260 }
00261
00262 inline
00263 Element<algebra::NumericalSemiring, float>
00264 op_choose_starable(const algebra::NumericalSemiring& set,
00265 SELECTOR(float))
00266 {
00267 float res = misc::random::generate<float>(-1, 1);
00268
00269 while (res == -1)
00270 res = misc::random::generate<float>(-1, 1);
00271 return
00272 Element<algebra::NumericalSemiring, float>
00273 (set, res);
00274 }
00275
00276 inline
00277 Element<algebra::NumericalSemiring, float>
00278 op_choose_non_starable(const algebra::NumericalSemiring& set,
00279 SELECTOR(float))
00280 {
00281 float res = misc::random::generate<float>() * 1000.;
00282 while (op_starable(set, res))
00283 res = misc::random::generate<float>() * 1000.;
00284 return Element<algebra::NumericalSemiring, float>(set, res);
00285 }
00286
00287 inline
00288 bool
00289 op_can_choose_non_starable(const algebra::NumericalSemiring&,
00290 SELECTOR(double))
00291 {
00292 return true;
00293
00294 }
00295
00296 inline
00297 Element<algebra::NumericalSemiring, double>
00298 op_choose_starable(const algebra::NumericalSemiring& set,
00299 SELECTOR(double))
00300 {
00301 double res = misc::random::generate<double>(-1, 1);
00302
00303 while (res == -1)
00304 res = misc::random::generate<double>(-1, 1);
00305 return
00306 Element<algebra::NumericalSemiring, double>
00307 (set, res);
00308 }
00309
00310 inline
00311 Element<algebra::NumericalSemiring, double>
00312 op_choose_non_starable(const algebra::NumericalSemiring& set,
00313 SELECTOR(double))
00314 {
00315 double res = misc::random::generate<double>() * 1000.;
00316 while (op_starable(set, res))
00317 res = misc::random::generate<double>() * 1000.;
00318 return Element<algebra::NumericalSemiring, double>(set, res);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327 inline algebra::RationalNumber
00328 identity_value(SELECTOR(algebra::NumericalSemiring),
00329 SELECTOR(algebra::RationalNumber))
00330 {
00331 return algebra::RationalNumber(1);
00332 }
00333
00334 inline algebra::RationalNumber
00335 zero_value(SELECTOR(algebra::NumericalSemiring),
00336 SELECTOR(algebra::RationalNumber))
00337 {
00338 return algebra::RationalNumber(0);
00339 }
00340
00341 inline bool op_starable(const algebra::NumericalSemiring&,
00342 const algebra::RationalNumber& r)
00343 {
00344 int denom = r.denom();
00345 return std::abs(r.num()) < denom;
00346 }
00347
00348 inline void op_in_star(const algebra::NumericalSemiring&,
00349 algebra::RationalNumber& r)
00350 {
00351 int denom = r.denom();
00352 algebra::RationalNumber one = algebra::RationalNumber(1, 1);
00353 if (denom > std::abs(r.num()))
00354 r = (one / (r - one));
00355 else
00356 assertion(! "star not defined.");
00357 }
00358
00359 inline
00360 bool
00361 op_can_choose_non_starable(const algebra::NumericalSemiring&,
00362 SELECTOR(algebra::RationalNumber))
00363 {
00364 return true;
00365
00366 }
00367
00368 inline
00369 Element<algebra::NumericalSemiring, algebra::RationalNumber>
00370 op_choose_starable(const algebra::NumericalSemiring& set,
00371 SELECTOR(algebra::RationalNumber))
00372 {
00373 algebra::RationalNumber min = algebra::RationalNumber(-1, 1);
00374 algebra::RationalNumber max = algebra::RationalNumber(1, 1);
00375 return
00376 Element<algebra::NumericalSemiring, algebra::RationalNumber>
00377 (set, misc::random::generate<algebra::RationalNumber>(min, max));
00378 }
00379
00380 inline
00381 Element<algebra::NumericalSemiring, algebra::RationalNumber>
00382 op_choose_non_starable(const algebra::NumericalSemiring& set,
00383 SELECTOR(algebra::RationalNumber))
00384 {
00385 algebra::RationalNumber res = algebra::RationalNumber(1, 1);
00386 int denom;
00387 do
00388 {
00389 res = misc::random::generate<algebra::RationalNumber>();
00390 denom = res.denom();
00391 }
00392 while (denom > std::abs(res.num()));
00393 return
00394 Element<algebra::NumericalSemiring, algebra::RationalNumber>
00395 (set, res);
00396 }
00397
00398 }
00399
00400 }
00401
00402 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SEMIRING_NUMERICAL_SEMIRING_HXX