neurophysik / jitcdde

Just-in-time compilation for delay differential equations
Other
56 stars 14 forks source link

euler maruyama scheme for stochastic delay differential equation #37

Closed Ziaeemehr closed 12 months ago

Ziaeemehr commented 3 years ago

Hi, As I know there is only Runke kutta 23 method available for DDE. Is it possible for you to add also Euler maruyama or if you don't have time give some guide how to add it?

best, Abolfazl

Wrzlprmft commented 3 years ago

Adding a new integrator to JiTCDDE is far from easy, because the existing integrator is strongly interwoven with the algorithm to gain efficiency. Also, I would be quite hesitant to add any non-adaptive integrators. I see two general options for you:

Also see Issue #27.

If you can tell me more about the nature and purpose of your noise, I may also give more specific advice.

Ziaeemehr commented 2 years ago

Hi, For some optimization reason, I implemented the SDDE code in C++. this is not directly an issue about jitcdde, but I hope to get some hints if you could find some free time.

I show some simple implementation in python just for demonstration which is very slow, but I actually need to get some hints, on what can I use in C/C++.

In the Euler scheme, delayed points can be accessed by index.

system of equations are:
    dy0dt = -y0 + y1(t-1) + y1(t-10) + sigma * dW
    dy1dt = y0 + y1(t-1) - y1
    dy2dt = y1 - y1(t-10)

D = [int(delays[i]/dt) for i in range(len(delays))]

def f_sys_index(t, n):
        f0p = -y[0][n] * y[1][n-D[0]] + y[1][n-D[1]]
        f1p = y[0][n] * y[1][n-D[0]] - y[1][n]
        f2p = y[1][n] - y[1][n-D[1]]

def euler(f_sys):
        for _ in range(nstart, nstart+num_iterations):
            dy = dt * f_sys(t[-1], -1)
            append(y[:, -1] + dy, t[-1] + dt)

To reduce the memory usage I keep only int(maxdelay/dt) elements for each component and roll the coordinates at each time step.

def append(new_y, new_t):
        """append an element"""
        y = np.roll(y, -1)
        y[:, -1] = new_y
        t = np.roll(t, -1)
        t[-1] = new_t

does jitcdde use a circular buffer? thank you for any guide in advance.

Wrzlprmft commented 2 years ago

JiTCDDE uses a doubly-linked cursor list. This is necessary because of the adaptive step size, covering for time-dependent delays, etc. (see Appendix A of the paper for details). If you are working with a constant step size and fixed delays, a circular buffer is a reasonable choice.