Dag Sverre Seljebotn wrote: > 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. > Well, in practice it never matters I suppose. The main point is that I consider it unfriendly to not allow any callables from Python code, and the code below satisfies both requirements (fast => DoubleFunction in Cython without anything in-between; don't care about speed => use slower wrapper and generic callable).
Dag Sverre > 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 > _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
