# random_numbers.cpp

    00001 /*
    00002     PyEO
    00003
    00004     Copyright (C) 2003 Maarten Keijzer
    00005
    00006     This program is free software; you can redistribute it and/or modify
    00007     it under the terms of the GNU General Public License as published by
    00008     the Free Software Foundation; either version 2 of the License, or
    00009     (at your option) any later version.
    00010
    00011     This program is distributed in the hope that it will be useful,
    00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014     GNU General Public License for more details.
    00015
    00016     You should have received a copy of the GNU General Public License
    00017     along with this program; if not, write to the Free Software
    00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    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 namespace eo
    00032 {
    00033     eoRng rng(time(0));
    00034 }
    00035
    00036 eoRng& get_rng() { return rng; }
    00037 double normal(eoRng& rng) { return rng.normal(); }
    00038
    00039 std::string rng_to_string(const eoRng& _rng)
    00040 {
    00041     std::ostringstream os;
    00042     _rng.printOn(os);
    00043     os << std::ends;
    00044     return os.str();
    00045 }
    00046
    00047
    00048 void rng_from_string(eoRng& _rng, std::string s)
    00049 {
    00050     std::istringstream is(s);
    00051     _rng.readFrom(is);
    00052 }
    00053
    00054 struct RNG_pickle_suite : boost::python::pickle_suite
    00055 {
    00056     static
    00057     boost::python::tuple getstate(const eoRng& _rng)
    00058     {
    00059         return boost::python::make_tuple(str(rng_to_string(_rng)));
    00060     }
    00061     static
    00062     void setstate(eoRng& _rng, boost::python::tuple pickled)
    00063     {
    00064         std::string state = extract<std::string>(pickled[0]);
    00065         rng_from_string(_rng, state);
    00066     }
    00067 };
    00068
    00069 int spin(eoRng& _rng, numeric::array values, double total)
    00070 {
    00071    if (total == 0.0)
    00072    {
    00073         unsigned sz = len(values);
    00074         for (unsigned i = 0; i < sz; ++i)
    00075         {
    00076             total += extract<double>(values[i]); //extract?
    00077         }
    00078    }
    00079
    00080    double chance = _rng.uniform() * total;
    00081
    00082    int i = 0;
    00083    while (chance >= 0.0)
    00084        chance -= extract<double>(values[i++]);
    00085
    00086    return --i;
    00087 }
    00088
    00089 void random_numbers()
    00090 {
    00091     class_<eoRng, boost::noncopyable>("eoRng", init<uint32_t>())
    00092         .def("flip", &eoRng::flip)
    00093         .def("random", &eoRng::random)
    00094         .def("rand", &eoRng::rand)
    00095         .def("rand_max", &eoRng::rand_max)
    00096         .def("reseed", &eoRng::reseed)
    00097         .def("uniform", &eoRng::uniform)
    00098         .def("normal", normal)
    00099         .def("negexp", &eoRng::negexp)
    00100         .def("to_string", rng_to_string)
    00101         .def("from_string", rng_from_string)
    00102         .def("roulette_wheel", spin)
    00103         .def_pickle(RNG_pickle_suite())
    00104         ;
    00105
    00106     def("rng", get_rng, return_value_policy<reference_existing_object>());
    00107 }