Code Monkey home page Code Monkey logo

sdeint's Introduction

sdeint

Numerical integration of Ito or Stratonovich SDEs.

Overview

sdeint is a collection of numerical algorithms for integrating Ito and Stratonovich stochastic ordinary differential equations (SODEs). It has simple functions that can be used in a similar way to scipy.integrate.odeint() or MATLAB's ode45.

There already exist some python and MATLAB packages providing Euler-Maruyama and Milstein algorithms, and a couple of others. So why am I bothering to make another package?

It is because there has been 25 years of further research with better methods but for some reason I can't find any open source reference implementations. Not even for those methods published by Kloeden and Platen way back in 1992. So I will aim to gradually add some improved methods here.

This is prototype code in python, so not aiming for speed. Later can always rewrite these with loops in C when speed is needed.

Warning: this is an early pre-release. Wait for version 1.0. Bug reports are very welcome!

functions

itoint(f, G, y0, tspan) for Ito equation dy = f(y,t)dt + G(y,t)dW
stratint(f, G, y0, tspan) for Stratonovich equation dy = f(y,t)dt + G(y,t)∘dW

These work with scalar or vector equations. They will choose an algorithm for you. Or you can use a specific algorithm directly:

specific algorithms:

itoEuler(f, G, y0, tspan): the Euler-Maruyama algorithm for Ito equations.
stratHeun(f, G, y0, tspan): the Stratonovich Heun algorithm for Stratonovich equations.
itoSRI2(f, G, y0, tspan): the Rößler2010 order 1.0 strong Stochastic Runge-Kutta algorithm SRI2 for Ito equations.
itoSRI2(f, [g1,...,gm], y0, tspan): as above, with G matrix given as a separate function for each column (gives speedup for large m or complicated G).
stratSRS2(f, G, y0, tspan): the Rößler2010 order 1.0 strong Stochastic Runge-Kutta algorithm SRS2 for Stratonovich equations.
stratSRS2(f, [g1,...,gm], y0, tspan): as above, with G matrix given as a separate function for each column (gives speedup for large m or complicated G).
stratKP2iS(f, G, y0, tspan): the Kloeden and Platen two-step implicit order 1.0 strong algorithm for Stratonovich equations.

For more information and advanced options for controlling random value generation and repeated integrals see the documentation for each function.

utility functions:

deltaW(N, m, h, generator=None): Generate increments of m independent Wiener processes for each of N time intervals of length h. Optionally provide a numpy.random.Generator instance to use.
Repeated integrals by the method of Kloeden, Platen and Wright (1992):
Ikpw(dW, h, n=5, generator=None): Approximate repeated Ito integrals.
Jkpw(dW, h, n=5, generator=None): Approximate repeated Stratonovich integrals.
Repeated integrals by the method of Wiktorsson (2001):
Iwik(dW, h, n=5, generator=None): Approximate repeated Ito integrals.
Jwik(dW, h, n=5, generator=None): Approximate repeated Stratonovich integrals.

Examples:

Integrate the one-dimensional Ito equation   dx = -(a + x*b**2)*(1 - x**2)dt + b*(1 - x**2)dW
with initial condition x0 = 0.1
import numpy as np
import sdeint

a = 1.0
b = 0.8
tspan = np.linspace(0.0, 5.0, 5001)
x0 = 0.1

def f(x, t):
    return -(a + x*b**2)*(1 - x**2)

def g(x, t):
    return b*(1 - x**2)

result = sdeint.itoint(f, g, x0, tspan)
Integrate the two-dimensional vector Ito equation   dx = A.x dt + B.dW
where x = (x1, x2),   dW = (dW1, dW2) and with initial condition x0 = (3.0, 3.0)
import numpy as np
import sdeint

A = np.array([[-0.5, -2.0],
              [ 2.0, -1.0]])

B = np.diag([0.5, 0.5]) # diagonal, so independent driving Wiener processes

tspan = np.linspace(0.0, 10.0, 10001)
x0 = np.array([3.0, 3.0])

def f(x, t):
    return A.dot(x)

def G(x, t):
    return B

result = sdeint.itoint(f, G, x0, tspan)

