Hi,
sorry, but your code below is a complete mess. I'll just add comments as
far as I can decypher it.
Zahra Sheikh schrieb am 29.09.2017 um 14:17:
> If you do not mind I recap again because it is getting really confusing for
> me to sum up with a solution and I guess it is not clear what I am trying
> to do:
>
> I want to write a python wrapper function for a C-type function which gets
> a pointer function as its argument. I have different log-probability
> distributions that I would like to pass as argument to both this python
> wrapper and consequently to the C-type function that is embedded in the
> python wrapper.
> My problems are:
> 1) how to pass different functions as argument to a python wrapper while
> they can also be callable from a python script?
Create a Python wrapper object for them that you can pass through Python
code, pack and unpack that object at need, and call the C functions from
its pointer in Cython.
> for instance the following function:
>
> *cdef class _SampleFunc: cdef void (*func)(double *, double *, double
> *) *
>
>
>
>
>
>
> *def normal(double* u, double* yu,
> double* ypu): yu[0] =
> -u[0]*u[0]*0.5
> ypu[0]= -u[0] return*
That should be a cdef function. It takes pointers as arguments and is
therefore not callable from Python.
> 2) how can I make the above function (for instance normal function) be
> callable from my python script.
It cannot be called from Python because Python does not know pointers. You
can implement a separate def-function for it that accepts Python object
arguments, converts them in some way, and then passes them into the C function.
> I\d like to pass it as an argument to the
> python wrapper, it becomes unwrapped and then this function (e.g. normal
> function) gets passed as argument to a function inside the python wrapper
> (which is a c-type function e.g. sample function)?
Yes, that's the approach.
> * def py_ars(int ns, int m, double emax, np.ndarray[ndim=1,
> dtype=np.float64_t] x, np.ndarray[ndim=1, dtype=np.float64_t]
> hx, np.ndarray[ndim=1, dtype=np.float64_t] hpx, int
> num, _SampleFunc f *#Different functions can pass as argument here
> * ):*
>
>
>
>
>
>
> * cdef np.ndarray[ndim=1, dtype=np.float64_t] sp cdef double beta = 0.
> cdef int i for i from 0 <= i <num:*
>
> *sample( * #a c-type function which three pointer arrays, a
> pointer function and a double pointer pass as its arguments
> * &x[0]),* # passing array by reference
> * &hx[0],* # passing array by reference
> *&hpx[0],*# passing array by reference
> *&f,*
This is wrong. It gives you the pointer to the Python "_SampleFunc" object,
which is useless. Instead, unpack the C function (f.func) and pass that.
You should also declare the argument in the "py_ars" signature as
"_SampleFunc f not None", because Cython will otherwise allow users to pass
None.
> * &beta*, # passing double variable by reference
> *)*
>
> *sp[i] = beta*
>
> *return sp*
Stefan