Fokker-Planck Equation

The Fokker-Planck equation (FPE) governs the time evolution of the probability density of a stochastic process. It is the deterministic counterpart to the Langevin equation -- tracking the distribution rather than individual realisations. We derive the Chang-Cooper scheme for numerically solving the FPE with guaranteed positivity and correct steady state.

1. Derivation from the Langevin Equation

Given the Itô SDE:

$$dx = a(x)\,dt + b(x)\,dW_t$$

the probability density \(P(x, t)\) satisfies the Fokker-Planck equation:

$$\frac{\partial P}{\partial t} = -\frac{\partial}{\partial x}\bigl[a(x) P\bigr] + \frac{1}{2}\frac{\partial^2}{\partial x^2}\bigl[b^2(x) P\bigr]$$

Derivation via Characteristic Function

Define the characteristic function \(\phi(k,t) = \langle e^{ikx_t} \rangle\). By Itô's lemma with \(f(x) = e^{ikx}\):

$$d(e^{ikx}) = \left(ika \, e^{ikx} - \frac{k^2 b^2}{2} e^{ikx}\right)dt + ikb \, e^{ikx} \, dW$$

Taking expectations (the \(dW\) term vanishes):

$$\frac{\partial \phi}{\partial t} = \langle ik \, a(x) e^{ikx} \rangle - \frac{k^2}{2}\langle b^2(x) e^{ikx} \rangle$$

Inverse Fourier transforming and using integration by parts twice yields the Fokker-Planck equation. The first term \(-\partial(aP)/\partial x\) is the drift (probability current), and the second \(\frac{1}{2}\partial^2(b^2 P)/\partial x^2\) is the diffusion.

Written in conservation form with probability current \(J\):

$$\frac{\partial P}{\partial t} = -\frac{\partial J}{\partial x}, \qquad J(x,t) = a(x)P - \frac{1}{2}\frac{\partial}{\partial x}\bigl[b^2(x)P\bigr]$$

2. Stationary Solution

Setting \(\partial P / \partial t = 0\) and \(J = 0\) (detailed balance):

$$a(x) P_{\text{st}} = \frac{1}{2}\frac{d}{dx}\bigl[b^2(x) P_{\text{st}}\bigr]$$

This is a first-order ODE. Expanding the right side:

$$a \, P_{\text{st}} = \frac{1}{2}\bigl[2b b' P_{\text{st}} + b^2 P_{\text{st}}'\bigr]$$

Rearranging:

$$\frac{P_{\text{st}}'}{P_{\text{st}}} = \frac{2a - 2bb'}{b^2} = \frac{2a}{b^2} - \frac{2b'}{b}$$

Integrating:

$$\boxed{P_{\text{st}}(x) = \frac{\mathcal{N}}{b^2(x)} \exp\!\left(2\int^x \frac{a(x')}{b^2(x')}\,dx'\right)}$$

where \(\mathcal{N}\) is the normalisation constant. For constant diffusion \(b = \sigma\) and gradient drift \(a(x) = -V'(x)\), this reduces to the Boltzmann distribution \(P_{\text{st}} \propto \exp(-2V/\sigma^2)\).

3. Chang-Cooper Numerical Scheme

Standard finite-difference schemes for the FPE can produce negative probabilities or fail to converge to the correct steady state. The Chang-Cooper scheme (1970) cures both issues by interpolating between upwind and downwind differencing.

Discretise the domain \([x_{\min}, x_{\max}]\) into \(N_x\) cells with spacing \(\Delta x\). The discrete probability current at cell boundary \(j+1/2\) is:

$$J_{j+1/2} = a_{j+1/2}\bigl[(1-\delta_j)P_j + \delta_j P_{j+1}\bigr] - \frac{D_{j+1/2}}{\Delta x}(P_{j+1} - P_j)$$

where \(D_{j+1/2} = b^2_{j+1/2}/2\) and the Chang-Cooper parameter \(\delta_j\) is chosen so that the scheme exactly preserves the stationary distribution. Define:

$$w_j = \frac{a_{j+1/2} \, \Delta x}{D_{j+1/2}}$$

Then the optimal interpolation parameter is:

$$\delta_j = \frac{1}{w_j} - \frac{1}{e^{w_j} - 1}$$

This is the Bernoulli function. When \(w \to 0\),\(\delta \to 1/2\) (central differencing); when \(|w| \gg 1\), it approaches upwind differencing. The time update uses the tridiagonal system:

$$\frac{P_j^{n+1} - P_j^n}{\Delta t} = -\frac{J_{j+1/2} - J_{j-1/2}}{\Delta x}$$

4. Python: Chang-Cooper FPE Solver

We solve the Fokker-Planck equation for the bistable potential and compare the evolving distribution to histograms from Langevin simulations.

Chang-Cooper Fokker-Planck Solver

Python
script.py163 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

5. Fortran: Chang-Cooper with Tridiagonal System

For large-scale problems, a Fortran implementation with the Thomas algorithm provides optimal performance. The tridiagonal solver runs in \(O(N)\) operations.

Thomas Algorithm (Tridiagonal Solver) for Chang-Cooper FPE

Python
script.py101 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server