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

- File List
- File Members

# 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, 2008, 2009 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 # include <vaucanson/misc/algebra.hh>
    00023
    00024 # include <cmath>
    00025 # include <cstdlib>
    00026 # include <vector>
    00027
    00028 # include <iostream>
    00029
    00030 namespace vcsn {
    00031   namespace misc {
    00032     namespace random {
    00033
    00034       template<>
    00035       inline char generate<char> ()
    00036       {
    00037         // We do not want any 0, because it could generate errors in strings.
    00038         return char (1 + unsigned (rand ()) % ( (1 << (sizeof (char) * 8)) - 1));
    00039       }
    00040
    00041       template<>
    00042       inline char generate<char> (char min, char max)
    00043       {
    00044         unsigned range = unsigned (max - min) + 1;
    00045         return char (min + rand () % range);
    00046       }
    00047
    00048       inline char generate_letter ()
    00049       {
    00050         return generate<char> ('a', 'z');
    00051       }
    00052
    00053       inline char generate_digit ()
    00054       {
    00055         return generate<char> ('0', '9');
    00056       }
    00057
    00058       template<>
    00059       inline bool generate<bool> ()
    00060       {
    00061         return static_cast<bool> (rand () & 1);
    00062       }
    00063
    00064       template<>
    00065       inline int generate<int> ()
    00066       {
    00067         int res = rand () % vcsn::misc::limits<int>::max ();
    00068         return generate<bool> () ? res : res * -1;
    00069       }
    00070
    00071       template<>
    00072       inline int generate<int> (int min, int max)
    00073       {
    00074         unsigned range = unsigned (max - min) + 1;
    00075         return min + rand () % range;
    00076       }
    00077
    00078       template<>
    00079       inline unsigned generate<unsigned> ()
    00080       {
    00081         return rand () % vcsn::misc::limits<unsigned>::max ();
    00082       }
    00083
    00084       template<>
    00085       inline unsigned generate<unsigned> (unsigned min, unsigned max)
    00086       {
    00087         unsigned range = unsigned (max - min) + 1;
    00088         return min + rand () % range;
    00089       }
    00090
    00091       template<>
    00092       inline float generate<float> ()
    00093       {
    00094         // This formula comes from the caml stdlib. It generates numbers
    00095         // between -2 and 2 (values that can be starable or not).
    00096         return ( ((static_cast<float> (rand ()) / RAND_MAX +
    00097                    static_cast<float> (rand ())) / RAND_MAX +
    00098                   static_cast<float> (rand ())) / RAND_MAX) * 4 - 2;
    00099       }
    00100
    00101       template<>
    00102       inline float generate<float> (float min, float max)
    00103       {
    00104         float range = float (max - min);
    00105         float generate_one = ( (static_cast<float> (rand ()) / RAND_MAX +
    00106                                 static_cast<float> (rand ())) / RAND_MAX +
    00107                                static_cast<float> (rand ())) / RAND_MAX;
    00108
    00109         return min + generate_one * range;
    00110       }
    00111
    00112       template<>
    00113       inline double generate<double> ()
    00114       {
    00115         // This formula comes from the caml stdlib. It generates numbers
    00116         // between -2 and 2 (values that can be starable or not).
    00117         return ( ((static_cast<double> (rand ()) / RAND_MAX +
    00118                    static_cast<double> (rand ())) / RAND_MAX +
    00119                   static_cast<double> (rand ())) / RAND_MAX) * 4 - 2;
    00120       }
    00121
    00122       template<>
    00123       inline double generate<double> (double min, double max)
    00124       {
    00125         double range = double (max - min);
    00126         double generate_one = ( (static_cast<double> (rand ()) / RAND_MAX +
    00127                                  static_cast<double> (rand ())) / RAND_MAX +
    00128                                 static_cast<double> (rand ())) / RAND_MAX;
    00129
    00130         return min + generate_one * range;
    00131       }
    00132
    00133       template <class IteratorValueType, class Iterator, class OutputIterator>
    00134       void sample_n (const IteratorValueType&, Iterator first, Iterator end,
    00135                      OutputIterator out, unsigned n)
    00136       {
    00137         std::vector<IteratorValueType> from;
    00138         for (Iterator i = first; i != end; ++i)
    00139           from.push_back (*i);
    00140
    00141         while ( (from.size () > 0) && (n > 0))
    00142         {
    00143           int  c = generate<int> (0, from.size () - 1);
    00144           *out = from[c];
    00145           ++out;
    00146           from.erase (from.begin () + c);
    00147           --n;
    00148         }
    00149       }
    00150
    00151       template<>
    00152       inline
    00153       vcsn::algebra::RationalNumber
    00154       generate<vcsn::algebra::RationalNumber> ()
    00155       {
    00156         const int num = generate<int> ();
    00157         const unsigned denom =
    00158           generate<unsigned> (1, vcsn::misc::limits<unsigned>::max ());
    00159         return vcsn::algebra::RationalNumber (num, denom);
    00160       }
    00161
    00162       template<>
    00163       inline
    00164       vcsn::algebra::RationalNumber
    00165       generate<vcsn::algebra::RationalNumber>
    00166       (const vcsn::algebra::RationalNumber min,
    00167        const vcsn::algebra::RationalNumber max)
    00168       {
    00169         int left = min.num_get () ;
    00170         int right = max.num_get ();
    00171         int den = min.den_get () * max.den_get ();
    00172
    00173         const int ratio = right - left;
    00174
    00175         int n1 = generate<int> (0, (vcsn::misc::limits<int>::max () - 1) / ratio);
    00176         int n2 = generate<int> (0, (vcsn::misc::limits<int>::max () - 1) / ratio);
    00177
    00178         if (n1 > n2)
    00179           {
    00180             int swap = n1;
    00181             n1 = n2;
    00182             n2 = swap;
    00183           }
    00184
    00185         n2 *= den;
    00186
    00187         n1 = n1 * ratio + (left * n2);
    00188
    00189         if (n1 == n2)
    00190           --n1;
    00191         if (-n1 == n2)
    00192           ++n1;
    00193
    00194         return
    00195           vcsn::algebra::RationalNumber (n1, n2);
    00196       }
    00197
    00198 # define MAKE_PAIR_SPECIALIZATION(TYPE1, TYPE2) \
    00199       template <> \
    00200       inline \
    00201       std::pair<TYPE1, TYPE2> generate<std::pair<TYPE1, TYPE2> >() \
    00202       { \
    00203         return std::make_pair(generate<TYPE1> (), generate<TYPE2> ()); \
    00204       }
    00205
    00206       MAKE_PAIR_SPECIALIZATION(char, char)
    00207       MAKE_PAIR_SPECIALIZATION(char, int)
    00208       MAKE_PAIR_SPECIALIZATION(int,  int)
    00209       MAKE_PAIR_SPECIALIZATION(int,  char)
    00210
    00211 # undef MAKE_PAIR_SPECIALIZATION
    00212
    00213       template <>
    00214       inline
    00215       small_alpha_letter_t
    00216       generate<small_alpha_letter_t> ()
    00217       {
    00218         return generate<char> (small_alpha_interval_t::from_value,
    00219                                small_alpha_interval_t::to_value);
    00220       }
    00221
    00222     } // Random
    00223   } // misc
    00224 } // vcsn
    00225
    00226 #endif // ! VCSN_MISC_RANDOM_HXX