Ondrej Certik wrote:
> On Tue, Mar 9, 2010 at 12:35 AM, Dag Sverre Seljebotn
> <[email protected]> wrote:
>   
>> Ondrej Certik wrote:
>>     
>>> On Thu, Mar 4, 2010 at 4:05 AM, Dag Sverre Seljebotn
>>> <[email protected]> wrote:
>>>
>>>       
>>>> Are anybody aware of a library for solving ODEs with fast callbacks to
>>>> Cython? The ones in SciPy require a Python callback at every step...
>>>>
>>>> My needs aren't particularily complicated.
>>>>
>>>> I'll just wrap something in C otherwise, of course (such as GSL).
>>>>
>>>>         
>>> If you do so, please post the code online. I want to see how you did
>>> the callbacks (so that it works both in python and cython), as I will
>>> need to implement the same things for our solvers. So far I just
>>> created a cdef function, that I register for the C callback. But it is
>>> not visible from Python.
>>>
>>>       
>> I'll have a look at the stuff in Sage first, then try sundials if my
>> needs aren't met there...
>>
>> As for doing the callbacks, I'd do what Sage essentially does:
>>
>> cdef class DoubleFunction:
>>    cdef double evaluate(double x):
>>        raise NotImplementedError()
>>
>> On the Python frontend side, one can trivially write a coercer object to
>> wrap Python callbacks if such are supplied. On the backend side, if you
>>     
>
>
> I understand this on the backend (C) side, that's clear. But on the
> Python side --- how would that be done? E.g. subclassing it? Would
> then
>
> cdef double call_double_func(double x, void* ctx):
>    return (<DoubleFunction>ctx).evaluate(x)
>
> evaluate my Python method? Wow, that would be super awesome, never
> thought about it (I also wanted to try cpdef instead). Let me try it.
>   

If you do

cdef class DoubleFunction:
    cpdef double evaluate(...) # NOTE cpdef

then yes, you can subclass it in Python. However there's a slight 
performance penalty for Cython code then (one if-test for NULL-ness of 
object dict) which might or might not matter.

I simply referred to

def odeint(func, ...):
    # This is O(1) so we don't care
    if not isinstance(func, DoubleFunction):
        # Not a DoubleFunction, assume it is callable
        func = CallableAsDoubleFunction(func)

where CallableAsDoubleFunction has

cdef double evaluate(self, double x)
    return self.func(x)


Dag Sverre
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to