Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_MATH_RANDOM_H
00002 #define OPENTISSUE_CORE_MATH_MATH_RANDOM_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <boost/cast.hpp>
00013
00014 #include <OpenTissue/core/math/math_constants.h>
00015
00016
00017 #ifdef BOOST_VERSION //--- FIXME: Nicer way too see if we have boost?
00018 # include <boost/random.hpp>
00019 #else
00020 # include <ctime>
00021 # include <cstdlib>
00022 #endif
00023
00024 namespace OpenTissue
00025 {
00026
00027 namespace math
00028 {
00029
00030 #ifdef BOOST_RANDOM_HPP
00031
00032
00033 template<typename value_type>
00034 class Random
00035 {
00036 public:
00037
00038 typedef boost::minstd_rand generator_type;
00039
00040 protected:
00041
00042 static generator_type & generator()
00043 {
00044 static generator_type tmp(static_cast<unsigned int>(std::time(0)));
00045 return tmp;
00046 }
00047
00048 public:
00049
00050 typedef value_type T;
00051 typedef boost::uniform_real<T> distribution_type;
00052 typedef boost::variate_generator<generator_type&, distribution_type > random_type;
00053
00054 distribution_type m_distribution;
00055 random_type m_random;
00056
00057 public:
00058
00059 Random()
00060 : m_distribution(details<T>::zero(),details<T>::one())
00061 , m_random(generator(), m_distribution)
00062 {}
00063
00064 Random(T lower,T upper)
00065 : m_distribution(lower,upper)
00066 , m_random(generator(), m_distribution)
00067 {}
00068
00069 private:
00070
00071 Random(Random const & rnd){}
00072 Random & operator=(Random const & rnd){return *this;}
00073
00074 public:
00075
00076 T operator()() { return m_random(); }
00077
00078 bool operator==(Random const & rnd) const { return m_distribution == rnd.m_distribution; }
00079
00080 };
00081
00082 #else
00083
00084
00085 template <typename value_type>
00086 class Random
00087 {
00088 protected:
00089
00090 typedef value_type T;
00091 typedef Random<T> self;
00092
00093 T m_lower;
00094 T m_upper;
00095
00096 protected:
00097
00098 static bool & is_initialized()
00099 {
00100 static bool initialized = false;
00101 return initialized;
00102 }
00103
00104 public:
00105
00106 Random()
00107 : m_lower(math::detail::zero<T>())
00108 , m_upper(math::detail::one<T>())
00109 {
00110 using std::time;
00111 if(!is_initialized())
00112 {
00113 std::srand(static_cast<unsigned int>(std::time(0)));
00114 is_initialized() = true;
00115 }
00116 }
00117
00118 Random(T lower,T upper)
00119 : m_lower(lower)
00120 , m_upper(upper)
00121 {
00122 self();
00123 }
00124
00125 private:
00126
00127 Random(Random const & rnd){}
00128 Random & operator=(Random const & rnd){return *this;}
00129
00130 public:
00131
00132 T operator()() const
00133 {
00134 double rnd = rand()/(1.0*RAND_MAX);
00135 return boost::numeric_cast<T>(m_lower+(m_upper-m_lower)*rnd);
00136 }
00137
00138 bool operator==(Random const & rnd) const { return (m_lower==rnd.m_lower && m_upper==rnd.m_upper); }
00139
00140 };
00141
00142 #endif
00143
00144 }
00145
00146 }
00147
00148
00149 #endif