synaps/base/Rand.h

00001 // Copyright (c) 2004  INRIA Sophia-Antipolis (France) and
00002 //                     Department of Informatics and Telecommunications
00003 //                     University of Athens (Greece).
00004 // All rights reserved.
00005 //
00006 // Authors : Elias P. TSIGARIDAS <et@di.uoa.gr>
00007 
00008 // Partially supported by INRIA's project "CALAMATA", a
00009 // bilateral collaboration with National Kapodistrian University of
00010 // Athens.
00011 // Partially supported by the IST Programme of the EU as a Shared-cost
00012 // RTD (FET Open) Project under Contract No  IST-2000-26473
00013 // (ECG - Effective Computational Geometry for Curves and Surfaces)
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 

SYNAPS DOCUMENTATION
logo