References for these algorithms:

itoEuler:
G. Maruyama (1955) Continuous Markov processes and stochastic equations
stratHeun:
W. Rumelin (1982) Numerical Treatment of Stochastic Differential Equations
R. Mannella (2002) Integration of Stochastic Differential Equations on a Computer
K. Burrage, P. M. Burrage and T. Tian (2004) Numerical methods for strong solutions of stochastic differential equations: an overview
itoSRI2, stratSRS2:
A. Rößler (2010) Runge-Kutta Methods for the Strong Approximation of Solutions of Stochastic Differential Equations
stratKP2iS:
P. Kloeden and E. Platen (1999) Numerical Solution of Stochastic Differential Equations, revised and updated 3rd printing
Ikpw, Jkpw:
P. Kloeden, E. Platen and I. Wright (1992) The approximation of multiple stochastic integrals
Iwik, Jwik:
M. Wiktorsson (2001) Joint Characteristic Function and Simultaneous Simulation of Iterated Ito Integrals for Multiple Independent Brownian Motions

TODO

  • Fast, parallel GPU implementation in C++, wrapped with this python interface.
  • Rewrite Iwik() and Jwik() so they don't waste so much memory.
  • Fix stratKP2iS(). In the unit tests it is currently less accurate than itoEuler() and this is likely due to a bug.
  • Implement the Ito version of the Kloeden and Platen two-step implicit alogrithm.
  • Add more strong stochastic Runge-Kutta algorithms. Perhaps starting with Burrage and Burrage (1996)
  • Currently prioritizing those algorithms that work for very general d-dimensional systems with arbitrary noise coefficient matrix, and which are derivative free. Eventually will add special case algorithms that give a speed increase for systems with certain symmetries. That is, 1-dimensional systems, systems with scalar noise, diagonal noise or commutative noise, etc. The idea is that itoint() and stratint() will detect these situations and dispatch to the most suitable algorithm.
  • Some time in the dim future, implement support for stochastic delay differential equations (SDDEs).

See also:

nsim: Framework that uses this sdeint library to enable massive parallel simulations of SDE systems (using multiple CPUs or a cluster) and provides some tools to analyze the resulting timeseries. https://github.com/mattja/nsim For parallel simulation this will be obsoleted by the GPU implementation in development.

sdeint's People

Contributors

mattja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sdeint's Issues

Random seed for reproducibility

It is possible to have random seed input as an argument
(e.g. itoEuler(f, G, y0, tspan, random_state=1)) for reproducibility purpose?

Thanks

bibtex & integration order

