00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef SYNAPS_UTIL_RAND_H
00017 #define SYNAPS_UTIL_RAND_H
00018
00019 #include <cstdlib>
00020 #include <limits>
00021 #include <ctime>
00022 #include <synaps/init.h>
00023 #include <synaps/arithm/Abs.h>
00024 #include <synaps/arithm/gmp.h>
00025
00026 __BEGIN_NAMESPACE_SYNAPS
00027
00028
00034 template<class C = double>
00035 class Rand
00036 {
00037 private:
00038 C m_;
00039 C M_;
00040 unsigned long int seed_;
00041
00042 void init()
00043 { std::srand(seed_); }
00044
00045 public:
00046 typedef C value_type;
00047
00048 Rand()
00049 : m_(C(-100000)),
00050 M_(C(100000)),
00051 seed_( (unsigned long )std::time(NULL) )
00052 { init(); }
00053
00054 Rand(const C& M)
00055 : m_(0), M_(M), seed_( (unsigned long)std::time(NULL) )
00056 { init(); }
00057
00058 Rand(const C& m, const C& M)
00059 : m_(m), M_(M), seed_( (unsigned long)std::time(NULL) )
00060 { init(); }
00061
00062 Rand(const C& m, const C& M, const unsigned long int& seed)
00063 : m_(m), M_(M), seed_(seed)
00064 { init(); }
00065
00066 bool get_rand_bool()
00067 {
00068 int r = int( ( double(std::rand())/RAND_MAX ) * 10 );
00069 return (r < 5 ? false : true);
00070 }
00071
00072 C operator()(void)
00073 {
00074 C U;
00075 if (m_ < 0)
00076 U = M_ + (m_ < 0 ? -m_ : m_) + 1;
00077 else
00078 U = M_ - m_ + 1;
00079 C r = C( ( double(std::rand())/RAND_MAX ) * U );
00080 return (r + m_);
00081 }
00082
00083 C operator()(const C& m, const C& M)
00084 {
00085 C U;
00086 if (m < 0)
00087 U = M + (m_ < 0 ? -m_ : m_) + 1;
00088 else
00089 U = M - m + 1;
00090 C r = C( ( double(std::rand())/RAND_MAX ) * U );
00091 return (r + m);
00092 }
00093
00094 };
00095
00096 #ifdef SYNAPS_WITH_GMP
00097
00105 template<>
00106 class Rand<ZZ>
00107 {
00108 private:
00109 ZZ m_;
00110 ZZ M_;
00111 gmp_randstate_t rstate_;
00112 unsigned long int seed_;
00113
00114 void init()
00115 {
00116 gmp_randinit (rstate_, GMP_RAND_ALG_LC, 32);
00117 gmp_randseed_ui(rstate_, seed_);
00118 }
00119
00120 public:
00121 typedef ZZ value_type;
00122
00123 Rand()
00124 : m_(std::numeric_limits<long>::min()),
00125 M_(std::numeric_limits<long>::max()),
00126 seed_( (unsigned)std::time(NULL) )
00127 { init(); }
00128
00129 Rand(const ZZ& M)
00130 : m_(0), M_(M), seed_( (unsigned)std::time(NULL) )
00131 { init(); }
00132
00133 Rand(const ZZ& m, const ZZ& M)
00134 : m_(m), M_(M), seed_( (unsigned)std::time(NULL) )
00135 { init(); }
00136
00137 Rand(const ZZ& m, const ZZ& M, const unsigned long int& seed)
00138 : m_(m), M_(M), seed_(seed)
00139 { init(); }
00140
00141 ZZ operator()(void)
00142 {
00143 ZZ U;
00144 if (m_ < 0)
00145 U = M_ + abs(m_) + 1;
00146 else
00147 U = M_ - m_ + 1;
00148 ZZ r;
00149 mpz_urandomm(r.get_mpz_t(), rstate_, U.get_mpz_t());
00150 return (r + m_);
00151 }
00152
00153 ZZ operator()(const ZZ& m, const ZZ& M)
00154 {
00155 ZZ U;
00156 if (m < 0)
00157 U = M + abs(m) + 1;
00158 else
00159 U = M - m + 1;
00160 ZZ r;
00161 mpz_urandomm(r.get_mpz_t(), rstate_, U.get_mpz_t());
00162 return (r + m);
00163 }
00164
00165
00166 bool get_rand_bool()
00167 {
00168 ZZ r;
00169 ZZ t(2);
00170 mpz_urandomm(r.get_mpz_t(), rstate_, t.get_mpz_t());
00171 return (r == 0 ? false : true);
00172 }
00173
00174 ~Rand()
00175 { gmp_randclear(rstate_); }
00176 };
00177
00178 #endif //SYNAPS_WITH_GMP
00179
00180
00181 __END_NAMESPACE_SYNAPS
00182
00183 #endif // SYNAPS_UTIL_RAND_H
00184