00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_MISC_RANDOM_HXX
00018 # define VCSN_MISC_RANDOM_HXX
00019
00020 # include <vaucanson/misc/random.hh>
00021 # include <vaucanson/misc/limits.hh>
00022
00023 # include <cmath>
00024 # include <cstdlib>
00025 # include <vector>
00026
00027 namespace vcsn {
00028 namespace misc {
00029 namespace random {
00030
00031 template<>
00032 inline char generate<char> ()
00033 {
00034
00035 return char (1 + unsigned (rand ()) % ( (1 << (sizeof (char) * 8)) - 1));
00036 }
00037
00038 template<>
00039 inline char generate<char> (char min, char max)
00040 {
00041 unsigned range = unsigned (max - min) + 1;
00042 return char (min + rand () % range);
00043 }
00044
00045 inline char generate_letter ()
00046 {
00047 return generate<char> ('a', 'z');
00048 }
00049
00050 inline char generate_digit ()
00051 {
00052 return generate<char> ('0', '9');
00053 }
00054
00055 template<>
00056 inline bool generate<bool> ()
00057 {
00058 return static_cast<bool> (rand () & 1);
00059 }
00060
00061 template<>
00062 inline int generate<int> ()
00063 {
00064 int res = rand () % vcsn::misc::limits<int>::max ();
00065 return generate<bool> () ? res : res * -1;
00066 }
00067
00068 template<>
00069 inline int generate<int> (int min, int max)
00070 {
00071 unsigned range = unsigned (max - min) + 1;
00072 return min + rand () % range;
00073 }
00074
00075 template<>
00076 inline unsigned generate<unsigned> ()
00077 {
00078 return rand () % vcsn::misc::limits<unsigned>::max ();
00079 }
00080
00081 template<>
00082 inline unsigned generate<unsigned> (unsigned min, unsigned max)
00083 {
00084 unsigned range = unsigned (max - min) + 1;
00085 return min + rand () % range;
00086 }
00087
00088 template<>
00089 inline float generate<float> ()
00090 {
00091
00092
00093 return ( ((static_cast<float> (rand ()) / RAND_MAX +
00094 static_cast<float> (rand ())) / RAND_MAX +
00095 static_cast<float> (rand ())) / RAND_MAX) * 4 - 2;
00096 }
00097
00098 template<>
00099 inline float generate<float> (float min, float max)
00100 {
00101 float range = float (max - min);
00102 float generate_one = ( (static_cast<float> (rand ()) / RAND_MAX +
00103 static_cast<float> (rand ())) / RAND_MAX +
00104 static_cast<float> (rand ())) / RAND_MAX;
00105
00106 return min + generate_one * range;
00107 }
00108
00109 template<>
00110 inline double generate<double> ()
00111 {
00112
00113
00114 return ( ((static_cast<double> (rand ()) / RAND_MAX +
00115 static_cast<double> (rand ())) / RAND_MAX +
00116 static_cast<double> (rand ())) / RAND_MAX) * 4 - 2;
00117 }
00118
00119 template<>
00120 inline double generate<double> (double min, double max)
00121 {
00122 double range = double (max - min);
00123 double generate_one = ( (static_cast<double> (rand ()) / RAND_MAX +
00124 static_cast<double> (rand ())) / RAND_MAX +
00125 static_cast<double> (rand ())) / RAND_MAX;
00126
00127 return min + generate_one * range;
00128 }
00129
00130 template <class IteratorValueType, class Iterator, class OutputIterator>
00131 void sample_n (const IteratorValueType&, Iterator first, Iterator end,
00132 OutputIterator out, unsigned n)
00133 {
00134 std::vector<IteratorValueType> from;
00135 for (Iterator i = first; i != end; ++i)
00136 from.push_back (*i);
00137
00138 while ( (from.size () > 0) && (n > 0))
00139 {
00140 int c = generate<int> (0, from.size () - 1);
00141 *out = from[c];
00142 ++out;
00143 from.erase (from.begin () + c);
00144 --n;
00145 }
00146 }
00147
00148 template<>
00149 inline
00150 vcsn::algebra::RationalNumber
00151 generate<vcsn::algebra::RationalNumber> ()
00152 {
00153 const int num = generate<int> ();
00154 const unsigned denom =
00155 generate<unsigned> (1, vcsn::misc::limits<unsigned>::max ());
00156 return vcsn::algebra::RationalNumber (num, denom);
00157 }
00158
00159 template<>
00160 inline
00161 vcsn::algebra::RationalNumber
00162 generate<vcsn::algebra::RationalNumber>
00163 (const vcsn::algebra::RationalNumber min,
00164 const vcsn::algebra::RationalNumber max)
00165 {
00166 const int denom = vcsn::algebra::lcm (min.denom (), max.denom ());
00167 const int num1 = min.num ()*denom/min.denom ();
00168 const int num2 = max.num ()*denom/max.denom ();
00169 const int maxi = std::max(std::max(std::abs(num1),
00170 std::abs(num2)), denom);
00171 const int ratio = (vcsn::misc::limits<int>::max ()-1)/maxi;
00172 return
00173 vcsn::algebra::RationalNumber (generate<int> (num1*ratio, num2*ratio),
00174 denom * ratio);
00175 }
00176
00177 # define MAKE_PAIR_SPECIALIZATION(TYPE1, TYPE2) \
00178 template <> \
00179 inline \
00180 std::pair<TYPE1, TYPE2> generate<std::pair<TYPE1, TYPE2> >() \
00181 { \
00182 return std::make_pair(generate<TYPE1> (), generate<TYPE2> ()); \
00183 }
00184
00185 MAKE_PAIR_SPECIALIZATION(char, char)
00186 MAKE_PAIR_SPECIALIZATION(char, int)
00187 MAKE_PAIR_SPECIALIZATION(int, int)
00188 MAKE_PAIR_SPECIALIZATION(int, char)
00189
00190 # undef MAKE_PAIR_SPECIALIZATION
00191
00192 template <>
00193 inline
00194 small_alpha_letter_t
00195 generate<small_alpha_letter_t> ()
00196 {
00197 return generate<char> (small_alpha_interval_t::from_value,
00198 small_alpha_interval_t::to_value);
00199 }
00200
00201 }
00202 }
00203 }
00204
00205 #endif // ! VCSN_MISC_RANDOM_HXX