00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <utils/eoRNG.h>
00022 #include <boost/python.hpp>
00023
00024 using namespace boost::python;
00025
00026 #include <sstream>
00027 #include <boost/python/detail/api_placeholder.hpp>
00028
00029 using namespace boost::python;
00030
00031
00032 const uint32_t eoRng::K(0x9908B0DFU);
00033 const int eoRng::M(397);
00034 const int eoRng::N(624);
00035
00036 namespace eo
00037 {
00038 eoRng rng(time(0));
00039 }
00040
00041 eoRng& get_rng() { return rng; }
00042 double normal(eoRng& rng) { return rng.normal(); }
00043
00044 std::string rng_to_string(const eoRng& _rng)
00045 {
00046 std::ostringstream os;
00047 _rng.printOn(os);
00048 os << std::ends;
00049 return os.str();
00050 }
00051
00052
00053 void rng_from_string(eoRng& _rng, std::string s)
00054 {
00055 std::istringstream is(s);
00056 _rng.readFrom(is);
00057 }
00058
00059 struct RNG_pickle_suite : boost::python::pickle_suite
00060 {
00061 static
00062 boost::python::tuple getstate(const eoRng& _rng)
00063 {
00064 return boost::python::make_tuple(str(rng_to_string(_rng)));
00065 }
00066 static
00067 void setstate(eoRng& _rng, boost::python::tuple pickled)
00068 {
00069 std::string state = extract<std::string>(pickled[0]);
00070 rng_from_string(_rng, state);
00071 }
00072 };
00073
00074 int spin(eoRng& _rng, numeric::array values, double total)
00075 {
00076 if (total == 0.0)
00077 {
00078 unsigned sz = len(values);
00079 for (unsigned i = 0; i < sz; ++i)
00080 {
00081 total += extract<double>(values[i]);
00082 }
00083 }
00084
00085 double chance = _rng.uniform() * total;
00086
00087 int i = 0;
00088 while (chance >= 0.0)
00089 chance -= extract<double>(values[i++]);
00090
00091 return --i;
00092 }
00093
00094 void random_numbers()
00095 {
00096 class_<eoRng, boost::noncopyable>("eoRng", init<uint32_t>())
00097 .def("flip", &eoRng::flip)
00098 .def("random", &eoRng::random)
00099 .def("rand", &eoRng::rand)
00100 .def("rand_max", &eoRng::rand_max)
00101 .def("reseed", &eoRng::reseed)
00102 .def("uniform", &eoRng::uniform)
00103 .def("normal", normal)
00104 .def("negexp", &eoRng::negexp)
00105 .def("to_string", rng_to_string)
00106 .def("from_string", rng_from_string)
00107 .def("roulette_wheel", spin)
00108 .def_pickle(RNG_pickle_suite())
00109 ;
00110
00111 def("rng", get_rng, return_value_policy<reference_existing_object>());
00112 }