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

Generated on Sun Jul 29 19:35:28 2007 for Vaucanson by  doxygen 1.5.2