Hi guys, i'm citing you, and I believe you need to add a citation format to the .md file
I got this far...

  @software{sdeint,
    author = {Matthew Aburn and Yoav Ram},
    url = {https://github.com/mattja/sdeint},
  }

thanks a lot for implementing all this!
BTW, we noticed that the algorithm for stochastic Ito integration you have is order 1.0, however Rossler paper is titled "second order RK...", and mathematica has a routine that implements order 3/2 (in dt). Is this correct ? Maybe i'm misleading what second order means here (probabily \sqrt{dt}^2), but are you planning to implement higher order algorithms?
thanks again

automatically check the function input

Hi,

thanks for the cool package. However, there seems to be a small issue with the return value of the input function

if I return lists in function f and function G, the integrator seems to be confused and then allocate a huge amount of memory. After manually converting my return values into numpy.array, the problem is solved. It took me an hour to figure this out.

Therefore, it would be easier if the integrator automatically checks the return values of the input function, to avoid confusing the reader.

Thanks!

Different noise realizations

Hi! Great library.

I wonder how can I get repeated simulations with differente noise realizations

I was tring this:

import numpy as np
import sdeint

M = 10

b = 1.0
tau = 0.8
tspan = np.linspace(0.0, 5.0, 5001)
x0 = 0.1*ones(M)

def f(x, t):
    return -x/tau

def g(x, t):
    return b*np.ones(x.shape)

result = sdeint.itoSRI2(f, [g]*M, x0, tspan)

But the outputs are all the same.

Thanks in advance.

A question: Mechanical system with white noise external forces

I have a mechanical system described as d/dt (q) = f(q, t, F), where
q …generalized coordinates,
F…external forces to be modeled as white noise
(Where I used sympy.physics.mechanics to generate these equations of motion)

What I did in order to apply SDEINT, I linearized about the forces F:
B = f(q, t, F).diff(F).subs({F: 0.})
F1 = f(q, t, F).subs({F: 0})

Then I calculated as
Result = itoint(F1, B, x0, tspan)

Is this the right approach, or what would be the correct one?

Thanks for any help!

Noise coefficient

I hope it's not a too stupid question since I have no background in SDEs in general but I need to use the package to generate sample paths for our machine learning project.

From my understanding, suppose I have a set of SDEs with d states, if I assume independent additive constant diffusion noise, then the G function should return a dxd diagonal matrix right? Should the entries of the matrix contain the "variance or std" of the noise? I am not even sure if the terms variance and std are proper here.

Thanks a lot for helping.

Allow the state y to be an array of arbitrary rank

Although scipy.integrate.odeint does not support that sort of thing.
But hey, why not?

This would then be an improved fix for mattja/nsim#2 , since it's reasonable for people to
supply a state of shape (n,1) interpreted as a column vector and expect it to work.

Implement with numpy.ravel on input and numpy.reshape on output but make sure data is not copied during reshape.

Boundary conditions

Nice project. I cannot see boundary conditions implemented (please correct me if I am wrong) which would make a easy and very powerful enhancement!

Problem with 2D ITO integration

I tried your 1D example given in the introduction, and it seemed to work fine.
Then I tried the 2D example, and it did not seem to work:
No matter what I entered, the graphs of both solutions dropped from the starting point straight to zero and remained there.

where is my mistake?
Thanks for any help!

BUG: initial conditions' type are not interpreted correctly

There's a bug that I suppose stems from the type interpretation of initial conditions. The following code which simulates a simple damped harmonic oscillator (with no noise at all) illustrates the error:

import numpy as np
import matplotlib.pyplot as plt
import sdeint


w0 = np.pi  # arbitrary
beta = 0.5  # arbitrary
tspan = np.linspace(0.0, 5.0, 5001)

x0 = 1, 1    # types interpreted as int (wrong solution) 
x1 = 1, 1.   # types interpreted as int (wrong solution)
x2 = 1., 1   # types interpreted as float (correct solution)

def f(x, t):
    return np.array([x[1], -w0*x[0]-beta*x[1]])

def g(x, t):
    return np.diag([0, 0])

result0 = sdeint.itoint(f, g, x0, tspan)
result1 = sdeint.itoint(f, g, x1, tspan)
result2 = sdeint.itoint(f, g, x2, tspan)

# vis the results
for i in range(3):
    l = plt.plot(tspan, eval('result'+str(i))[:,0], label=str(I), linewidth=5-2*i)
    plt.plot(tspan, eval('result'+str(i))[:,1], '--', color=l[0].get_color(), linewidth=5-2*i)
plt.legend()
plt.show()

Might be related to #15 and #16.

Citation

I'd like to use sdeint to generate a couple of figures. :)

How should I cite sdeint for that?

Delay equations.

I'd like to brighten the possibility of integrating stochastic delay ODEs, if possible.

Can the approach used in, https://github.com/Zulko/ddeint/blob/master/ddeint/ddeint.py, be adapted for sdeint? I'm quite happy to write the code, if there's interest. Wanted to see if that looks like a viable approach. My understanding of numerical methods for stochastic ODEs is not good enough to be sure this is a sane route.

High Dimensional Solver

Hi,
I've been using this package for my master's thesis. I ran into problems with high-dimensional systems, where an unreasonable amount of memory was required. I rewrote the main loop for the itoint solver to generate the Brownian increments to be generated on the fly. This may be slightly lower but allowed me to handle much larger systems.
I would like to share this with you since this package helped me a lot.
I could either incorporate this into the current solver or write an additional option for larger systems. Please let me know your preferences.

Extract noise?

I am using sdeint as it is shown in the 2nd example. So multi-dimensional independent driving Wiener processes. Is it possible to save the noise for every dimension/timestep?

Expectation and Variance

I love to play around (that is all I am doing, I am semi retired) with SDEINT.
It gives possible realizations of the stochastic system. ( I usually use sympy.physics.mechanics to get equations of motion for some mechanical system, and then ‚exite it‘ with white noise forces).

It would be nice, if in addition, one could get the expectation and the variance of the solution.
Something like:

R, E, V = itoint(f, G, times, all=True) giving everything
R = itoint(f, G, times, all=False) giving only a realisation

Just a thought.

Codec error when installing

 pip install sdeint
Collecting sdeint
  Downloading sdeint-0.2.0.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\yoavram\AppData\Local\Temp\pip-build-ptlgr1og\sdeint\setup.py", line 48, in <module>
        long_description=read('README.rst'),
      File "C:\Users\yoavram\AppData\Local\Temp\pip-build-ptlgr1og\sdeint\setup.py", line 11, in read
        return codecs.open(os.path.join(here, *parts), 'r').read()
      File "D:\Anaconda3\lib\encodings\cp1255.py", line 23, in decode
        return codecs.charmap_decode(input,self.errors,decoding_table)[0]
    UnicodeDecodeError: 'charmap' codec can't decode byte 0x9f in position 1592: character maps to <undefined>

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\yoavram\AppData\Local\Temp\pip-build-ptlgr1og\sdeint

Same thing happens when installing directly from the code downloaded from github.

Python 3.4, Windows 7 64-bit.

Two-dimensional problem

Hello, big man. I want to ask a question. I have made a two-dimensional project according to your method. I always can't get the result I want. Can you explain a two-dimensional example?

Implementation of first passage times

First of all, thanks a lot for the package, it's very useful!

I was wondering whether the following application could be a relevant addition for sdeint:
In several fields, including neuroscience and decision making, it's often of interest to calculate the first passage time of (simple) stochastic processes reaching a certain bound or bounds (usually constant for simplicity although it doesn't need to be). You might have heard about the DDM model and variants.

