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