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