Your functions such as itoSRI2() are very useful to calculate the trajectories of this process, but one still needs to evaluate when the trajectories reach the bound for the first time. To do this, most commonly one integrates trajectories until a fixed maximum (long) time Tmax, and then finds when the trajectories reach the bound. This is not very efficient, as many trajectories will reach the bound much earlier than Tmax. The other alternative is to evaluate the bound crossing at every time step of the trajectory, but since this is outside of the itoSRI2() function, it's also probably not efficient (multiple calls to the function with subsequent overhead, etc.)

I was wondering if it would be worthwhile to implement a method in which you pass already the bound function(s), and it returns directly the first passage time, and which bound was reached first (in case of multiple), all from within the itoSRI2() akin method. I think it would be valuable for a lot of researchers that currently are using the first technique described above, or implementing their own (and likely inefficient) Euler-Maruyama simulations.

Allow passing a numpy Generator for random numbers

Hello,

This is a follow up on #14 given numpy's latest recommendation regarding random number generation, which can be found here.

In short, using np.random.XXX is now legacy, and the recommended usage is:

rng = np.random.default_rng(seed=0)
rng.normal()

And instead of setting the global seed, one should pass the Generator instance to the place where it is needed.
AFAIK, sdeint does not allow passing a Generator instance.

It would be nice to incorporate this feature for compatibility with newer code, e.g., with sdeint using a global Generator instance that could be set by the user.

Thanks

is it possible to integrate jump process?

Hi, thanks for your really great library! it really saves my day.

I'm not expert in maths, but am currently interested in simulating sde include a poisson process. is it possible or would you incorporate a poisson process dNt into your library in the future? it could be great if you can suggest some ways to implement it. Thanks for your help in advance!

Only a question out of curiosity

I am playing around with sdeint.itoint a lot - and enjoy it!
It seems to me that when I integrate a given interval, say, (0, 10), the more 'steps' I give the more 'accurate' it gets - and the longer it calculates.
With scipy.odeint this does not seem to be the case.
Of course, only my observation, I do not really know how either program works internally.

Is my observation correct, or am I doing something wrong?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.