Skip to content
Snippets Groups Projects
Commit e50483e7 authored by André Anjos's avatar André Anjos :speech_balloon:
Browse files

Supports older boost distributions

parent d4276cc8
Branches
Tags
No related merge requests found
...@@ -12,7 +12,7 @@ package_dir = os.path.dirname(os.path.realpath(__file__)) ...@@ -12,7 +12,7 @@ package_dir = os.path.dirname(os.path.realpath(__file__))
package_dir = os.path.join(package_dir, 'xbob', 'core', 'include') package_dir = os.path.join(package_dir, 'xbob', 'core', 'include')
include_dirs = [package_dir] include_dirs = [package_dir]
packages = ['bob-core >= 1.2.2', 'boost >= 1.47'] packages = ['bob-core >= 1.2.2', 'boost']
version = '2.0.0a0' version = '2.0.0a0'
setup( setup(
......
...@@ -10,7 +10,11 @@ ...@@ -10,7 +10,11 @@
#include <xbob.blitz/cppapi.h> #include <xbob.blitz/cppapi.h>
#include <xbob.blitz/cleanup.h> #include <xbob.blitz/cleanup.h>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION >= 104700
#include <boost/random/discrete_distribution.hpp> #include <boost/random/discrete_distribution.hpp>
#endif
PyDoc_STRVAR(s_discrete_str, XBOB_EXT_MODULE_PREFIX ".discrete"); PyDoc_STRVAR(s_discrete_str, XBOB_EXT_MODULE_PREFIX ".discrete");
...@@ -49,7 +53,13 @@ boost::shared_ptr<void> make_discrete(PyObject* probabilities) { ...@@ -49,7 +53,13 @@ boost::shared_ptr<void> make_discrete(PyObject* probabilities) {
cxx_probabilities.push_back(v); cxx_probabilities.push_back(v);
} }
#if BOOST_VERSION >= 104700
return boost::make_shared<boost::random::discrete_distribution<T,double>>(cxx_probabilities); return boost::make_shared<boost::random::discrete_distribution<T,double>>(cxx_probabilities);
#else
PyErr_SetString(PyExc_NotImplementedError, "discrete distribution requires boost >= 1.47");
return boost::shared_ptr<void>();
#endif
} }
PyObject* PyBoostDiscrete_SimpleNew (int type_num, PyObject* probabilities) { PyObject* PyBoostDiscrete_SimpleNew (int type_num, PyObject* probabilities) {
...@@ -164,6 +174,7 @@ int PyBoostDiscrete_Converter(PyObject* o, PyBoostDiscreteObject** a) { ...@@ -164,6 +174,7 @@ int PyBoostDiscrete_Converter(PyObject* o, PyBoostDiscreteObject** a) {
template <typename T> template <typename T>
PyObject* get_probabilities(PyBoostDiscreteObject* self) { PyObject* get_probabilities(PyBoostDiscreteObject* self) {
#if BOOST_VERSION >= 104700
std::vector<double> w = boost::static_pointer_cast<boost::random::discrete_distribution<T,double>>(self->distro)->probabilities(); std::vector<double> w = boost::static_pointer_cast<boost::random::discrete_distribution<T,double>>(self->distro)->probabilities();
PyObject* retval = PyTuple_New(w.size()); PyObject* retval = PyTuple_New(w.size());
if (!retval) return 0; if (!retval) return 0;
...@@ -171,6 +182,10 @@ PyObject* get_probabilities(PyBoostDiscreteObject* self) { ...@@ -171,6 +182,10 @@ PyObject* get_probabilities(PyBoostDiscreteObject* self) {
PyTuple_SET_ITEM(retval, k, Py_BuildValue("d", w[k])); PyTuple_SET_ITEM(retval, k, Py_BuildValue("d", w[k]));
} }
return retval; return retval;
#else
PyErr_SetString(PyExc_NotImplementedError, "discrete distribution requires boost >= 1.47");
return 0;
#endif
} }
/** /**
...@@ -208,8 +223,13 @@ static PyObject* PyBoostDiscrete_GetDtype(PyBoostDiscreteObject* self) { ...@@ -208,8 +223,13 @@ static PyObject* PyBoostDiscrete_GetDtype(PyBoostDiscreteObject* self) {
} }
template <typename T> PyObject* reset(PyBoostDiscreteObject* self) { template <typename T> PyObject* reset(PyBoostDiscreteObject* self) {
#if BOOST_VERSION >= 104700
boost::static_pointer_cast<boost::random::discrete_distribution<T,double>>(self->distro)->reset(); boost::static_pointer_cast<boost::random::discrete_distribution<T,double>>(self->distro)->reset();
Py_RETURN_NONE; Py_RETURN_NONE;
#else
PyErr_SetString(PyExc_NotImplementedError, "discrete distribution requires boost >= 1.47");
return 0;
#endif
} }
/** /**
...@@ -229,7 +249,12 @@ static PyObject* PyBoostDiscrete_Reset(PyBoostDiscreteObject* self) { ...@@ -229,7 +249,12 @@ static PyObject* PyBoostDiscrete_Reset(PyBoostDiscreteObject* self) {
} }
template <typename T> PyObject* call(PyBoostDiscreteObject* self, PyBoostMt19937Object* rng) { template <typename T> PyObject* call(PyBoostDiscreteObject* self, PyBoostMt19937Object* rng) {
#if BOOST_VERSION >= 104700
return PyBlitzArrayCxx_FromCScalar(boost::static_pointer_cast<boost::random::discrete_distribution<T,double>>(self->distro)->operator()(*rng->rng)); return PyBlitzArrayCxx_FromCScalar(boost::static_pointer_cast<boost::random::discrete_distribution<T,double>>(self->distro)->operator()(*rng->rng));
#else
PyErr_SetString(PyExc_NotImplementedError, "discrete distribution requires boost >= 1.47");
return 0;
#endif
} }
/** /**
......
...@@ -139,12 +139,16 @@ def test_binomial(): ...@@ -139,12 +139,16 @@ def test_binomial():
def test_discrete(): def test_discrete():
probs = (0.5, 0.2, 0.3) # mean == 0*0.5 + 1*0.2 + 2*0.3 = 0.8 probs = (0.5, 0.2, 0.3) # mean == 0*0.5 + 1*0.2 + 2*0.3 = 0.8
d = random.discrete(int, probs)
assert numpy.allclose(probs, d.probabilities)
x = random.variate_generator(random.mt19937(), d) try:
m = x(10000) d = random.discrete(int, probs)
assert abs(m.mean() - 0.8) < 0.1 assert numpy.allclose(probs, d.probabilities)
x = random.variate_generator(random.mt19937(), d)
m = x(10000)
assert abs(m.mean() - 0.8) < 0.1
except NotImplementedError:
pass
def test_repr(): def test_repr():
...@@ -158,5 +162,11 @@ def test_repr(): ...@@ -158,5 +162,11 @@ def test_repr():
repr(x) repr(x)
x = random.binomial(float) x = random.binomial(float)
repr(x) repr(x)
x = random.discrete(int, (0.1, 0.9))
repr(x) def test_repr_discrete():
try:
x = random.discrete(int, (0.1, 0.9))
repr(x)
except NotImplementedError:
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment