30 Jul 19:02 2015
cython fails to recognize overloaded constructor
Lee Zamparo <zamparo <at> gmail.com>
20150730 17:02:09 GMT
20150730 17:02:09 GMT
Hi everyone,
And here's the random.pyx file which defines the cppclass:
 I'm new to cython, and was trying to compile a wrapper around a boostbased random number generator (see here). My full problem description complete with gist is crossposted to stackoverflow, so I'll only summarize it here:
 I'm using python 2.7.10 (Anaconda 2.0.1) and cython 0.22.1.
 random.pyx exposes an interface defined in rng_wrapper.hpp

A test in example.pyx file compiles and runs fine
 A very similar test in example_seed.pyx does not compile
The error reported has to do with an overloaded constructor:
Error compiling Cython file:

...
cdef int N = n
cdef unsigned long Seed = seed
cdef rng_sampler[double] * rng_p = new rng_sampler[double](Seed)

example/example_seed.pyx:15:67 Cannot assign type 'unsigned long' to 'mt19937'
Here is an abridged definition of the rng_sampler class (see the gist for the rest):
#include <ctime>
#include "boost/random/mersenne_twister.hpp"
#include "boost/random/normal_distribution.hpp"
#include "boost/random/gamma_distribution.hpp"
#include "boost/random/exponential_distribution.hpp"
#include "boost/random/uniform_real_distribution.hpp"
#include "boost/random/chi_squared_distribution.hpp"
using namespace boost::random;template<typename float_t=double>
class rng_sampler {
public:
typedef float_t result_type;
rng_sampler(mt19937 &in_R) : R(in_R) {} // < the copy constructor
rng_sampler() { // < the default constructor
R = mt19937();
R.seed(std::clock());
}
rng_sampler(unsigned long seed) { // < the constructor which takes an unsigned long
R = mt19937();
R.seed(seed);
}
// sampling methods here
private:
mt19937 R;
};
#include "boost/random/mersenne_twister.hpp"
#include "boost/random/normal_distribution.hpp"
#include "boost/random/gamma_distribution.hpp"
#include "boost/random/exponential_distribution.hpp"
#include "boost/random/uniform_real_distribution.hpp"
#include "boost/random/chi_squared_distribution.hpp"
using namespace boost::random;template<typename float_t=double>
class rng_sampler {
public:
typedef float_t result_type;
rng_sampler(mt19937 &in_R) : R(in_R) {} // < the copy constructor
rng_sampler() { // < the default constructor
R = mt19937();
R.seed(std::clock());
}
rng_sampler(unsigned long seed) { // < the constructor which takes an unsigned long
R = mt19937();
R.seed(seed);
}
// sampling methods here
private:
mt19937 R;
};
import numpy as np
cimport numpy as np
cimport cython
from cython.operator cimport dereference as deref
from libcpp cimport bool
cdef extern from "boost/random/mersenne_twister.hpp" namespace "boost::random" nogil:
# random number generator
cdef cppclass mt19937:
#init
mt19937() nogil
#attributes
#methods
seed(unsigned long)
cdef extern from "rng_wrapper.hpp" nogil:
# wrapper to distributions ...
cdef cppclass rng_sampler[result_type]:
#init
rng_sampler(mt19937) nogil
rng_sampler(unsigned long) nogil
rng_sampler() nogil
# methods (gamma and exp are using rate param)
result_type normal(result_type, result_type) nogil
result_type gamma(result_type, result_type) nogil
result_type uniform(result_type, result_type) nogil
result_type exp(result_type) nogil
result_type chisq(result_type) nogil
ctypedef mt19937 rng
cimport numpy as np
cimport cython
from cython.operator cimport dereference as deref
from libcpp cimport bool
cdef extern from "boost/random/mersenne_twister.hpp" namespace "boost::random" nogil:
# random number generator
cdef cppclass mt19937:
#init
mt19937() nogil
#attributes
#methods
seed(unsigned long)
cdef extern from "rng_wrapper.hpp" nogil:
# wrapper to distributions ...
cdef cppclass rng_sampler[result_type]:
#init
rng_sampler(mt19937) nogil
rng_sampler(unsigned long) nogil
rng_sampler() nogil
# methods (gamma and exp are using rate param)
result_type normal(result_type, result_type) nogil
result_type gamma(result_type, result_type) nogil
result_type uniform(result_type, result_type) nogil
result_type exp(result_type) nogil
result_type chisq(result_type) nogil
ctypedef mt19937 rng
As I read it, the code tries to call the overloaded constructor using an unsigned long:
rng_sampler(unsigned long seed) {
R = mt19937();
R.seed(seed);
}
R = mt19937();
R.seed(seed);
}
Yet the compiler does not recognize this, and instead fails to call the copy constructor:
rng_sampler(mt19937 &in_R) : R(in_R) {}
Can anyone help me understand why this is the case? And better yet how to properly declare the unsigned long constructor so that cython recognizes it?

You received this message because you are subscribed to the Google Groups "cythonusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cythonusers+unsubscribe <at> googlegroups.com.
For more options, visit https://groups.google.com/d/optout.