- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

# random.hxx

    00001 // random.hxx: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 The Vaucanson Group.
    00006 //
    00007 // This program is free software; you can redistribute it and/or
    00008 // modify it under the terms of the GNU General Public License
    00009 // as published by the Free Software Foundation; either version 2
    00010 // of the License, or (at your option) any later version.
    00011 //
    00012 // The complete GNU General Public Licence Notice can be found as the
    00013 // `COPYING' file in the root directory.
    00014 //
    00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
    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         // We do not want any 0, because it could generate errors in strings.
    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         // This formula comes from the caml stdlib. It generates numbers
    00092         // between -2 and 2 (values that can be starable or not).
    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         // This formula comes from the caml stdlib. It generates numbers
    00113         // between -2 and 2 (values that can be starable or not).
    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 Iterator, class OutputIterator>
    00131       void sample_n (Iterator first, Iterator end,
    00132                      OutputIterator out, unsigned n)
    00133       {
    00134         std::vector<int> 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 (abs (num1), abs (num2)),denom);
    00170         const int ratio = (vcsn::misc::limits<int>::max ()-1)/maxi;
    00171         return
    00172           vcsn::algebra::RationalNumber (generate<int> (num1*ratio, num2*ratio),
    00173                                          denom * ratio);
    00174       }
    00175
    00176       template <>
    00177       inline
    00178       std::pair<char, int> generate<std::pair<char, int> > ()
    00179       {
    00180         return std::make_pair (generate<char> (), generate<int> ());
    00181       }
    00182
    00183       template <>
    00184       inline
    00185       small_alpha_letter_t
    00186       generate<small_alpha_letter_t> ()
    00187       {
    00188         return generate<char> (small_alpha_interval_t::from_value,
    00189                                small_alpha_interval_t::to_value);
    00190       }
    00191
    00192     } // Random
    00193   } // misc
    00194 } // vcsn
    00195
    00196 #endif // ! VCSN_MISC_RANDOM_HXX