The JiTCSDE module ================== **Note and remember** *that some relevant information can be found in the* `common JiTC*DE documentation`_. *This includes installation instructions, compiler issues and optimisation, general performance considerations, how to implement network dynamics and conditional statements, and a small FAQ.* Introduction ------------ JiTCSDE (just-in-time compilation for stochastic differential equations) is a standalone Python implementation of the adaptive integration method proposed by Rackauckas and Nie [RN17]_, which in turn employs Rößler-type stochastic Runge–Kutta methods [R10]_. It can handle both Itō and Stratonovich SDEs, converting the latter internally. JiTCSDE is designed in analogy to `JiTCODE`_ (which is handled very similarly to `SciPy’s ODE`_ (`scipy.integrate.ode`)): It takes iterables (or generator functions or dictionaries) of symbolic expressions, translates them to C code, compiles them and an integrator wrapped around them on the fly, and allows you to operate this integrator from Python. Symbolic expressions are mostly handled by `SymEngine`_, `SymPy`_’s compiled-backend-to-be (see `SymPy vs. SymEngine`_ for details). This approach has the following advantages: * **Speed boost through compilation** Evaluating the derivative and the core operations of the Runge–Kutta integration happen in compiled C code and thus very efficiently. * **Speed boost through symbolic optimisation** If your derivative is automatically generated by some routine, you can simplify it symbolically to boost the speed. In fact, blatant optimisations such as :math:`y·(x-x)=0` are done on the fly by SymEngine. This is for example interesting if you want to simulate dynamics on a sparse network, as non-existing links are not taken into account when calculating the derivative when integrating. * **Symbolic interface** You can enter your differential equations almost like you would on paper. Also, if you are working with SymPy or SymEngine anyway – e.g., to calculate points of zero drift –, you do not need to bother much with translating your equations. If compilation fails to work for whatever reason, pure Python functions can be employed as a fallback (which is much slower, however). A brief mathematic background ----------------------------- This documentation assumes that the stochastic differential equation (SDE) you want to solve is: .. math:: \mathrm{d} y = f(t,y) \mathrm{d} t + g(t,y) ⊙ \mathrm{d} W(t) where :math:`y`, :math:`f`, :math:`g` and :math:`\mathrm{d} W(t)` are vectors or vector-valued, respectively, with the same dimension and :math:`⊙` indicates the component-wise product between vectors. Rackauckas’ and Nie’s method [RN17]_ basically works like an adaptive Runge–Kutta integrator for ordinary differential equations (ODEs): It employs two stochastic Runge–Kutta integrators and uses the difference between them to estimate the error of the integration. These methods are intertwined to minimise the additional computational effort required to estimate the error. The step size is adapted to keep the estimated error below a user-determined threshold. To avoid a bias through rejected steps, the respective noise is stored and reused employing a Brownian bridge. If the noise is additive, i.e., if `g` does not depend on `y`, a more simple algorithm is used. .. _example: A simple example ---------------- .. automodule:: noisy_lorenz Jumps ----- If you wish to have jumps on top of the Brownian noise (and thus obtain a jump–diffusion process), you can do this using the extension `jitcsde_jump`. It draws the waiting time between jumps as well as the value of the jump from a distribution that you specify. The jumps are positioned precisely, i.e., the dynamics is integrated up to the time of a jump, the jump is applied, and the integration is continued afterwards. Note that this functionality is implemented purely in Python, which makes it very flexible, but may also slows things down when the jump rate is high in comparison to the integration step (not to be confused with the sampling step), which however should not occur in typical applications. Also note that this only works for Itō SDEs. .. automodule:: noisy_and_jumpy_lorenz Networks and large equations ---------------------------- JiTCSDE is specifically designed to be able to handle large stochastic differential equations, as they arise, e.g., in networks. The caveats, tools, and tricks when doing this are the same as for JiTCODE; so please refer to its documentation, in particular the sections: * `Handling very large differential equations `_ * `A more complicated example `_ Command reference ----------------- .. automodule:: _jitcsde :members: :exclude-members: jitcsde, jitcsde_jump The main class ^^^^^^^^^^^^^^ .. autoclass:: jitcsde :members: :inherited-members: Jumps ^^^^^ .. autoclass:: jitcsde_jump :members: .. _reference: References ---------- .. _common JiTC*DE documentation: https://jitcde-common.readthedocs.io .. [RN17] C. Rackauckas, Q. Nie: Adaptive methods for stochastic differential equations via natural embeddings and rejection sampling with memory, Discrete Cont. Dyn.-B 22, pp. 2731–2761 (2017), `10.3934/dcdsb.2017133 `_. .. [R10] A. Rößler, Runge–Kutta methods for the strong approximation of solutions of stochastic differential equations, SIAM J. Numer. Anal. 48, pp. 922–952 (2010) `10.1137/09076636X `_. .. _JiTCODE: http://github.com/neurophysik/jitcode .. _JiTCODE documentation: http://jitcode.readthedocs.io .. _SciPy’s ODE: http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html .. _SymPy Issue 8997: https://github.com/sympy/sympy/issues/8997 .. _SymPy vs. SymEngine: https://jitcde-common.readthedocs.io/#sympy-vs-symengine .. _SymEngine: https://github.com/symengine/symengine .. _SymPy: http://www.sympy.org/