From bd30cca000fcf3fd46e03c43aaa26b8bb6dad3fa Mon Sep 17 00:00:00 2001 From: Matthieu Darcy <68646255+MatthieuDarcy@users.noreply.github.com> Date: Wed, 22 Jul 2026 11:39:45 -0400 Subject: [PATCH 01/10] Added tutorials on PDEs This is a proof of concept on how to use dynestyx to solve inverse problems involving time dependent PDEs. Discretization is done manually using a finite difference scheme, yielding an ODE for which the dynestyx machinery can be applied. --- .../pde/Heat Equation inference.ipynb | 88212 ++++++++++++++++ .../pde/Reaction-diffusion inference.ipynb | 47722 +++++++++ 2 files changed, 135934 insertions(+) create mode 100644 docs/tutorials/pde/Heat Equation inference.ipynb create mode 100644 docs/tutorials/pde/Reaction-diffusion inference.ipynb diff --git a/docs/tutorials/pde/Heat Equation inference.ipynb b/docs/tutorials/pde/Heat Equation inference.ipynb new file mode 100644 index 00000000..a87a7ee5 --- /dev/null +++ b/docs/tutorials/pde/Heat Equation inference.ipynb @@ -0,0 +1,88212 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 68, + "id": "99dc002b", + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "jax.config.update(\"jax_enable_x64\", True)" + ] + }, + { + "cell_type": "markdown", + "id": "ee947373", + "metadata": {}, + "source": [ + "# A quick introduction to modeling dynamical systems driven by partial differential equations\n", + "\n", + "Consider a time-dependent function $u(t,x)$ representing the state of some underlying physical system. In many cases, this function is characterized as the solution of a partial differential equation\n", + "\n", + "$$\n", + "\\frac{\\partial u}{\\partial t} = Lu + f(x, u, \\partial_{x} u, \\partial_{xx}u, \\dots),\n", + "$$\n", + "\n", + "subject to some boundary conditions, where $L$ is a linear differential operator and $f$ is a (generally nonlinear) function of $u$ and possibly its spatial derivatives.\n", + "\n", + "## Discretization of PDEs\n", + "\n", + "Solving a time-dependent PDE numerically requires a choice of spatial discretization: the solution $u(t,x)$ is expressed either in a finite-dimensional basis, global (Fourier, Chebyshev polynomials) or local (Lagrange polynomials, B-splines), or via a spatial discretization scheme such as finite differences or finite volumes. Under any of these choices, the PDE reduces to an ODE over the discretized state $\\mathbf{u}(t) \\in \\mathbb{R}^n$:\n", + "\n", + "$$\n", + "\\frac{d\\mathbf{u}}{dt} = A\\mathbf{u} + f(\\mathbf{u}),\n", + "$$\n", + "\n", + "where $A$ is the matrix representation of the discretized operator $L$, and the boundary conditions are typically absorbed into the definition of $\\mathbf{u}$ and $A$. This reduction turns the problem of inferring unknowns in a PDE into inferring unknowns in an ODE — exactly the class of problem dynestyx is built to handle, letting us place priors over initial conditions and unknown parameters and run standard probabilistic-programming inference directly on the resulting finite-dimensional dynamical system.\n", + "\n", + "Numerically, the ODE can be solved using either an explicit or an implicit time-marching scheme, such as the forward and backward Euler schemes:\n", + "$$\n", + "\\begin{aligned}\n", + "\\mathbf{u}^{n+1} &= \\mathbf{u}^n + \\Delta t\\big( A \\mathbf{u}^n + f(\\mathbf{u}^n) \\big) \\quad &&\\text{Explicit: the RHS depends only on } \\mathbf{u}^n\\\\[4pt]\n", + "\\mathbf{u}^{n+1} &= \\mathbf{u}^n + \\Delta t\\big( A \\mathbf{u}^{n+1} + f(\\mathbf{u}^{n+1}) \\big) \\quad &&\\text{Implicit: the RHS depends only on } \\mathbf{u}^{n+1}\\\\[4pt]\n", + "\\end{aligned}\n", + "$$\n", + "A single step of an explicit scheme is the cheapest to compute, but for stiff systems may require an unrealistically small $\\Delta t$ to remain numerically stable. Implicit schemes remain stable at much larger step sizes, at the cost of a full nonlinear solve at each step. Implicit-explicit (IMEX) methods combine the advantages of both by splitting the right-hand side into an implicit part (often the linear operator $A$) and an explicit part (often the nonlinearity $f$); these are not yet supported in dynestyx." + ] + }, + { + "cell_type": "markdown", + "id": "15d89a8d", + "metadata": {}, + "source": [ + "# A first model: linear heat equation\n", + "\n", + "As a first example, we consider the linear heat equation with zero Dirichlet boundary conditions:\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "&\\frac{\\partial u}{\\partial t} = \\nu\\Delta u \\quad && (x,t) \\in (0, T) \\times (0,1)\\\\\n", + "& u(t, 0) = u(t, 1) = 0 \\quad && x \\in \\{0,1\\}\\\\\n", + "& u(0, x)= u_0 \\quad && x \\in [0,1]\n", + "\\end{aligned}\n", + "$$\n", + "\n", + "where $\\Delta := \\frac{\\partial^2 }{\\partial x^2}$ is the one-dimensional Laplacian. Discretizing space on a uniform grid $x_i$ and writing $\\mathbf{u}^t_i = u(t, x_i)$, the discrete Laplacian is\n", + "\n", + "$$\n", + "\\Delta \\mathbf{u}^t_i = \\frac{\\mathbf{u}^t_{i+1} -2\\mathbf{u}^t_{i} + \\mathbf{u}^t_{i-1}}{h^2}.\n", + "$$\n", + "\n", + "In matrix form this is $\\Delta \\mathbf{u} = A\\mathbf{u}$, where, on the interior nodes (the boundary values are held fixed at zero by the Dirichlet condition), $A$ is the tridiagonal matrix\n", + "\n", + "$$\n", + "A = \\frac{1}{h^2}\n", + "\\begin{pmatrix}\n", + "-2 & 1 & & & \\\\\n", + "1 & -2 & 1 & & \\\\\n", + " & \\ddots & \\ddots & \\ddots & \\\\\n", + " & & 1 & -2 & 1 \\\\\n", + " & & & 1 & -2\n", + "\\end{pmatrix}.\n", + "$$\n", + "\n", + "The dynamics are then given by the linear model\n", + "\n", + "$$\n", + "\\frac{d\\mathbf{u}}{dt}(t) = \\nu A \\mathbf{u}(t).\n", + "$$\n", + "\n", + "The initial condition is a smooth Gaussian bump multiplied by a sine factor to ensure compatibility with the zero Dirichlet boundary condition:\n", + "\n", + "$$\n", + "u_0(x) = \\exp\\Big(-\\frac{(x -\\mu)^2}{0.5}\\Big)\\sin(\\pi x).\n", + "$$\n", + "\n", + "The bump's center $\\mu$ is the unknown parameter we aim to recover." + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "c4eabed1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import jax.numpy as jnp\n", + "import matplotlib.pyplot as plt\n", + "import numpyro\n", + "import numpyro.distributions as dist\n", + "\n", + "import dynestyx as dsx\n", + "from dynestyx import ContinuousTimeStateEvolution, DynamicalModel, LinearGaussianObservation\n", + "from dynestyx.inference.filter_configs import ContinuousTimeKFConfig\n", + "from dynestyx import Simulator, Filter\n", + "import diffrax as dfx\n", + "\n", + "import jax.random as jr\n", + "from numpyro.infer import Predictive\n", + "\n", + "from dynestyx import ODESimulator\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "153b1450", + "metadata": {}, + "outputs": [], + "source": [ + "# Discretization parametes\n", + "spatial_discretization = 2**6\n", + "obs_time = jnp.linspace(0, 1, 2**6)" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "id": "8fd820e0", + "metadata": {}, + "outputs": [], + "source": [ + "# Building the discrete laplacian operator for the heat equation (interior nodes only)\n", + "nu = 1e-2 # diffusion coefficient\n", + "n = spatial_discretization\n", + "x_full = jnp.linspace(0, 1, n, endpoint=True)\n", + "h = x_full[1] - x_full[0]\n", + "x = x_full[1:-1] # interior nodes; boundary values are fixed at 0 by the Dirichlet BC\n", + "\n", + "n_interior = n - 2\n", + "A = (jnp.diag(-2.0 * jnp.ones(n_interior))\n", + " + jnp.diag(jnp.ones(n_interior - 1), 1)\n", + " + jnp.diag(jnp.ones(n_interior - 1), -1)) / h**2 * nu\n", + "\n", + "# Initial condition parameter\n", + "mu_true = 0.5" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "id": "43de3d49", + "metadata": {}, + "outputs": [], + "source": [ + "# define the initial condition a function of mu and x.\n", + "initial_condition = lambda mu : jnp.exp(- (x - mu)**2/(2*0.1**2)) * jnp.sin(jnp.pi*x)\n", + "ic_noise = 1e-2 # the noise on the initial condition\n", + "obs_noise = 1e-2 # the noise on the observations\n", + "\n", + "\n", + "def heat_equation_model(mu=None, obs_times=None, obs_values=None, predict_times=None):\n", + " mu = numpyro.sample(\"mu\", dist.Uniform(0, 1), obs=mu)\n", + "\n", + " # Create the dynamical model with sampled mu\n", + " dynamics = DynamicalModel(initial_condition= dist.Normal(initial_condition(mu), ic_noise).to_event(1),\n", + " state_evolution = ContinuousTimeStateEvolution(\n", + " drift=lambda x, u, t: A @ x,\n", + " ),\n", + " observation_model = LinearGaussianObservation(\n", + " H=jnp.eye(n_interior), R=obs_noise**2 * jnp.eye(n_interior)\n", + " ),\n", + " )\n", + "\n", + " return dsx.sample(\"f\", dynamics, obs_times=obs_times, obs_values=obs_values, predict_times=predict_times)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "5cabf7bf", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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uPo/gqZ99NFHtuDgYFtWVpbjsXvuuceWnp7u2Pfreu6552xxcXG1/v7666/bQkNDbZWVlVS7E/Ly8hx1PXDgwCafv3z5cr2f//TTT47HXnjhBVtUVJQtPz/f1ly03FTbsmWLZGVlyZlnnukI/NT6F4MHD9atMe7aBr8pKSmRH3/8sVb9RUZG6l9bjdVfbGxsvffLysqoXicsWLBAd+kZ66qpa/UdNLXPql+wBw8e1L9o4Xqdq9bFmnN7nH322brlRjXJ10e1SPbp00d3Hdak/o/AuTpXrbzt27evVedqTaOtW7fWu83QoUN1q/DatWv1fTVTypIlS/Tjja1jhN+4uqSCOu60atVKd3XX/J6Ki4t13TcX31a13bt362u1GFdN6r7xN3dsg9o5CKoZs6X19+ijj0paWppuTkbj1MFaHdzrq/M9e/Y0uJ062D/88MO6ST8kJIRqdpHan+urc7X/N5RjpvKghg0bppvrVWCkckaef/55ul9bWOfG3+qjusQ//vhj3Q04YMAA/WNVPffLL7909m3hhu+pbdu2+kdXS86jBDfVjHyNurMmRkVFNXgwac42cG/9vfTSS/Lmm2/qX7kxMTFUbxPUybSqqqreOleP15crppK1VQKsSqxUuSJwndqf66tz428NtWyqBFh1Yr333nt1vsjTTz8tV155JV+Bh+pc5fzdcccduuVA7e9qsILKk3rooYeocy9+T6GhofrSkvNoQK4KXp/k5GRHwmTNKPLIkSOSmprqtm1Qf/3VpOovJSWlyapSv2hVouD777+vu7LQNHXAiIuLq7fO1Uq79bXKLF26VLZt2yb//Oc/9cVISlajdlRT8nvvvacTwtH4vl5fnSsN7etqG9XK9sEHH0h4eLjj5KyCHNWCo1or4d46f+qpp/T/A3VsMah6Vi1naqSbSpaF57+ngoICHdg4cx5oCC031fr16ydhYWE6y9ugKnf16tU6h8Zd20BqHTRUf3jN+lN+/vnnJutPtdbccsstupvk/PPPp1pdoPIQXKnz4cOH62HLzz77rOOintu7d299WzUho3l13qFDB51vUB/VJaUO7kZgoxh1ffToUarciTpfs2ZNraHzqs7VMbtv3771blP3h6pi3K97Aob7vifVOqZGAtb8npQWnUebnYpsQZdddpkeNWJkez/99NO2yMhIPQLKcPvtt+sscFe2QcMeeOABW5s2bRz19dlnn+nRZkuWLHE854knntCjcwxvv/22LTw8XI+GgOtmzZqlRyKsXLlS31+xYoXeZ9955x3Hc2bPnm0bM2ZMg6/BaCnXqP1Z7df/+c9/9P3du3fbWrdubXvwwQcdz1Gj/UaMGGHbt2+fvr9582a9n3/99df6fkVFhW3atGm2Tp066dtonDqmqP36H//4h76vjtF9+/a1XX755Y7nbN++Xdf5smXL9P0XX3yx1v8NNULq5ptvtiUlJR03ShONa2i0VFFRka7zuXPn6vuqXtPS0mx33HGHvl9WVmabNGlSo8cfZxDc1JCTk6OHZsbGxtoyMjL0kOR///vftSps8uTJttNPP92lbdCw0tJS2yWXXKIPQt27d9cHlueff77Wc2688UZbz5499W01NFAN71T1rP6D1LxQ764deNSJs0ePHvq6ZsCuPPXUU7aQkJAGtye4cZ3ar9X+rfZztb+r/V7t/4ZPP/1UD4nduXOn47H3339fn1h79+6tfwT06dPHceJF0+bMmaOPFerYrI7R6litjtmG9evX6zr/9ttvawUzEREROhBSda6CyXnz5lHdTrryyiv18bht27a26Ohox/HZCA7VtapzNcTesGjRIlu7du1s7du31/v7gAEDav0/aA5WBa/Hzp079aRbvXr1Om7YpZrkSQ0J7Nmzp9PboGn79u2TAwcOSLdu3XROSN26zc/Pl4EDB+qE17rN+waV90EegvNU/oEajdCpU6fj+rb379+vR0+NGDGi3m2NnBu1v8N5KpdA1V3r1q2P6/5QXU1qegnVFF8zwVIlFqvHk5KS9OgdYwg/nKPqb/PmzTqXpm5CvBpurEYCqiH3NYcwq1l21XFHHYtUnTNC0Hnr16+vd8Z41b2t6lENXFi2bJl07dq1Vm6qOp6o86va992R20RwAwAALIWEYgAAYCkENwAAwFIIbgAAgKUQ3AAAAEshuAEAAJZCcAMAACyF4AYAAFgKwQ0AALAUghsAAGApBDcA/J5akuOLL76o9djevXvlgw8+0MuiAAgsBDcA/F50dLRceOGF8v777+v7ag0y475aUwhAYAk1uwAA0FJ9+/aVp556Sm6++WYZPXq0/Otf/9ILH86dO5fKBQIQC2cCsIwzzjhDBzVbt27V3VRTp041u0gATEBwA8AyVq9eLUOGDJHTTjtNvvzyS7OLA8AkBDcALMFms8mUKVNk//79sm3bNlm0aJGMHDnS7GIBMAEJxQAs4emnn5a1a9fKggUL5IYbbpArrrhCCgsLzS4WABPQcgPA761Zs0ZGjBihh36fe+65UlxcLMOGDdOPqeRiAIGFlhsAfu8///mPPPjggzqwUaKiouS9997TQc6OHTvMLh4AL6PlBgAAWAotNwAAwFIIbgAAgKUQ3AAAAEshuAEAAJZCcAMAACyF4AYAAFgKwQ0AALAUghsAAGApBDcAAMBSCG4AAIClENwAAABLIbgBAABiJf8PC1IfYlEazt0AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(x, initial_condition(mu_true))\n", + "plt.title(\"Initial condition for the heat equation\")\n", + "plt.xlabel(\"x\")\n", + "plt.ylabel(\"u(t=0, x)\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "de4bfd36", + "metadata": {}, + "source": [ + "## Generating the solution " + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "8e8aac05", + "metadata": {}, + "outputs": [], + "source": [ + "prng_key = jr.PRNGKey(0)\n", + "key, subkey = jr.split(prng_key)\n", + "predictive_model = Predictive(heat_equation_model, num_samples=1)\n", + "\n", + " \n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(), # note the implcit solver is used here\n", + " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", + " dt0=1e-4,\n", + " max_steps=10**6,\n", + "):\n", + " pde_solution = predictive_model(predict_times=obs_time, obs_values=None, mu=mu_true, rng_key=subkey)" + ] + }, + { + "cell_type": "markdown", + "id": "7b3d35f1", + "metadata": {}, + "source": [ + "## Visualizing the solution\n", + "\n", + "We plot the sampled realization both as a space-time heatmap and as an animation of $u(t, \\cdot)$ over time. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "a44a243e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + " \n", + "
\n", + " \n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", + "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", + "\n", + "from matplotlib.animation import FuncAnimation\n", + "from IPython.display import HTML\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))\n", + "\n", + "# Static heatmap\n", + "mesh = ax1.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", + "fig.colorbar(mesh, ax=ax1, label=\"u(t, x)\")\n", + "ax1.set_xlabel(\"x\")\n", + "ax1.set_ylabel(\"t\")\n", + "ax1.set_title(\"Space-time solution of the heat equation\")\n", + "\n", + "# Animated line plot\n", + "line, = ax2.plot(x_full, u_full[0])\n", + "ax2.set_xlim(x_full[0], x_full[-1])\n", + "ax2.set_ylim(u_full.min(), u_full.max())\n", + "ax2.set_xlabel(\"x\")\n", + "ax2.set_ylabel(\"u(t, x)\")\n", + "time_label = ax2.set_title(f\"t = {obs_time[0]:.3f}\")\n", + "\n", + "def update(frame):\n", + " line.set_ydata(u_full[frame])\n", + " time_label.set_text(f\"t = {obs_time[frame]:.3f}\")\n", + " return line, time_label\n", + "\n", + "anim = FuncAnimation(fig, update, frames=u_full.shape[0], interval=80)\n", + "plt.tight_layout()\n", + "plt.close(fig)\n", + "HTML(anim.to_jshtml())" + ] + }, + { + "cell_type": "markdown", + "id": "900d496b", + "metadata": {}, + "source": [ + "# Inferring the initial condition using NUTS through the solver\n", + "\n", + "We can now run NUTS directly under `ODESimulator`: NUTS backpropagates straight through the PDE solve (\"unrolling\"), the same\n", + "pattern used in the ODE tutorial." + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "4a157038", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 150/150 [16:43<00:00, 6.69s/it, 1023 steps of size 5.71e-04. acc. prob=0.87]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior mu mean: 0.4998176615737267\n", + "Posterior mu std: 0.00016913852462442698\n", + "True mu: 0.5\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "from numpyro.infer import MCMC, NUTS\n", + "from numpyro.infer.reparam import LocScaleReparam\n", + "from numpyro.handlers import reparam\n", + "\n", + "# `f_x_0` (dynestyx's internal initial-state site) is a 62-dim latent tightly coupled to\n", + "# the scalar `mu` via a narrow Gaussian (ic_noise). Sampled directly, this is a funnel:\n", + "# NUTS gets stuck with 0% acceptance regardless of warmup/samples. LocScaleReparam\n", + "# non-centers it (raw ~ N(0,1), f_x_0 = loc + ic_noise * raw), which fixes the geometry.\n", + "reparam_model = reparam(heat_equation_model, config={\"f_x_0\": LocScaleReparam(0)})\n", + "\n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(),\n", + " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", + " dt0=1e-4,\n", + " max_steps=10**6,\n", + "):\n", + " nuts_kernel = NUTS(reparam_model, step_size=1e-4)\n", + " mcmc = MCMC(nuts_kernel, num_warmup=75, num_samples=75)\n", + " mcmc.run(\n", + " jr.PRNGKey(1),\n", + " obs_times=pde_solution[\"f_times\"][0, 0],\n", + " obs_values=pde_solution[\"f_observations\"][0, 0],\n", + " )\n", + "posterior = mcmc.get_samples()\n", + "print(\"Posterior mu mean:\", float(jnp.mean(posterior[\"mu\"])))\n", + "print(\"Posterior mu std:\", float(jnp.std(posterior[\"mu\"])))\n", + "print(\"True mu:\", mu_true)" + ] + }, + { + "cell_type": "markdown", + "id": "f40db08a", + "metadata": {}, + "source": [ + "# Inference with the continuous-time Kalman filter\n", + "\n", + "Since the discretized `heat_equation` is a linear-Gaussian state-space model, we can a continuous-time Kalman to get the exact densities and use this within MCMC, as an alternative to running MCMC through the simulation. Further, this allows us to use the LTI module to efficiently solve the linear ODE." + ] + }, + { + "cell_type": "markdown", + "id": "019f5991", + "metadata": {}, + "source": [ + "We first define a new model that uses the LTI module present within dynestyx. " + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "39970910", + "metadata": {}, + "outputs": [], + "source": [ + "def heat_equation(obs_times=None, obs_values=None, predict_times=None):\n", + " mu = numpyro.sample(\"mu\", dist.Uniform(0.0, 1.0))\n", + " dynamics =dsx.LTI_continuous(\n", + " A=A, \n", + " L=jnp.eye(x.shape[0])*0.0, # no diffusion: deterministic heat equation\n", + " H=jnp.eye(x.shape[0]), # observe the full state \n", + " R=obs_noise**2 * jnp.eye(x.shape[0]), # small observation noise \n", + " initial_mean=initial_condition(mu), # initial condition mean\n", + " initial_cov=ic_noise**2*jnp.eye(x.shape[0]), # initial condition covariance\n", + ")\n", + " return dsx.sample(\n", + " \"f\",\n", + " dynamics,\n", + " obs_times=obs_times,\n", + " obs_values=obs_values,\n", + " predict_times=predict_times,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "62bc2534", + "metadata": {}, + "outputs": [], + "source": [ + "data_predictive = Predictive(\n", + " heat_equation,\n", + " params={\"mu\": mu_true},\n", + " num_samples=1,\n", + " exclude_deterministic=False,\n", + ")\n", + "\n", + "with Simulator(n_simulations=1):\n", + " pde_solution = data_predictive(jr.PRNGKey(0), predict_times=obs_time)\n", + "\n", + "u = pde_solution[\"f_states\"][0, 0]\n", + "observations = pde_solution[\"f_observations\"][0, 0]" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "d5ae120e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + " \n", + "
\n", + " \n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", + "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", + "\n", + "from matplotlib.animation import FuncAnimation\n", + "from IPython.display import HTML\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))\n", + "\n", + "# Static heatmap\n", + "mesh = ax1.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", + "fig.colorbar(mesh, ax=ax1, label=\"u(t, x)\")\n", + "ax1.set_xlabel(\"x\")\n", + "ax1.set_ylabel(\"t\")\n", + "ax1.set_title(\"Space-time solution of the heat equation\")\n", + "\n", + "# Animated line plot\n", + "line, = ax2.plot(x_full, u_full[0])\n", + "ax2.set_xlim(x_full[0], x_full[-1])\n", + "ax2.set_ylim(u_full.min(), u_full.max())\n", + "ax2.set_xlabel(\"x\")\n", + "ax2.set_ylabel(\"u(t, x)\")\n", + "time_label = ax2.set_title(f\"t = {obs_time[0]:.3f}\")\n", + "\n", + "def update(frame):\n", + " line.set_ydata(u_full[frame])\n", + " time_label.set_text(f\"t = {obs_time[frame]:.3f}\")\n", + " return line, time_label\n", + "\n", + "anim = FuncAnimation(fig, update, frames=u_full.shape[0], interval=80)\n", + "plt.tight_layout()\n", + "plt.close(fig)\n", + "HTML(anim.to_jshtml())" + ] + }, + { + "cell_type": "markdown", + "id": "f38a891e", + "metadata": {}, + "source": [ + "We now use the continuous time Kalman filter to obtain the marginal densities $p(\\theta | y_{1:T})$ and run MCMC. In this case, the Kalman filter provides exact marginals." + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "4976ab95", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 150/150 [01:30<00:00, 1.65it/s, 3 steps of size 1.06e-01. acc. prob=0.98] \n" + ] + } + ], + "source": [ + "def filtered_parameter_model():\n", + " with Filter(\n", + " filter_config=ContinuousTimeKFConfig( # the continuous-time Kalman filter.\n", + " record_filtered_states_mean=True,\n", + " )\n", + " ):\n", + " return heat_equation(obs_times=obs_time, obs_values=observations)\n", + "\n", + "\n", + "nuts = NUTS(filtered_parameter_model)\n", + "mcmc = MCMC(nuts, num_warmup=75, num_samples=75)\n", + "mcmc.run(jr.PRNGKey(2))\n", + "posterior = mcmc.get_samples()" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "3ac31625", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior mu mean: 0.4999424984828169\n", + "Posterior mu std: 0.00044981278817763694\n", + "True mu: 0.5\n" + ] + } + ], + "source": [ + "print(\"Posterior mu mean:\", float(jnp.mean(posterior[\"mu\"])))\n", + "print(\"Posterior mu std:\", float(jnp.std(posterior[\"mu\"])))\n", + "print(\"True mu:\", mu_true)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dynestyx", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/tutorials/pde/Reaction-diffusion inference.ipynb b/docs/tutorials/pde/Reaction-diffusion inference.ipynb new file mode 100644 index 00000000..c21ed414 --- /dev/null +++ b/docs/tutorials/pde/Reaction-diffusion inference.ipynb @@ -0,0 +1,47722 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "99dc002b", + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "jax.config.update(\"jax_enable_x64\", True)" + ] + }, + { + "cell_type": "markdown", + "id": "e35d5123", + "metadata": {}, + "source": [ + "# A second model: non-linear reaction-diffusion equation\n", + "This notebook assumes that you have read the previous on the heat equation. If you are unfamiliar with finite discretization schemes for PDEs, please refer to the previous notebook on the heat equation for a (very) short introduction. We now consider the nonlinear KPP-Fisher reaction diffusion-equation with zero Dirichlet boundary condition:\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "&\\frac{\\partial u}{\\partial t} = \\nu\\Delta u + ru(1-u) \\quad && (x,t) \\in (0, T) \\times (0,1)\\\\\n", + "& u(t, 0) = u(t, 1) = 0 \\quad && x \\in \\{0,1\\}\\\\\n", + "& u(0, x)= u_0 \\quad && x \\in [0,1]\n", + "\\end{aligned}\n", + "$$\n", + "After discretization using a finite difference scheme $\\mathbf{u}^t_i = u(t, x_i)$ , the resulting ODE system is \n", + "$$\n", + "\\frac{d\\mathbf{u}}{dt}(t) = \\nu A \\mathbf{u}(t) + f(\\mathbf{u})\n", + "$$\n", + "where $f(\\mathbf{u})_i = r\\mathbf{u}_i(1-\\mathbf{u}_i)$. Here we will aim to recover the reaction parameters $r$.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c4eabed1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import jax.numpy as jnp\n", + "import matplotlib.pyplot as plt\n", + "import numpyro\n", + "import numpyro.distributions as dist\n", + "\n", + "import dynestyx as dsx\n", + "from dynestyx import ContinuousTimeStateEvolution, DynamicalModel, LinearGaussianObservation\n", + "import diffrax as dfx\n", + "\n", + "\n", + "import jax.random as jr\n", + "from numpyro.infer import Predictive\n", + "\n", + "from dynestyx import ODESimulator\n", + "from dynestyx import Filter\n", + "from dynestyx.inference.filter_configs import ContinuousTimeEnKFConfig\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "153b1450", + "metadata": {}, + "outputs": [], + "source": [ + "# Discretization parametes\n", + "spatial_discretization = 2**6\n", + "obs_time = jnp.linspace(0, 1, 2**6)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8fd820e0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True r: 1.091723649484995\n" + ] + } + ], + "source": [ + "# Building the discrete laplacian operator for the heat equation (interior nodes only)\n", + "nu = 1e-2 # diffusion coefficient\n", + "dt = 1e-2 # time step for the simulation\n", + "key = jr.PRNGKey(42)\n", + "r_true = dist.Gamma(concentration=1.0, rate=1.0).sample(key) # sample the true reaction rate from a prior distribution\n", + "print(\"True r:\", float(r_true))\n", + "\n", + "\n", + "n = spatial_discretization\n", + "x_full = jnp.linspace(0, 1, n, endpoint=True)\n", + "h = x_full[1] - x_full[0]\n", + "x = x_full[1:-1] # interior nodes; boundary values are fixed at 0 by the Dirichlet BC\n", + "\n", + "n_interior = n - 2\n", + "A = (jnp.diag(-2.0 * jnp.ones(n_interior))\n", + " + jnp.diag(jnp.ones(n_interior - 1), 1)\n", + " + jnp.diag(jnp.ones(n_interior - 1), -1)) / h**2 * nu\n", + " \n", + "f = lambda x: r_true * x * (1 - x) # reaction term\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43de3d49", + "metadata": {}, + "outputs": [], + "source": [ + "# define the initial condition a function of x.\n", + "def initial_condition(x):\n", + " mu = 0.5\n", + " envelope = jnp.exp(-(x - mu)**2 / (2 * 0.5**2)) * jnp.sin(jnp.pi * x)\n", + " wiggle = 1.0 + 0.3 * jnp.sin(6 * jnp.pi * x)\n", + " return 0.8 * envelope * wiggle\n", + "\n", + "ic_noise = 1e-2 # the noise on the initial condition\n", + "obs_noise = 1e-2 # the noise on the observations\n", + "\n", + "def reaction_diffusion_equation_model(r=None, obs_times=None, obs_values=None, predict_times=None):\n", + " r = numpyro.sample(\"r\", dist.Gamma(concentration=1.0, rate=1.0), obs=r)\n", + "\n", + " dynamics = DynamicalModel(\n", + " initial_condition=dist.MultivariateNormal(\n", + " loc=initial_condition(x), covariance_matrix=ic_noise**2 * jnp.eye(n_interior)\n", + " ),\n", + " state_evolution=ContinuousTimeStateEvolution(\n", + " drift=lambda x, u, t: A @ x + r * x * (1 - x),\n", + " ),\n", + " observation_model=LinearGaussianObservation(\n", + " H=jnp.eye(n_interior), R=obs_noise**2 * jnp.eye(n_interior)\n", + " ),\n", + " )\n", + " return dsx.sample(\"f\", dynamics, obs_times=obs_times, obs_values=obs_values, predict_times=predict_times)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "5cabf7bf", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(x, initial_condition(x))\n", + "plt.title(\"Initial condition for the reaction_diffusion_equation_model equation\")\n", + "plt.xlabel(\"x\")\n", + "plt.ylabel(\"u(x, t=0)\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "de4bfd36", + "metadata": {}, + "source": [ + "## Generating the solution " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "34bdad7d", + "metadata": {}, + "outputs": [], + "source": [ + "prng_key = jr.PRNGKey(0)\n", + "key, subkey = jr.split(prng_key)\n", + "predictive_model = Predictive(reaction_diffusion_equation_model, num_samples=1)\n", + "\n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(), # note the use of an implicit solver.\n", + " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", + " dt0=dt,\n", + " max_steps=10**6,\n", + "):\n", + " pde_solution = predictive_model(predict_times=obs_time, obs_values=None, r=r_true, rng_key=subkey)" + ] + }, + { + "cell_type": "markdown", + "id": "7b3d35f1", + "metadata": {}, + "source": [ + "## Visualizing the solution\n", + "\n", + "We plot the sampled realization both as a space-time heatmap and as an animation of $u(t, \\cdot)$ over time. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6e5895fb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + " \n", + "
\n", + " \n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + "
\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", + "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", + "\n", + "from matplotlib.animation import FuncAnimation\n", + "from IPython.display import HTML\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))\n", + "\n", + "# Static heatmap\n", + "mesh = ax1.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", + "fig.colorbar(mesh, ax=ax1, label=\"u(t, x)\")\n", + "ax1.set_xlabel(\"x\")\n", + "ax1.set_ylabel(\"t\")\n", + "ax1.set_title(\"Space-time solution of the KPP equation\")\n", + "\n", + "# Animated line plot\n", + "line, = ax2.plot(x_full, u_full[0])\n", + "ax2.set_xlim(x_full[0], x_full[-1])\n", + "ax2.set_ylim(u_full.min(), u_full.max())\n", + "ax2.set_xlabel(\"x\")\n", + "ax2.set_ylabel(\"u(t, x)\")\n", + "time_label = ax2.set_title(f\"t = {obs_time[0]:.3f}\")\n", + "\n", + "def update(frame):\n", + " line.set_ydata(u_full[frame])\n", + " time_label.set_text(f\"t = {obs_time[frame]:.3f}\")\n", + " return line, time_label\n", + "\n", + "anim = FuncAnimation(fig, update, frames=u_full.shape[0], interval=80)\n", + "plt.tight_layout()\n", + "plt.close(fig)\n", + "HTML(anim.to_jshtml())" + ] + }, + { + "cell_type": "markdown", + "id": "900d496b", + "metadata": {}, + "source": [ + "# Inferring the reaction rate by running MCMC through the simulator\n", + "\n", + "`reaction_diffusion_equation_model` is fully deterministic given `r` (no process noise, small-noise Gaussian\n", + "observation model), so we run NUTS directly under `ODESimulator`: NUTS backpropagates\n", + "straight through the PDE solve (\"unrolling\"), the same \"direct simulation\" pattern used\n", + "for the heat equation. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4a157038", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 75/75 [01:49<00:00, 1.47s/it, 255 steps of size 1.62e-03. acc. prob=0.85] \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior r mean: 1.0895972102153126\n", + "Posterior r std: 0.0027094033006313\n", + "True r: 1.091723649484995\n" + ] + } + ], + "source": [ + "from numpyro.infer import MCMC, NUTS\n", + "from numpyro.infer.reparam import LocScaleReparam\n", + "from numpyro.handlers import reparam\n", + "\n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(),\n", + " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", + " dt0=dt,\n", + " max_steps=10**6,\n", + "):\n", + " nuts_kernel = NUTS(reaction_diffusion_equation_model, step_size=1e-4)\n", + " mcmc = MCMC(nuts_kernel, num_warmup=50, num_samples=25)\n", + " mcmc.run(\n", + " jr.PRNGKey(1),\n", + " obs_times=pde_solution[\"f_times\"][0, 0],\n", + " obs_values=pde_solution[\"f_observations\"][0, 0],\n", + " )\n", + "posterior = mcmc.get_samples()\n", + "print(\"Posterior r mean:\", float(jnp.mean(posterior[\"r\"])))\n", + "print(\"Posterior r std:\", float(jnp.std(posterior[\"r\"])))\n", + "print(\"True r:\", float(r_true))" + ] + }, + { + "cell_type": "markdown", + "id": "5af136da", + "metadata": {}, + "source": [ + "# Inference with the continuous time Ensemble Kalman filter\n", + "\n", + "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "d2e136e5", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 150/150 [02:27<00:00, 1.01it/s, 7 steps of size 2.04e-01. acc. prob=0.95] \n" + ] + } + ], + "source": [ + "def filtered_parameter_model():\n", + " with Filter(\n", + " filter_config=ContinuousTimeEnKFConfig( # continuous-time ensemble Kalman filter\n", + " record_filtered_states_mean=True,\n", + " )\n", + " ):\n", + " return reaction_diffusion_equation_model(obs_times=pde_solution[\"f_times\"][0, 0], obs_values=pde_solution[\"f_observations\"][0, 0])\n", + "\n", + "nuts = NUTS(filtered_parameter_model)\n", + "mcmc = MCMC(nuts, num_warmup=75, num_samples=75)\n", + "mcmc.run(jr.PRNGKey(2))\n", + "posterior = mcmc.get_samples()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "4f5f5e7c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior r mean: 1.0946497820379353\n", + "Posterior r std: 0.0031052409082442454\n", + "True r: 1.091723649484995\n" + ] + } + ], + "source": [ + "print(\"Posterior r mean:\", float(jnp.mean(posterior[\"r\"])))\n", + "print(\"Posterior r std:\", float(jnp.std(posterior[\"r\"])))\n", + "print(\"True r:\", float(r_true))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "994de745", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dynestyx", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 9a58ae450f0cb9b07fbba419039f8e7c915be2d6 Mon Sep 17 00:00:00 2001 From: Matthieu Darcy <68646255+MatthieuDarcy@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:28:28 -0400 Subject: [PATCH 02/10] Updated tutorials Removed html animations to reduce filesize. Changed the reparametrization to use MultivariateNormal (more in line with other tutorials). Renamed notebooks. --- .../pde/Heat Equation inference.ipynb | 88212 ---------------- .../pde/Reaction-diffusion inference.ipynb | 47722 --------- .../pde/heat_equation_inference.ipynb | 545 + .../pde/reaction_diffusion_inference.ipynb | 382 + 4 files changed, 927 insertions(+), 135934 deletions(-) delete mode 100644 docs/tutorials/pde/Heat Equation inference.ipynb delete mode 100644 docs/tutorials/pde/Reaction-diffusion inference.ipynb create mode 100644 docs/tutorials/pde/heat_equation_inference.ipynb create mode 100644 docs/tutorials/pde/reaction_diffusion_inference.ipynb diff --git a/docs/tutorials/pde/Heat Equation inference.ipynb b/docs/tutorials/pde/Heat Equation inference.ipynb deleted file mode 100644 index a87a7ee5..00000000 --- a/docs/tutorials/pde/Heat Equation inference.ipynb +++ /dev/null @@ -1,88212 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 68, - "id": "99dc002b", - "metadata": {}, - "outputs": [], - "source": [ - "import jax\n", - "jax.config.update(\"jax_enable_x64\", True)" - ] - }, - { - "cell_type": "markdown", - "id": "ee947373", - "metadata": {}, - "source": [ - "# A quick introduction to modeling dynamical systems driven by partial differential equations\n", - "\n", - "Consider a time-dependent function $u(t,x)$ representing the state of some underlying physical system. In many cases, this function is characterized as the solution of a partial differential equation\n", - "\n", - "$$\n", - "\\frac{\\partial u}{\\partial t} = Lu + f(x, u, \\partial_{x} u, \\partial_{xx}u, \\dots),\n", - "$$\n", - "\n", - "subject to some boundary conditions, where $L$ is a linear differential operator and $f$ is a (generally nonlinear) function of $u$ and possibly its spatial derivatives.\n", - "\n", - "## Discretization of PDEs\n", - "\n", - "Solving a time-dependent PDE numerically requires a choice of spatial discretization: the solution $u(t,x)$ is expressed either in a finite-dimensional basis, global (Fourier, Chebyshev polynomials) or local (Lagrange polynomials, B-splines), or via a spatial discretization scheme such as finite differences or finite volumes. Under any of these choices, the PDE reduces to an ODE over the discretized state $\\mathbf{u}(t) \\in \\mathbb{R}^n$:\n", - "\n", - "$$\n", - "\\frac{d\\mathbf{u}}{dt} = A\\mathbf{u} + f(\\mathbf{u}),\n", - "$$\n", - "\n", - "where $A$ is the matrix representation of the discretized operator $L$, and the boundary conditions are typically absorbed into the definition of $\\mathbf{u}$ and $A$. This reduction turns the problem of inferring unknowns in a PDE into inferring unknowns in an ODE — exactly the class of problem dynestyx is built to handle, letting us place priors over initial conditions and unknown parameters and run standard probabilistic-programming inference directly on the resulting finite-dimensional dynamical system.\n", - "\n", - "Numerically, the ODE can be solved using either an explicit or an implicit time-marching scheme, such as the forward and backward Euler schemes:\n", - "$$\n", - "\\begin{aligned}\n", - "\\mathbf{u}^{n+1} &= \\mathbf{u}^n + \\Delta t\\big( A \\mathbf{u}^n + f(\\mathbf{u}^n) \\big) \\quad &&\\text{Explicit: the RHS depends only on } \\mathbf{u}^n\\\\[4pt]\n", - "\\mathbf{u}^{n+1} &= \\mathbf{u}^n + \\Delta t\\big( A \\mathbf{u}^{n+1} + f(\\mathbf{u}^{n+1}) \\big) \\quad &&\\text{Implicit: the RHS depends only on } \\mathbf{u}^{n+1}\\\\[4pt]\n", - "\\end{aligned}\n", - "$$\n", - "A single step of an explicit scheme is the cheapest to compute, but for stiff systems may require an unrealistically small $\\Delta t$ to remain numerically stable. Implicit schemes remain stable at much larger step sizes, at the cost of a full nonlinear solve at each step. Implicit-explicit (IMEX) methods combine the advantages of both by splitting the right-hand side into an implicit part (often the linear operator $A$) and an explicit part (often the nonlinearity $f$); these are not yet supported in dynestyx." - ] - }, - { - "cell_type": "markdown", - "id": "15d89a8d", - "metadata": {}, - "source": [ - "# A first model: linear heat equation\n", - "\n", - "As a first example, we consider the linear heat equation with zero Dirichlet boundary conditions:\n", - "\n", - "$$\n", - "\\begin{aligned}\n", - "&\\frac{\\partial u}{\\partial t} = \\nu\\Delta u \\quad && (x,t) \\in (0, T) \\times (0,1)\\\\\n", - "& u(t, 0) = u(t, 1) = 0 \\quad && x \\in \\{0,1\\}\\\\\n", - "& u(0, x)= u_0 \\quad && x \\in [0,1]\n", - "\\end{aligned}\n", - "$$\n", - "\n", - "where $\\Delta := \\frac{\\partial^2 }{\\partial x^2}$ is the one-dimensional Laplacian. Discretizing space on a uniform grid $x_i$ and writing $\\mathbf{u}^t_i = u(t, x_i)$, the discrete Laplacian is\n", - "\n", - "$$\n", - "\\Delta \\mathbf{u}^t_i = \\frac{\\mathbf{u}^t_{i+1} -2\\mathbf{u}^t_{i} + \\mathbf{u}^t_{i-1}}{h^2}.\n", - "$$\n", - "\n", - "In matrix form this is $\\Delta \\mathbf{u} = A\\mathbf{u}$, where, on the interior nodes (the boundary values are held fixed at zero by the Dirichlet condition), $A$ is the tridiagonal matrix\n", - "\n", - "$$\n", - "A = \\frac{1}{h^2}\n", - "\\begin{pmatrix}\n", - "-2 & 1 & & & \\\\\n", - "1 & -2 & 1 & & \\\\\n", - " & \\ddots & \\ddots & \\ddots & \\\\\n", - " & & 1 & -2 & 1 \\\\\n", - " & & & 1 & -2\n", - "\\end{pmatrix}.\n", - "$$\n", - "\n", - "The dynamics are then given by the linear model\n", - "\n", - "$$\n", - "\\frac{d\\mathbf{u}}{dt}(t) = \\nu A \\mathbf{u}(t).\n", - "$$\n", - "\n", - "The initial condition is a smooth Gaussian bump multiplied by a sine factor to ensure compatibility with the zero Dirichlet boundary condition:\n", - "\n", - "$$\n", - "u_0(x) = \\exp\\Big(-\\frac{(x -\\mu)^2}{0.5}\\Big)\\sin(\\pi x).\n", - "$$\n", - "\n", - "The bump's center $\\mu$ is the unknown parameter we aim to recover." - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "c4eabed1", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "import jax.numpy as jnp\n", - "import matplotlib.pyplot as plt\n", - "import numpyro\n", - "import numpyro.distributions as dist\n", - "\n", - "import dynestyx as dsx\n", - "from dynestyx import ContinuousTimeStateEvolution, DynamicalModel, LinearGaussianObservation\n", - "from dynestyx.inference.filter_configs import ContinuousTimeKFConfig\n", - "from dynestyx import Simulator, Filter\n", - "import diffrax as dfx\n", - "\n", - "import jax.random as jr\n", - "from numpyro.infer import Predictive\n", - "\n", - "from dynestyx import ODESimulator\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "153b1450", - "metadata": {}, - "outputs": [], - "source": [ - "# Discretization parametes\n", - "spatial_discretization = 2**6\n", - "obs_time = jnp.linspace(0, 1, 2**6)" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "id": "8fd820e0", - "metadata": {}, - "outputs": [], - "source": [ - "# Building the discrete laplacian operator for the heat equation (interior nodes only)\n", - "nu = 1e-2 # diffusion coefficient\n", - "n = spatial_discretization\n", - "x_full = jnp.linspace(0, 1, n, endpoint=True)\n", - "h = x_full[1] - x_full[0]\n", - "x = x_full[1:-1] # interior nodes; boundary values are fixed at 0 by the Dirichlet BC\n", - "\n", - "n_interior = n - 2\n", - "A = (jnp.diag(-2.0 * jnp.ones(n_interior))\n", - " + jnp.diag(jnp.ones(n_interior - 1), 1)\n", - " + jnp.diag(jnp.ones(n_interior - 1), -1)) / h**2 * nu\n", - "\n", - "# Initial condition parameter\n", - "mu_true = 0.5" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "43de3d49", - "metadata": {}, - "outputs": [], - "source": [ - "# define the initial condition a function of mu and x.\n", - "initial_condition = lambda mu : jnp.exp(- (x - mu)**2/(2*0.1**2)) * jnp.sin(jnp.pi*x)\n", - "ic_noise = 1e-2 # the noise on the initial condition\n", - "obs_noise = 1e-2 # the noise on the observations\n", - "\n", - "\n", - "def heat_equation_model(mu=None, obs_times=None, obs_values=None, predict_times=None):\n", - " mu = numpyro.sample(\"mu\", dist.Uniform(0, 1), obs=mu)\n", - "\n", - " # Create the dynamical model with sampled mu\n", - " dynamics = DynamicalModel(initial_condition= dist.Normal(initial_condition(mu), ic_noise).to_event(1),\n", - " state_evolution = ContinuousTimeStateEvolution(\n", - " drift=lambda x, u, t: A @ x,\n", - " ),\n", - " observation_model = LinearGaussianObservation(\n", - " H=jnp.eye(n_interior), R=obs_noise**2 * jnp.eye(n_interior)\n", - " ),\n", - " )\n", - "\n", - " return dsx.sample(\"f\", dynamics, obs_times=obs_times, obs_values=obs_values, predict_times=predict_times)" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "5cabf7bf", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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uPo/gqZ99NFHtuDgYFtWVpbjsXvuuceWnp7u2Pfreu6552xxcXG1/v7666/bQkNDbZWVlVS7E/Ly8hx1PXDgwCafv3z5cr2f//TTT47HXnjhBVtUVJQtPz/f1ly03FTbsmWLZGVlyZlnnukI/NT6F4MHD9atMe7aBr8pKSmRH3/8sVb9RUZG6l9bjdVfbGxsvffLysqoXicsWLBAd+kZ66qpa/UdNLXPql+wBw8e1L9o4Xqdq9bFmnN7nH322brlRjXJ10e1SPbp00d3Hdak/o/AuTpXrbzt27evVedqTaOtW7fWu83QoUN1q/DatWv1fTVTypIlS/Tjja1jhN+4uqSCOu60atVKd3XX/J6Ki4t13TcX31a13bt362u1GFdN6r7xN3dsg9o5CKoZs6X19+ijj0paWppuTkbj1MFaHdzrq/M9e/Y0uJ062D/88MO6ST8kJIRqdpHan+urc7X/N5RjpvKghg0bppvrVWCkckaef/55ul9bWOfG3+qjusQ//vhj3Q04YMAA/WNVPffLL7909m3hhu+pbdu2+kdXS86jBDfVjHyNurMmRkVFNXgwac42cG/9vfTSS/Lmm2/qX7kxMTFUbxPUybSqqqreOleP15crppK1VQKsSqxUuSJwndqf66tz428NtWyqBFh1Yr333nt1vsjTTz8tV155JV+Bh+pc5fzdcccduuVA7e9qsILKk3rooYeocy9+T6GhofrSkvNoQK4KXp/k5GRHwmTNKPLIkSOSmprqtm1Qf/3VpOovJSWlyapSv2hVouD777+vu7LQNHXAiIuLq7fO1Uq79bXKLF26VLZt2yb//Oc/9cVISlajdlRT8nvvvacTwtH4vl5fnSsN7etqG9XK9sEHH0h4eLjj5KyCHNWCo1or4d46f+qpp/T/A3VsMah6Vi1naqSbSpaF57+ngoICHdg4cx5oCC031fr16ydhYWE6y9ugKnf16tU6h8Zd20BqHTRUf3jN+lN+/vnnJutPtdbccsstupvk/PPPp1pdoPIQXKnz4cOH62HLzz77rOOintu7d299WzUho3l13qFDB51vUB/VJaUO7kZgoxh1ffToUarciTpfs2ZNraHzqs7VMbtv3771blP3h6pi3K97Aob7vifVOqZGAtb8npQWnUebnYpsQZdddpkeNWJkez/99NO2yMhIPQLKcPvtt+sscFe2QcMeeOABW5s2bRz19dlnn+nRZkuWLHE854knntCjcwxvv/22LTw8XI+GgOtmzZqlRyKsXLlS31+xYoXeZ9955x3Hc2bPnm0bM2ZMg6/BaCnXqP1Z7df/+c9/9P3du3fbWrdubXvwwQcdz1Gj/UaMGGHbt2+fvr9582a9n3/99df6fkVFhW3atGm2Tp066dtonDqmqP36H//4h76vjtF9+/a1XX755Y7nbN++Xdf5smXL9P0XX3yx1v8NNULq5ptvtiUlJR03ShONa2i0VFFRka7zuXPn6vuqXtPS0mx33HGHvl9WVmabNGlSo8cfZxDc1JCTk6OHZsbGxtoyMjL0kOR///vftSps8uTJttNPP92lbdCw0tJS2yWXXKIPQt27d9cHlueff77Wc2688UZbz5499W01NFAN71T1rP6D1LxQ764deNSJs0ePHvq6ZsCuPPXUU7aQkJAGtye4cZ3ar9X+rfZztb+r/V7t/4ZPP/1UD4nduXOn47H3339fn1h79+6tfwT06dPHceJF0+bMmaOPFerYrI7R6litjtmG9evX6zr/9ttvawUzEREROhBSda6CyXnz5lHdTrryyiv18bht27a26Ohox/HZCA7VtapzNcTesGjRIlu7du1s7du31/v7gAEDav0/aA5WBa/Hzp079aRbvXr1Om7YpZrkSQ0J7Nmzp9PboGn79u2TAwcOSLdu3XROSN26zc/Pl4EDB+qE17rN+waV90EegvNU/oEajdCpU6fj+rb379+vR0+NGDGi3m2NnBu1v8N5KpdA1V3r1q2P6/5QXU1qegnVFF8zwVIlFqvHk5KS9OgdYwg/nKPqb/PmzTqXpm5CvBpurEYCqiH3NYcwq1l21XFHHYtUnTNC0Hnr16+vd8Z41b2t6lENXFi2bJl07dq1Vm6qOp6o86va992R20RwAwAALIWEYgAAYCkENwAAwFIIbgAAgKUQ3AAAAEshuAEAAJZCcAMAACyF4AYAAFgKwQ0AALAUghsAAGApBDcA/J5akuOLL76o9djevXvlgw8+0MuiAAgsBDcA/F50dLRceOGF8v777+v7ag0y475aUwhAYAk1uwAA0FJ9+/aVp556Sm6++WYZPXq0/Otf/9ILH86dO5fKBQIQC2cCsIwzzjhDBzVbt27V3VRTp041u0gATEBwA8AyVq9eLUOGDJHTTjtNvvzyS7OLA8AkBDcALMFms8mUKVNk//79sm3bNlm0aJGMHDnS7GIBMAEJxQAs4emnn5a1a9fKggUL5IYbbpArrrhCCgsLzS4WABPQcgPA761Zs0ZGjBihh36fe+65UlxcLMOGDdOPqeRiAIGFlhsAfu8///mPPPjggzqwUaKiouS9997TQc6OHTvMLh4AL6PlBgAAWAotNwAAwFIIbgAAgKUQ3AAAAEshuAEAAJZCcAMAACyF4AYAAFgKwQ0AALAUghsAAGApBDcAAMBSCG4AAIClENwAAABLIbgBAABiJf8PC1IfYlEazt0AAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(x, initial_condition(mu_true))\n", - "plt.title(\"Initial condition for the heat equation\")\n", - "plt.xlabel(\"x\")\n", - "plt.ylabel(\"u(t=0, x)\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "de4bfd36", - "metadata": {}, - "source": [ - "## Generating the solution " - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "8e8aac05", - "metadata": {}, - "outputs": [], - "source": [ - "prng_key = jr.PRNGKey(0)\n", - "key, subkey = jr.split(prng_key)\n", - "predictive_model = Predictive(heat_equation_model, num_samples=1)\n", - "\n", - " \n", - "with ODESimulator(\n", - " solver=dfx.ImplicitEuler(), # note the implcit solver is used here\n", - " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", - " dt0=1e-4,\n", - " max_steps=10**6,\n", - "):\n", - " pde_solution = predictive_model(predict_times=obs_time, obs_values=None, mu=mu_true, rng_key=subkey)" - ] - }, - { - "cell_type": "markdown", - "id": "7b3d35f1", - "metadata": {}, - "source": [ - "## Visualizing the solution\n", - "\n", - "We plot the sampled realization both as a space-time heatmap and as an animation of $u(t, \\cdot)$ over time. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "id": "a44a243e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - " \n", - "
\n", - " \n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
\n", - "
\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 75, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", - "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", - "\n", - "from matplotlib.animation import FuncAnimation\n", - "from IPython.display import HTML\n", - "\n", - "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))\n", - "\n", - "# Static heatmap\n", - "mesh = ax1.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", - "fig.colorbar(mesh, ax=ax1, label=\"u(t, x)\")\n", - "ax1.set_xlabel(\"x\")\n", - "ax1.set_ylabel(\"t\")\n", - "ax1.set_title(\"Space-time solution of the heat equation\")\n", - "\n", - "# Animated line plot\n", - "line, = ax2.plot(x_full, u_full[0])\n", - "ax2.set_xlim(x_full[0], x_full[-1])\n", - "ax2.set_ylim(u_full.min(), u_full.max())\n", - "ax2.set_xlabel(\"x\")\n", - "ax2.set_ylabel(\"u(t, x)\")\n", - "time_label = ax2.set_title(f\"t = {obs_time[0]:.3f}\")\n", - "\n", - "def update(frame):\n", - " line.set_ydata(u_full[frame])\n", - " time_label.set_text(f\"t = {obs_time[frame]:.3f}\")\n", - " return line, time_label\n", - "\n", - "anim = FuncAnimation(fig, update, frames=u_full.shape[0], interval=80)\n", - "plt.tight_layout()\n", - "plt.close(fig)\n", - "HTML(anim.to_jshtml())" - ] - }, - { - "cell_type": "markdown", - "id": "900d496b", - "metadata": {}, - "source": [ - "# Inferring the initial condition using NUTS through the solver\n", - "\n", - "We can now run NUTS directly under `ODESimulator`: NUTS backpropagates straight through the PDE solve (\"unrolling\"), the same\n", - "pattern used in the ODE tutorial." - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "4a157038", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "sample: 100%|██████████| 150/150 [16:43<00:00, 6.69s/it, 1023 steps of size 5.71e-04. acc. prob=0.87]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Posterior mu mean: 0.4998176615737267\n", - "Posterior mu std: 0.00016913852462442698\n", - "True mu: 0.5\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "from numpyro.infer import MCMC, NUTS\n", - "from numpyro.infer.reparam import LocScaleReparam\n", - "from numpyro.handlers import reparam\n", - "\n", - "# `f_x_0` (dynestyx's internal initial-state site) is a 62-dim latent tightly coupled to\n", - "# the scalar `mu` via a narrow Gaussian (ic_noise). Sampled directly, this is a funnel:\n", - "# NUTS gets stuck with 0% acceptance regardless of warmup/samples. LocScaleReparam\n", - "# non-centers it (raw ~ N(0,1), f_x_0 = loc + ic_noise * raw), which fixes the geometry.\n", - "reparam_model = reparam(heat_equation_model, config={\"f_x_0\": LocScaleReparam(0)})\n", - "\n", - "with ODESimulator(\n", - " solver=dfx.ImplicitEuler(),\n", - " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", - " dt0=1e-4,\n", - " max_steps=10**6,\n", - "):\n", - " nuts_kernel = NUTS(reparam_model, step_size=1e-4)\n", - " mcmc = MCMC(nuts_kernel, num_warmup=75, num_samples=75)\n", - " mcmc.run(\n", - " jr.PRNGKey(1),\n", - " obs_times=pde_solution[\"f_times\"][0, 0],\n", - " obs_values=pde_solution[\"f_observations\"][0, 0],\n", - " )\n", - "posterior = mcmc.get_samples()\n", - "print(\"Posterior mu mean:\", float(jnp.mean(posterior[\"mu\"])))\n", - "print(\"Posterior mu std:\", float(jnp.std(posterior[\"mu\"])))\n", - "print(\"True mu:\", mu_true)" - ] - }, - { - "cell_type": "markdown", - "id": "f40db08a", - "metadata": {}, - "source": [ - "# Inference with the continuous-time Kalman filter\n", - "\n", - "Since the discretized `heat_equation` is a linear-Gaussian state-space model, we can a continuous-time Kalman to get the exact densities and use this within MCMC, as an alternative to running MCMC through the simulation. Further, this allows us to use the LTI module to efficiently solve the linear ODE." - ] - }, - { - "cell_type": "markdown", - "id": "019f5991", - "metadata": {}, - "source": [ - "We first define a new model that uses the LTI module present within dynestyx. " - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "id": "39970910", - "metadata": {}, - "outputs": [], - "source": [ - "def heat_equation(obs_times=None, obs_values=None, predict_times=None):\n", - " mu = numpyro.sample(\"mu\", dist.Uniform(0.0, 1.0))\n", - " dynamics =dsx.LTI_continuous(\n", - " A=A, \n", - " L=jnp.eye(x.shape[0])*0.0, # no diffusion: deterministic heat equation\n", - " H=jnp.eye(x.shape[0]), # observe the full state \n", - " R=obs_noise**2 * jnp.eye(x.shape[0]), # small observation noise \n", - " initial_mean=initial_condition(mu), # initial condition mean\n", - " initial_cov=ic_noise**2*jnp.eye(x.shape[0]), # initial condition covariance\n", - ")\n", - " return dsx.sample(\n", - " \"f\",\n", - " dynamics,\n", - " obs_times=obs_times,\n", - " obs_values=obs_values,\n", - " predict_times=predict_times,\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "id": "62bc2534", - "metadata": {}, - "outputs": [], - "source": [ - "data_predictive = Predictive(\n", - " heat_equation,\n", - " params={\"mu\": mu_true},\n", - " num_samples=1,\n", - " exclude_deterministic=False,\n", - ")\n", - "\n", - "with Simulator(n_simulations=1):\n", - " pde_solution = data_predictive(jr.PRNGKey(0), predict_times=obs_time)\n", - "\n", - "u = pde_solution[\"f_states\"][0, 0]\n", - "observations = pde_solution[\"f_observations\"][0, 0]" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "d5ae120e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - " \n", - "
\n", - " \n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
\n", - "
\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 79, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", - "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", - "\n", - "from matplotlib.animation import FuncAnimation\n", - "from IPython.display import HTML\n", - "\n", - "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))\n", - "\n", - "# Static heatmap\n", - "mesh = ax1.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", - "fig.colorbar(mesh, ax=ax1, label=\"u(t, x)\")\n", - "ax1.set_xlabel(\"x\")\n", - "ax1.set_ylabel(\"t\")\n", - "ax1.set_title(\"Space-time solution of the heat equation\")\n", - "\n", - "# Animated line plot\n", - "line, = ax2.plot(x_full, u_full[0])\n", - "ax2.set_xlim(x_full[0], x_full[-1])\n", - "ax2.set_ylim(u_full.min(), u_full.max())\n", - "ax2.set_xlabel(\"x\")\n", - "ax2.set_ylabel(\"u(t, x)\")\n", - "time_label = ax2.set_title(f\"t = {obs_time[0]:.3f}\")\n", - "\n", - "def update(frame):\n", - " line.set_ydata(u_full[frame])\n", - " time_label.set_text(f\"t = {obs_time[frame]:.3f}\")\n", - " return line, time_label\n", - "\n", - "anim = FuncAnimation(fig, update, frames=u_full.shape[0], interval=80)\n", - "plt.tight_layout()\n", - "plt.close(fig)\n", - "HTML(anim.to_jshtml())" - ] - }, - { - "cell_type": "markdown", - "id": "f38a891e", - "metadata": {}, - "source": [ - "We now use the continuous time Kalman filter to obtain the marginal densities $p(\\theta | y_{1:T})$ and run MCMC. In this case, the Kalman filter provides exact marginals." - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "4976ab95", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "sample: 100%|██████████| 150/150 [01:30<00:00, 1.65it/s, 3 steps of size 1.06e-01. acc. prob=0.98] \n" - ] - } - ], - "source": [ - "def filtered_parameter_model():\n", - " with Filter(\n", - " filter_config=ContinuousTimeKFConfig( # the continuous-time Kalman filter.\n", - " record_filtered_states_mean=True,\n", - " )\n", - " ):\n", - " return heat_equation(obs_times=obs_time, obs_values=observations)\n", - "\n", - "\n", - "nuts = NUTS(filtered_parameter_model)\n", - "mcmc = MCMC(nuts, num_warmup=75, num_samples=75)\n", - "mcmc.run(jr.PRNGKey(2))\n", - "posterior = mcmc.get_samples()" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "id": "3ac31625", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Posterior mu mean: 0.4999424984828169\n", - "Posterior mu std: 0.00044981278817763694\n", - "True mu: 0.5\n" - ] - } - ], - "source": [ - "print(\"Posterior mu mean:\", float(jnp.mean(posterior[\"mu\"])))\n", - "print(\"Posterior mu std:\", float(jnp.std(posterior[\"mu\"])))\n", - "print(\"True mu:\", mu_true)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "dynestyx", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.14" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/tutorials/pde/Reaction-diffusion inference.ipynb b/docs/tutorials/pde/Reaction-diffusion inference.ipynb deleted file mode 100644 index c21ed414..00000000 --- a/docs/tutorials/pde/Reaction-diffusion inference.ipynb +++ /dev/null @@ -1,47722 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "99dc002b", - "metadata": {}, - "outputs": [], - "source": [ - "import jax\n", - "jax.config.update(\"jax_enable_x64\", True)" - ] - }, - { - "cell_type": "markdown", - "id": "e35d5123", - "metadata": {}, - "source": [ - "# A second model: non-linear reaction-diffusion equation\n", - "This notebook assumes that you have read the previous on the heat equation. If you are unfamiliar with finite discretization schemes for PDEs, please refer to the previous notebook on the heat equation for a (very) short introduction. We now consider the nonlinear KPP-Fisher reaction diffusion-equation with zero Dirichlet boundary condition:\n", - "\n", - "$$\n", - "\\begin{aligned}\n", - "&\\frac{\\partial u}{\\partial t} = \\nu\\Delta u + ru(1-u) \\quad && (x,t) \\in (0, T) \\times (0,1)\\\\\n", - "& u(t, 0) = u(t, 1) = 0 \\quad && x \\in \\{0,1\\}\\\\\n", - "& u(0, x)= u_0 \\quad && x \\in [0,1]\n", - "\\end{aligned}\n", - "$$\n", - "After discretization using a finite difference scheme $\\mathbf{u}^t_i = u(t, x_i)$ , the resulting ODE system is \n", - "$$\n", - "\\frac{d\\mathbf{u}}{dt}(t) = \\nu A \\mathbf{u}(t) + f(\\mathbf{u})\n", - "$$\n", - "where $f(\\mathbf{u})_i = r\\mathbf{u}_i(1-\\mathbf{u}_i)$. Here we will aim to recover the reaction parameters $r$.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "c4eabed1", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "import jax.numpy as jnp\n", - "import matplotlib.pyplot as plt\n", - "import numpyro\n", - "import numpyro.distributions as dist\n", - "\n", - "import dynestyx as dsx\n", - "from dynestyx import ContinuousTimeStateEvolution, DynamicalModel, LinearGaussianObservation\n", - "import diffrax as dfx\n", - "\n", - "\n", - "import jax.random as jr\n", - "from numpyro.infer import Predictive\n", - "\n", - "from dynestyx import ODESimulator\n", - "from dynestyx import Filter\n", - "from dynestyx.inference.filter_configs import ContinuousTimeEnKFConfig\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "153b1450", - "metadata": {}, - "outputs": [], - "source": [ - "# Discretization parametes\n", - "spatial_discretization = 2**6\n", - "obs_time = jnp.linspace(0, 1, 2**6)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "8fd820e0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "True r: 1.091723649484995\n" - ] - } - ], - "source": [ - "# Building the discrete laplacian operator for the heat equation (interior nodes only)\n", - "nu = 1e-2 # diffusion coefficient\n", - "dt = 1e-2 # time step for the simulation\n", - "key = jr.PRNGKey(42)\n", - "r_true = dist.Gamma(concentration=1.0, rate=1.0).sample(key) # sample the true reaction rate from a prior distribution\n", - "print(\"True r:\", float(r_true))\n", - "\n", - "\n", - "n = spatial_discretization\n", - "x_full = jnp.linspace(0, 1, n, endpoint=True)\n", - "h = x_full[1] - x_full[0]\n", - "x = x_full[1:-1] # interior nodes; boundary values are fixed at 0 by the Dirichlet BC\n", - "\n", - "n_interior = n - 2\n", - "A = (jnp.diag(-2.0 * jnp.ones(n_interior))\n", - " + jnp.diag(jnp.ones(n_interior - 1), 1)\n", - " + jnp.diag(jnp.ones(n_interior - 1), -1)) / h**2 * nu\n", - " \n", - "f = lambda x: r_true * x * (1 - x) # reaction term\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "43de3d49", - "metadata": {}, - "outputs": [], - "source": [ - "# define the initial condition a function of x.\n", - "def initial_condition(x):\n", - " mu = 0.5\n", - " envelope = jnp.exp(-(x - mu)**2 / (2 * 0.5**2)) * jnp.sin(jnp.pi * x)\n", - " wiggle = 1.0 + 0.3 * jnp.sin(6 * jnp.pi * x)\n", - " return 0.8 * envelope * wiggle\n", - "\n", - "ic_noise = 1e-2 # the noise on the initial condition\n", - "obs_noise = 1e-2 # the noise on the observations\n", - "\n", - "def reaction_diffusion_equation_model(r=None, obs_times=None, obs_values=None, predict_times=None):\n", - " r = numpyro.sample(\"r\", dist.Gamma(concentration=1.0, rate=1.0), obs=r)\n", - "\n", - " dynamics = DynamicalModel(\n", - " initial_condition=dist.MultivariateNormal(\n", - " loc=initial_condition(x), covariance_matrix=ic_noise**2 * jnp.eye(n_interior)\n", - " ),\n", - " state_evolution=ContinuousTimeStateEvolution(\n", - " drift=lambda x, u, t: A @ x + r * x * (1 - x),\n", - " ),\n", - " observation_model=LinearGaussianObservation(\n", - " H=jnp.eye(n_interior), R=obs_noise**2 * jnp.eye(n_interior)\n", - " ),\n", - " )\n", - " return dsx.sample(\"f\", dynamics, obs_times=obs_times, obs_values=obs_values, predict_times=predict_times)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "5cabf7bf", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(x, initial_condition(x))\n", - "plt.title(\"Initial condition for the reaction_diffusion_equation_model equation\")\n", - "plt.xlabel(\"x\")\n", - "plt.ylabel(\"u(x, t=0)\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "de4bfd36", - "metadata": {}, - "source": [ - "## Generating the solution " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "34bdad7d", - "metadata": {}, - "outputs": [], - "source": [ - "prng_key = jr.PRNGKey(0)\n", - "key, subkey = jr.split(prng_key)\n", - "predictive_model = Predictive(reaction_diffusion_equation_model, num_samples=1)\n", - "\n", - "with ODESimulator(\n", - " solver=dfx.ImplicitEuler(), # note the use of an implicit solver.\n", - " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", - " dt0=dt,\n", - " max_steps=10**6,\n", - "):\n", - " pde_solution = predictive_model(predict_times=obs_time, obs_values=None, r=r_true, rng_key=subkey)" - ] - }, - { - "cell_type": "markdown", - "id": "7b3d35f1", - "metadata": {}, - "source": [ - "## Visualizing the solution\n", - "\n", - "We plot the sampled realization both as a space-time heatmap and as an animation of $u(t, \\cdot)$ over time. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "6e5895fb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - " \n", - "
\n", - " \n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - "
\n", - "
\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", - "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", - "\n", - "from matplotlib.animation import FuncAnimation\n", - "from IPython.display import HTML\n", - "\n", - "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))\n", - "\n", - "# Static heatmap\n", - "mesh = ax1.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", - "fig.colorbar(mesh, ax=ax1, label=\"u(t, x)\")\n", - "ax1.set_xlabel(\"x\")\n", - "ax1.set_ylabel(\"t\")\n", - "ax1.set_title(\"Space-time solution of the KPP equation\")\n", - "\n", - "# Animated line plot\n", - "line, = ax2.plot(x_full, u_full[0])\n", - "ax2.set_xlim(x_full[0], x_full[-1])\n", - "ax2.set_ylim(u_full.min(), u_full.max())\n", - "ax2.set_xlabel(\"x\")\n", - "ax2.set_ylabel(\"u(t, x)\")\n", - "time_label = ax2.set_title(f\"t = {obs_time[0]:.3f}\")\n", - "\n", - "def update(frame):\n", - " line.set_ydata(u_full[frame])\n", - " time_label.set_text(f\"t = {obs_time[frame]:.3f}\")\n", - " return line, time_label\n", - "\n", - "anim = FuncAnimation(fig, update, frames=u_full.shape[0], interval=80)\n", - "plt.tight_layout()\n", - "plt.close(fig)\n", - "HTML(anim.to_jshtml())" - ] - }, - { - "cell_type": "markdown", - "id": "900d496b", - "metadata": {}, - "source": [ - "# Inferring the reaction rate by running MCMC through the simulator\n", - "\n", - "`reaction_diffusion_equation_model` is fully deterministic given `r` (no process noise, small-noise Gaussian\n", - "observation model), so we run NUTS directly under `ODESimulator`: NUTS backpropagates\n", - "straight through the PDE solve (\"unrolling\"), the same \"direct simulation\" pattern used\n", - "for the heat equation. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a157038", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "sample: 100%|██████████| 75/75 [01:49<00:00, 1.47s/it, 255 steps of size 1.62e-03. acc. prob=0.85] \n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Posterior r mean: 1.0895972102153126\n", - "Posterior r std: 0.0027094033006313\n", - "True r: 1.091723649484995\n" - ] - } - ], - "source": [ - "from numpyro.infer import MCMC, NUTS\n", - "from numpyro.infer.reparam import LocScaleReparam\n", - "from numpyro.handlers import reparam\n", - "\n", - "with ODESimulator(\n", - " solver=dfx.ImplicitEuler(),\n", - " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", - " dt0=dt,\n", - " max_steps=10**6,\n", - "):\n", - " nuts_kernel = NUTS(reaction_diffusion_equation_model, step_size=1e-4)\n", - " mcmc = MCMC(nuts_kernel, num_warmup=50, num_samples=25)\n", - " mcmc.run(\n", - " jr.PRNGKey(1),\n", - " obs_times=pde_solution[\"f_times\"][0, 0],\n", - " obs_values=pde_solution[\"f_observations\"][0, 0],\n", - " )\n", - "posterior = mcmc.get_samples()\n", - "print(\"Posterior r mean:\", float(jnp.mean(posterior[\"r\"])))\n", - "print(\"Posterior r std:\", float(jnp.std(posterior[\"r\"])))\n", - "print(\"True r:\", float(r_true))" - ] - }, - { - "cell_type": "markdown", - "id": "5af136da", - "metadata": {}, - "source": [ - "# Inference with the continuous time Ensemble Kalman filter\n", - "\n", - "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "d2e136e5", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "sample: 100%|██████████| 150/150 [02:27<00:00, 1.01it/s, 7 steps of size 2.04e-01. acc. prob=0.95] \n" - ] - } - ], - "source": [ - "def filtered_parameter_model():\n", - " with Filter(\n", - " filter_config=ContinuousTimeEnKFConfig( # continuous-time ensemble Kalman filter\n", - " record_filtered_states_mean=True,\n", - " )\n", - " ):\n", - " return reaction_diffusion_equation_model(obs_times=pde_solution[\"f_times\"][0, 0], obs_values=pde_solution[\"f_observations\"][0, 0])\n", - "\n", - "nuts = NUTS(filtered_parameter_model)\n", - "mcmc = MCMC(nuts, num_warmup=75, num_samples=75)\n", - "mcmc.run(jr.PRNGKey(2))\n", - "posterior = mcmc.get_samples()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "4f5f5e7c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Posterior r mean: 1.0946497820379353\n", - "Posterior r std: 0.0031052409082442454\n", - "True r: 1.091723649484995\n" - ] - } - ], - "source": [ - "print(\"Posterior r mean:\", float(jnp.mean(posterior[\"r\"])))\n", - "print(\"Posterior r std:\", float(jnp.std(posterior[\"r\"])))\n", - "print(\"True r:\", float(r_true))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "994de745", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "dynestyx", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.14" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/tutorials/pde/heat_equation_inference.ipynb b/docs/tutorials/pde/heat_equation_inference.ipynb new file mode 100644 index 00000000..4c172b15 --- /dev/null +++ b/docs/tutorials/pde/heat_equation_inference.ipynb @@ -0,0 +1,545 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "99dc002b", + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "jax.config.update(\"jax_enable_x64\", True)" + ] + }, + { + "cell_type": "markdown", + "id": "ee947373", + "metadata": {}, + "source": [ + "# A quick introduction to modeling dynamical systems driven by partial differential equations\n", + "\n", + "Consider a time-dependent function $u(t,x)$ representing the state of some underlying physical system. In many cases, this function is characterized as the solution of a partial differential equation\n", + "\n", + "$$\n", + "\\frac{\\partial u}{\\partial t} = Lu + f(x, u, \\partial_{x} u, \\partial_{xx}u, \\dots),\n", + "$$\n", + "\n", + "subject to some boundary conditions, where $L$ is a linear differential operator and $f$ is a (generally nonlinear) function of $u$ and possibly its spatial derivatives.\n", + "\n", + "## Discretization of PDEs\n", + "\n", + "Solving a time-dependent PDE numerically requires a choice of spatial discretization: the solution $u(t,x)$ is expressed either in a finite-dimensional basis, global (Fourier, Chebyshev polynomials) or local (Lagrange polynomials, B-splines), or via a spatial discretization scheme such as finite differences or finite volumes. Under any of these choices, the PDE reduces to an ODE over the discretized state $\\mathbf{u}(t) \\in \\mathbb{R}^n$:\n", + "\n", + "$$\n", + "\\frac{d\\mathbf{u}}{dt} = A\\mathbf{u} + f(\\mathbf{u}),\n", + "$$\n", + "\n", + "where $A$ is the matrix representation of the discretized operator $L$, and the boundary conditions are typically absorbed into the definition of $\\mathbf{u}$ and $A$. This reduction turns the problem of inferring unknowns in a PDE into inferring unknowns in an ODE, exactly the class of problem dynestyx is built to handle, letting us place priors over initial conditions and unknown parameters and run standard probabilistic-programming inference directly on the resulting finite-dimensional dynamical system.\n", + "\n", + "Numerically, the ODE can be solved using either an explicit or an implicit time-marching scheme, such as the forward and backward Euler schemes:\n", + "$$\n", + "\\begin{aligned}\n", + "\\mathbf{u}^{n+1} &= \\mathbf{u}^n + \\Delta t\\big( A \\mathbf{u}^n + f(\\mathbf{u}^n) \\big) \\quad &&\\text{Explicit: the RHS depends only on } \\mathbf{u}^n\\\\[4pt]\n", + "\\mathbf{u}^{n+1} &= \\mathbf{u}^n + \\Delta t\\big( A \\mathbf{u}^{n+1} + f(\\mathbf{u}^{n+1}) \\big) \\quad &&\\text{Implicit: the RHS depends only on } \\mathbf{u}^{n+1}\\\\[4pt]\n", + "\\end{aligned}\n", + "$$\n", + "A single step of an explicit scheme is the cheapest to compute, but for stiff systems (such as diffusion equations) may require an unrealistically small $\\Delta t$ to remain numerically stable. Implicit schemes remain stable at much larger step sizes, at the cost of a full nonlinear solve at each step. Implicit-explicit (IMEX) methods combine the advantages of both by splitting the right-hand side into an implicit part (often the linear operator $A$) and an explicit part (often the nonlinearity $f$); these are not yet supported in dynestyx." + ] + }, + { + "cell_type": "markdown", + "id": "15d89a8d", + "metadata": {}, + "source": [ + "# A first model: linear heat equation\n", + "\n", + "As a first example, we consider the linear heat equation with zero Dirichlet boundary conditions:\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "&\\frac{\\partial u}{\\partial t} = \\nu\\Delta u \\quad && (x,t) \\in (0, T) \\times (0,1)\\\\\n", + "& u(t, 0) = u(t, 1) = 0 \\quad && x \\in \\{0,1\\}\\\\\n", + "& u(0, x)= u_0 \\quad && x \\in [0,1]\n", + "\\end{aligned}\n", + "$$\n", + "\n", + "where $\\Delta := \\frac{\\partial^2 }{\\partial x^2}$ is the one-dimensional Laplacian. Discretizing space on a uniform grid $x_i$ and writing $\\mathbf{u}^t_i = u(t, x_i)$, the discrete Laplacian is\n", + "\n", + "$$\n", + "\\Delta \\mathbf{u}^t_i = \\frac{\\mathbf{u}^t_{i+1} -2\\mathbf{u}^t_{i} + \\mathbf{u}^t_{i-1}}{h^2}.\n", + "$$\n", + "\n", + "In matrix form this is $\\Delta \\mathbf{u} = A\\mathbf{u}$, where, on the interior nodes (the boundary values are held fixed at zero by the Dirichlet condition), $A$ is the tridiagonal matrix\n", + "\n", + "$$\n", + "A = \\frac{1}{h^2}\n", + "\\begin{pmatrix}\n", + "-2 & 1 & & & \\\\\n", + "1 & -2 & 1 & & \\\\\n", + " & \\ddots & \\ddots & \\ddots & \\\\\n", + " & & 1 & -2 & 1 \\\\\n", + " & & & 1 & -2\n", + "\\end{pmatrix}.\n", + "$$\n", + "\n", + "The dynamics are then given by the linear model\n", + "\n", + "$$\n", + "\\frac{d\\mathbf{u}}{dt}(t) = \\nu A \\mathbf{u}(t).\n", + "$$\n", + "\n", + "The initial condition is a smooth Gaussian bump multiplied by a sine factor to ensure compatibility with the zero Dirichlet boundary condition:\n", + "\n", + "$$\n", + "u_0(x) = \\exp\\Big(-\\frac{(x -\\mu)^2}{0.5}\\Big)\\sin(\\pi x).\n", + "$$\n", + "\n", + "The bump's center $\\mu$ is the unknown parameter we aim to recover." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c4eabed1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import jax.numpy as jnp\n", + "import matplotlib.pyplot as plt\n", + "import numpyro\n", + "import numpyro.distributions as dist\n", + "\n", + "import dynestyx as dsx\n", + "from dynestyx import ContinuousTimeStateEvolution, DynamicalModel, LinearGaussianObservation\n", + "from dynestyx.inference.filter_configs import ContinuousTimeKFConfig\n", + "from dynestyx import Simulator, Filter\n", + "import diffrax as dfx\n", + "\n", + "import jax.random as jr\n", + "from numpyro.infer import Predictive\n", + "\n", + "from dynestyx import ODESimulator\n", + "from numpyro.infer.reparam import TransformReparam\n", + "from numpyro.distributions.transforms import LowerCholeskyAffine\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "153b1450", + "metadata": {}, + "outputs": [], + "source": [ + "# Discretization parametes (if the simulation is too slow, try reducing these)\n", + "spatial_discretization = 2**6 # spatial discretization for the simulation\n", + "dt = 1e-2 # time step for the simulation (ony an initial guess, the ODE solver will adaptively choose the time step)\n", + "obs_time = jnp.linspace(0, 1, 2**6)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "8fd820e0", + "metadata": {}, + "outputs": [], + "source": [ + "# Building the discrete laplacian operator for the heat equation (interior nodes only)\n", + "nu = 1e-2 # diffusion coefficient\n", + "n = spatial_discretization\n", + "x_full = jnp.linspace(0, 1, n, endpoint=True)\n", + "h = x_full[1] - x_full[0]\n", + "x = x_full[1:-1] # interior nodes; boundary values are fixed at 0 by the Dirichlet BC\n", + "\n", + "n_interior = n - 2\n", + "A = (jnp.diag(-2.0 * jnp.ones(n_interior))\n", + " + jnp.diag(jnp.ones(n_interior - 1), 1)\n", + " + jnp.diag(jnp.ones(n_interior - 1), -1)) / h**2 * nu\n", + "\n", + "# Initial condition parameter\n", + "mu_true = 0.5" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "43de3d49", + "metadata": {}, + "outputs": [], + "source": [ + "# define the initial condition a function of mu and x.\n", + "initial_condition = lambda mu : jnp.exp(- (x - mu)**2/(2*0.1**2)) * jnp.sin(jnp.pi*x)\n", + "ic_noise = 1e-2 # the noise on the initial condition\n", + "obs_noise = 1e-2 # the noise on the observations\n", + "\n", + "\n", + "\n", + "def heat_equation_model(mu=None, obs_times=None, obs_values=None, predict_times=None):\n", + " mu = numpyro.sample(\"mu\", dist.Uniform(0, 1), obs=mu)\n", + "\n", + " # Create the dynamical model with sampled mu\n", + " # Reparameterize the initial condition\n", + " standard_x0 = dist.MultivariateNormal(\n", + " loc=jnp.zeros(n_interior),\n", + " scale_tril=jnp.eye(n_interior),\n", + " )\n", + "\n", + " initial_distribution = dist.TransformedDistribution(\n", + " standard_x0,\n", + " LowerCholeskyAffine(\n", + " loc=initial_condition(mu),\n", + " scale_tril=ic_noise * jnp.eye(n_interior),\n", + " ),\n", + " )\n", + "\n", + " dynamics = DynamicalModel(\n", + " initial_condition=initial_distribution,\n", + " state_evolution=ContinuousTimeStateEvolution(\n", + " drift=lambda x, u, t: A @ x,\n", + " ),\n", + " observation_model=LinearGaussianObservation(\n", + " H=jnp.eye(n_interior), R=obs_noise**2 * jnp.eye(n_interior)\n", + " ),\n", + " )\n", + "\n", + " return dsx.sample(\"f\", dynamics, obs_times=obs_times, obs_values=obs_values, predict_times=predict_times)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "5cabf7bf", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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uPo/gqZ99NFHtuDgYFtWVpbjsXvuuceWnp7u2Pfreu6552xxcXG1/v7666/bQkNDbZWVlVS7E/Ly8hx1PXDgwCafv3z5cr2f//TTT47HXnjhBVtUVJQtPz/f1ly03FTbsmWLZGVlyZlnnukI/NT6F4MHD9atMe7aBr8pKSmRH3/8sVb9RUZG6l9bjdVfbGxsvffLysqoXicsWLBAd+kZ66qpa/UdNLXPql+wBw8e1L9o4Xqdq9bFmnN7nH322brlRjXJ10e1SPbp00d3Hdak/o/AuTpXrbzt27evVedqTaOtW7fWu83QoUN1q/DatWv1fTVTypIlS/Tjja1jhN+4uqSCOu60atVKd3XX/J6Ki4t13TcX31a13bt362u1GFdN6r7xN3dsg9o5CKoZs6X19+ijj0paWppuTkbj1MFaHdzrq/M9e/Y0uJ062D/88MO6ST8kJIRqdpHan+urc7X/N5RjpvKghg0bppvrVWCkckaef/55ul9bWOfG3+qjusQ//vhj3Q04YMAA/WNVPffLL7909m3hhu+pbdu2+kdXS86jBDfVjHyNurMmRkVFNXgwac42cG/9vfTSS/Lmm2/qX7kxMTFUbxPUybSqqqreOleP15crppK1VQKsSqxUuSJwndqf66tz428NtWyqBFh1Yr333nt1vsjTTz8tV155JV+Bh+pc5fzdcccduuVA7e9qsILKk3rooYeocy9+T6GhofrSkvNoQK4KXp/k5GRHwmTNKPLIkSOSmprqtm1Qf/3VpOovJSWlyapSv2hVouD777+vu7LQNHXAiIuLq7fO1Uq79bXKLF26VLZt2yb//Oc/9cVISlajdlRT8nvvvacTwtH4vl5fnSsN7etqG9XK9sEHH0h4eLjj5KyCHNWCo1or4d46f+qpp/T/A3VsMah6Vi1naqSbSpaF57+ngoICHdg4cx5oCC031fr16ydhYWE6y9ugKnf16tU6h8Zd20BqHTRUf3jN+lN+/vnnJutPtdbccsstupvk/PPPp1pdoPIQXKnz4cOH62HLzz77rOOintu7d299WzUho3l13qFDB51vUB/VJaUO7kZgoxh1ffToUarciTpfs2ZNraHzqs7VMbtv3771blP3h6pi3K97Aob7vifVOqZGAtb8npQWnUebnYpsQZdddpkeNWJkez/99NO2yMhIPQLKcPvtt+sscFe2QcMeeOABW5s2bRz19dlnn+nRZkuWLHE854knntCjcwxvv/22LTw8XI+GgOtmzZqlRyKsXLlS31+xYoXeZ9955x3Hc2bPnm0bM2ZMg6/BaCnXqP1Z7df/+c9/9P3du3fbWrdubXvwwQcdz1Gj/UaMGGHbt2+fvr9582a9n3/99df6fkVFhW3atGm2Tp066dtonDqmqP36H//4h76vjtF9+/a1XX755Y7nbN++Xdf5smXL9P0XX3yx1v8NNULq5ptvtiUlJR03ShONa2i0VFFRka7zuXPn6vuqXtPS0mx33HGHvl9WVmabNGlSo8cfZxDc1JCTk6OHZsbGxtoyMjL0kOR///vftSps8uTJttNPP92lbdCw0tJS2yWXXKIPQt27d9cHlueff77Wc2688UZbz5499W01NFAN71T1rP6D1LxQ764deNSJs0ePHvq6ZsCuPPXUU7aQkJAGtye4cZ3ar9X+rfZztb+r/V7t/4ZPP/1UD4nduXOn47H3339fn1h79+6tfwT06dPHceJF0+bMmaOPFerYrI7R6litjtmG9evX6zr/9ttvawUzEREROhBSda6CyXnz5lHdTrryyiv18bht27a26Ohox/HZCA7VtapzNcTesGjRIlu7du1s7du31/v7gAEDav0/aA5WBa/Hzp079aRbvXr1Om7YpZrkSQ0J7Nmzp9PboGn79u2TAwcOSLdu3XROSN26zc/Pl4EDB+qE17rN+waV90EegvNU/oEajdCpU6fj+rb379+vR0+NGDGi3m2NnBu1v8N5KpdA1V3r1q2P6/5QXU1qegnVFF8zwVIlFqvHk5KS9OgdYwg/nKPqb/PmzTqXpm5CvBpurEYCqiH3NYcwq1l21XFHHYtUnTNC0Hnr16+vd8Z41b2t6lENXFi2bJl07dq1Vm6qOp6o86va992R20RwAwAALIWEYgAAYCkENwAAwFIIbgAAgKUQ3AAAAEshuAEAAJZCcAMAACyF4AYAAFgKwQ0AALAUghsAAGApBDcA/J5akuOLL76o9djevXvlgw8+0MuiAAgsBDcA/F50dLRceOGF8v777+v7ag0y475aUwhAYAk1uwAA0FJ9+/aVp556Sm6++WYZPXq0/Otf/9ILH86dO5fKBQIQC2cCsIwzzjhDBzVbt27V3VRTp041u0gATEBwA8AyVq9eLUOGDJHTTjtNvvzyS7OLA8AkBDcALMFms8mUKVNk//79sm3bNlm0aJGMHDnS7GIBMAEJxQAs4emnn5a1a9fKggUL5IYbbpArrrhCCgsLzS4WABPQcgPA761Zs0ZGjBihh36fe+65UlxcLMOGDdOPqeRiAIGFlhsAfu8///mPPPjggzqwUaKiouS9997TQc6OHTvMLh4AL6PlBgAAWAotNwAAwFIIbgAAgKUQ3AAAAEshuAEAAJZCcAMAACyF4AYAAFgKwQ0AALAUghsAAGApBDcAAMBSCG4AAIClENwAAABLIbgBAABiJf8PC1IfYlEazt0AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(x, initial_condition(mu_true))\n", + "plt.title(\"Initial condition for the heat equation\")\n", + "plt.xlabel(\"x\")\n", + "plt.ylabel(\"u(t=0, x)\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "de4bfd36", + "metadata": {}, + "source": [ + "## Generating the solution " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "8e8aac05", + "metadata": {}, + "outputs": [], + "source": [ + "prng_key = jr.PRNGKey(0)\n", + "key, subkey = jr.split(prng_key)\n", + "predictive_model = Predictive(heat_equation_model, num_samples=1)\n", + "\n", + " \n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(), # note the implcit solver is used here\n", + " stepsize_controller=dfx.PIDController(rtol=1e-3, atol=1e-3),\n", + " dt0=dt,\n", + " max_steps=10**6,\n", + "):\n", + " pde_solution = predictive_model(predict_times=obs_time, obs_values=None, mu=mu_true, rng_key=subkey)" + ] + }, + { + "cell_type": "markdown", + "id": "7b3d35f1", + "metadata": {}, + "source": [ + "## Visualizing the solution\n", + "\n", + "We plot the sampled realization as a space-time heatmap. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a44a243e", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeYAAAGGCAYAAACuZyKVAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUTJJREFUeJztnQe8E1X2x0/yCr0ICAjSBaSjgBRFRVBkQUHs6IKKaxcUC2JFhT9W7Kzi7roUFXFdRewKdkUREAEVBUSxgEgvD3gvc/+fczHZ5OXMe3eSTDLJ/L5+xkdu5k69kzP3nt89J6CUUgQAAAAATxDM9AEAAAAA4H/AMAMAAAAeAoYZAAAA8BAwzAAAAICHgGEGAAAAPAQMMwAAAOAhYJgBAAAADwHDDAAAAHgIGGYAAADAQ8Aw5yDvvfceBQIBeueddygXcfP8suXa/fzzzzRkyBCqXbu2Pt777rvP8TZeeuklXXfBggWuHGO69wOyqw0DHxrm7777js4//3w65JBDqHLlytSsWTM65ZRT6JVXXiHLsijbeeONN/TDxw8h8N+1u+KKK+j777+nFStWEEfVvfbaa3P2XJMhV88/V88L7CefcpClS5fSkUceSZ06daKZM2dSx44daf369fTggw/SySefTB988AEdddRRlKsce+yx+sca5O61e//992n48OFUv379TB8K8BjZ0oaBzwzzQw89RLt27aLnnnuODj74YF3WvHlzevjhh6lPnz5UoUKFTB8iAAkTCoVo69atVKlSJVxFAHIRlYMMHjxY5eXlqX379pW77osvvsivluqTTz5Rd955p2rQoIGqWLGiOvbYY9WiRYti1v3mm2/0uuGlQoUKql27duree+9VoVAoZt0tW7aoa665RrVo0UKvx39vuOEGtX379ph1rr76atW0aVNVUFCgDjroIHXZZZeprVu3lnnMf//732OOI7xwOfPuu+/qz2+//bZ4nhMnTtTnWa1aNXXOOeeonTt3Ksuy1IQJE1TDhg31+Q8aNEht2LAhbt+JHnNRUZE+f74OvH2uf/7556u1a9fGrPfDDz/oYzrwwANVYWGhatmypbr99ttj7qV0fo888oguW7dunXjPnnrqqYSvnelxha/xp59+qiZPnqwaNWqk733v3r3V0qVLy7w+pvuZNGmSePw7duyI21Z55+r0eBO9927sx+RZLO/87TA9zxUrVqj+/furSpUqqbp166rrr79effvtt3ofTz75pOO2marzynQbBsmTk4aZGzE3rptuuqlc4xxuiEOHDlX33HOP+uOPP9TKlStVv379tOHif9uxadMm/VDxg8n7jH6wDz30UP1gv/LKK/qBXr16tbr77rvVP//5T73Otm3bVNu2bVWrVq3UvHnz9A/rF198oTp27Ki6detW7nG//vrr+rj5ISxNWYb5jDPOUA8//LDavHmz+uyzz/QPysiRI/UD+sADD+hzWrhwoapfv7467bTTYrabzDFfccUV+gfhvffeU7t371Y///yzmjZtmn55CfPLL7+oevXqqU6dOunt8nV7+umnVZUqVdQpp5xS5vk5+fFzeu1Mjyt8jfnH77777lMbN27U7adz586qefPmqri42Pb6ONkPb4f3M3bs2DK3V965OjneZO59OvZj9yyWdf4Spvvndla7dm3Vs2dPtWzZMv08TZkyRZ1++ulJGeZUnFcm2zBIDTlpmPnhOffcc1UgEFDVq1dXf/nLX9SNN96oG2zpnm10Q4yGHzQ2zMOGDSt3f5dccok65JBDIp+5ZxgMBtWSJUts69xyyy16neXLl8eU82c+nhkzZrhimC+88MKYdW+99Vb99nzRRRfFlLOh5uPjl4xUHHP79u31j1ZZjBo1So90fPfdd+KLVvhc022YTY8rfI0vuOCCmPVeffVVXf7mm2+m5PxTbZhNjjeZe5+u/UjPolPDbLr/K6+8Uj83/IJZ+gU0lYY5kfPKZBsGqSEnVdkFBQU0Y8YM+vHHH+mBBx6gVq1a0Wuvvab9yz179tRTTUrDorBoDjjgADrmmGNo/vz5MeX//ve/qVevXlS9enWtiuTl8ccfpzVr1kTU3ryvtm3bUufOnW2Pce7cuXqddu3axZTzZxb0sLhnz549kX2EFxawJcOAAQNiPh966KG0b98+6tu3b0x5mzZt9PmsXbvW0THbwUI8rj9p0iRauXKluM68efOoQ4cO1LJly5jy0047LfJ9JnB6XAMHDoz53L59e/2X20gq95MqTI43mXvv1n5MnkWnmO6f70WXLl2oYcOGMevxFLZkceO80tWGQWrIScMcplGjRnTBBRdo47xkyRKaPXs2LVy4kC6//PK4devVqyeW/fHHH5HP/HDwFKxBgwbpaSrFxcWRqSr8wIQfmt9//z3ugS0N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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", + "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", + "\n", + "fig, ax = plt.subplots(figsize=(5, 4))\n", + "mesh = ax.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", + "fig.colorbar(mesh, ax=ax, label=\"u(t, x)\")\n", + "ax.set_xlabel(\"x\")\n", + "ax.set_ylabel(\"t\")\n", + "ax.set_title(\"Space-time solution of the heat equation\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "900d496b", + "metadata": {}, + "source": [ + "# Inferring the initial condition using NUTS through the solver\n", + "\n", + "We can now run NUTS directly under `ODESimulator`: NUTS backpropagates straight through the PDE solve (\"unrolling\"), the same\n", + "pattern used in the ODE tutorial." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "4a157038", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 150/150 [03:02<00:00, 1.21s/it, 1023 steps of size 4.70e-04. acc. prob=0.93]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior mu mean: 0.4992715247133896\n", + "Posterior mu std: 0.00016874902994593196\n", + "True mu: 0.5\n" + ] + } + ], + "source": [ + "from numpyro.infer import MCMC, NUTS\n", + "from numpyro.handlers import reparam\n", + "\n", + "# `f_x_0` (dynestyx's internal initial-state site) is a 62-dim latent tightly coupled to\n", + "# the scalar `mu` via a narrow Gaussian (ic_noise). Sampled directly, this is a funnel:\n", + "# NUTS gets stuck with 0% acceptance regardless of warmup/samples. LocScaleReparam\n", + "# non-centers it (raw ~ N(0,1), f_x_0 = loc + ic_noise * raw), which fixes the geometry.\n", + "reparam_model = reparam(heat_equation_model, config={\"f_x_0\": TransformReparam()})\n", + "\n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(), # note the use of the implicit solver here, unconditionally stable for stiff problems like the heat equation\n", + " stepsize_controller=dfx.PIDController(rtol=1e-3, atol=1e-3),\n", + " dt0=dt,\n", + " max_steps=10**6,\n", + "):\n", + " nuts_kernel = NUTS(reparam_model, step_size=1e-4)\n", + " mcmc = MCMC(nuts_kernel, num_warmup=75, num_samples=75)\n", + " mcmc.run(\n", + " jr.PRNGKey(1),\n", + " obs_times=pde_solution[\"f_times\"][0, 0],\n", + " obs_values=pde_solution[\"f_observations\"][0, 0],\n", + " )\n", + "posterior = mcmc.get_samples()\n", + "print(\"Posterior mu mean:\", float(jnp.mean(posterior[\"mu\"])))\n", + "print(\"Posterior mu std:\", float(jnp.std(posterior[\"mu\"])))\n", + "print(\"True mu:\", mu_true)" + ] + }, + { + "cell_type": "markdown", + "id": "f40db08a", + "metadata": {}, + "source": [ + "# Inference with the continuous-time Kalman filter\n", + "\n", + "Since the discretized `heat_equation` is a linear-Gaussian state-space model, we can a continuous-time Kalman to get the exact densities and use this within MCMC, as an alternative to running MCMC through the simulation. Further, this allows us to use the LTI module to efficiently solve the linear ODE." + ] + }, + { + "cell_type": "markdown", + "id": "019f5991", + "metadata": {}, + "source": [ + "We first define a new model that uses the LTI module present within dynestyx. " + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "39970910", + "metadata": {}, + "outputs": [], + "source": [ + "def heat_equation(obs_times=None, obs_values=None, predict_times=None):\n", + " mu = numpyro.sample(\"mu\", dist.Uniform(0.0, 1.0))\n", + " dynamics =dsx.LTI_continuous(\n", + " A=A, \n", + " L=jnp.eye(x.shape[0])*0.0, # no diffusion: deterministic heat equation\n", + " H=jnp.eye(x.shape[0]), # observe the full state \n", + " R=obs_noise**2 * jnp.eye(x.shape[0]), # small observation noise \n", + " initial_mean=initial_condition(mu), # initial condition mean\n", + " initial_cov=ic_noise**2*jnp.eye(x.shape[0]), # initial condition covariance\n", + ")\n", + " return dsx.sample(\n", + " \"f\",\n", + " dynamics,\n", + " obs_times=obs_times,\n", + " obs_values=obs_values,\n", + " predict_times=predict_times,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "62bc2534", + "metadata": {}, + "outputs": [], + "source": [ + "data_predictive = Predictive(\n", + " heat_equation,\n", + " params={\"mu\": mu_true},\n", + " num_samples=1,\n", + " exclude_deterministic=False,\n", + ")\n", + "\n", + "with Simulator(n_simulations=1):\n", + " pde_solution = data_predictive(jr.PRNGKey(0), predict_times=obs_time)\n", + "\n", + "u = pde_solution[\"f_states\"][0, 0]\n", + "observations = pde_solution[\"f_observations\"][0, 0]" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d5ae120e", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeYAAAGGCAYAAACuZyKVAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUbNJREFUeJztnQeYFMXWhk/PBnJQEAHJiChRBQUxISKKEQMG9IKCVxQwgYqYCIIYMWf9FVRUvF7M6QIGDCgiklQkiCICkpewwO5M/c8p7syd2Tm9VE9PT+rv9WmXqenqrk5zuup8dY6llFIEAAAAgIwgkO4GAAAAAOB/wDADAAAAGQQMMwAAAJBBwDADAAAAGQQMMwAAAJBBwDADAAAAGQQMMwAAAJBBwDADAAAAGQQMMwAAAJBBwDDnIJ999hlZlkXTpk2jXMTL48uWc/fnn39Sr169qFatWrq9999/v+NtvPXWW7rurFmzPGljqvcDsuseBj40zL/++itddtlldOCBB1LlypWpadOmdPbZZ9N7771HoVCIsp2PPvpIP3z8EAL/nbshQ4bQkiVLaNGiRcRRdW+44YacPVY35Orx5+pxgT3kUw4yb948Ovroo6l9+/b08ssvU7t27WjNmjX00EMP0ZlnnklffPEFHXPMMZSrdO3aVf9Yg9w9d59//jn17duX6tatm+6mgAwjW+5h4DPD/PDDD9P27dvp9ddfpwYNGuiyZs2a0SOPPEInnHACVahQId1NBCBhgsEgbd68mSpVqoSzCEAuonKQs846S+Xl5andu3fvdd2pU6fyq6X6+uuv1Z133qnq16+vKlasqLp27armzJkTs+7PP/+s1w0vFSpUUK1bt1b33XefCgaDMetu2rRJDRs2TDVv3lyvx39vvvlmVVRUFLPO9ddfr5o0aaIKCgpUvXr11KBBg9TmzZvLbfOTTz4Z047wwuXMp59+qj//5z//EY9z3Lhx+jirVaumLr74YrVt2zYVCoXU2LFj1QEHHKCP//TTT1dr166N23eibS4uLtbHz+eBt8/1L7vsMrVixYqY9X777Tfdpv32208VFhaqFi1aqNGjR8dcS+n4Hn30UV22cuVK8Zq98MILCZ8703aFz/E333yjJkyYoBo2bKiv/bHHHqvmzZtX7vkx3c/48ePF9m/dujVuW3s7VqftTfTae7Efk2dxb8dvh+lxLlq0SJ188smqUqVKqk6dOuqmm25Sv/zyi97Hs88+6/jeTNZxpfseBu7JScPMNzHfXLfeeutejXP4RjznnHPUvffeq9avX68WL16sunfvrg0X/9uODRs26IeKH0zeZ/SDffDBB+sH+7333tMP9LJly9Q999yjnn/+eb3Oli1bVKtWrdRBBx2kpk+frn9Yv//+e9WuXTt1xBFH7LXdH374oW43P4RlKc8wn3/++eqRRx5RGzduVN9++63+QRkwYIB+QB988EF9TLNnz1Z169ZV5513Xsx23bR5yJAh+gfhs88+Uzt27FB//vmnmjhxon55CbNq1Sq1//77q/bt2+vt8nl75ZVXVJUqVdTZZ59d7vE5+fFzeu5M2xU+x/zjd//996t169bp++fQQw9VzZo1UyUlJbbnx8l+eDu8n+HDh5e7vb0dq5P2urn2qdiP3bNY3vFLmO6f77NatWqpo446Si1YsEA/T0888YTq3bu3K8OcjONK5z0MkkNOGmZ+eC655BJlWZaqXr26OvXUU9Utt9yib9iyPdvoGzEaftDYMPfp02ev+7vyyivVgQceGPnMPcNAIKDmzp1rW+f222/X6yxcuDCmnD9ze1566SVPDPPll18es+4dd9yh356vuOKKmHI21Nw+fslIRpvbtGmjf7TK45prrtEjHb/++qv4ohU+1lQbZtN2hc9x//79Y9Z7//33dfnHH3+clONPtmE2aa+ba5+q/UjPolPDbLr/q6++Wj83/IJZ9gU0mYY5keNK5z0MkkNOqrILCgropZdeot9//50efPBBOuigg+iDDz7Q/uWjjjpKTzUpC4vCotlnn33o+OOPpxkzZsSUv/jii9SlSxeqXr26VkXy8tRTT9Hy5csjam/eV6tWrejQQw+1beO7776r12ndunVMOX9mQQ+Le3bu3BnZR3hhAZsbevbsGfP54IMPpt27d9OJJ54YU37IIYfo41mxYoWjNtvBQjyuP378eFq8eLG4zvTp06lt27bUokWLmPLzzjsv8n06cNqu0047LeZzmzZt9F++R5K5n2Rh0l43196r/Zg8i04x3T9fiw4dOtABBxwQsx5PYXOLF8eVqnsYJIecNMxhGjZsSP3799fGee7cuTRlyhSaPXs2DR48OG7d/fffXyxbv3595DM/HDwF6/TTT9fTVEpKSiJTVfiBCT80f//9d9wDWxZW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VdIjhATfqJxAJZh0H7P8LJj66k2fTbPn3153YiX8O2Ni5MLbchLYwxxulRfbzUFUmvjiiy/4Cqkff/wxUvb444+rihUrqqKiIv05GAyqBQsWqE2bNhnX2RsrV67U28CCc4B7APcA7gH5HuDfyWRRXFys6tatm/C5rlu3rt6Gn7D4f+l6KeCA4dzj5SDiGzdupEGDBtE111wTGXrmucrsQ37hhRfo0ksvNaqzN3jY+6+//qJq1arpOKnc0y47R84vsL/dz8fP+P0c+P34GZyD/52DP/74QyuTORIWa3eSxc6dOxMO2FFYWKiDgPiJtAYYYXn6uHHj6I477tDz0saOHasNbXRotNatW8co6PZWZ2/wzdagQQP973C0l/DcOL/i9+Nn/H4O/H78DM4B6ahaXtwHbFj9Zlyz1jCzHF0KrRaGe7ULFy50VAcAAADIZtIeKxsAAAAA/8PXhpmHwkeOHCmGd/MDfj9+xu/nwO/Hz+Ac4BxkGmkVfwEAAAAgFl/3mAEAAIBMA4YZAAAAyCBgmAEAAIAMIqcNM895Puuss6hbt250++2364AiXtTJVDZt2kQ33XQTnXDCCXTOOefEhTMtC8sNpk6dSn379qXu3bvTlVdeSYsWLaJsZsaMGXT++edT165d6brrrtNpQ035v//7P+rcuTM98cQTlK0UFxfruf4nnnginX766fTyyy8b1fvuu++of//++jm44YYbdDCfbOXHH3/U9zTHSL788stp6dKle63D2YXC902fPn3o/fffp2yFk/i88sorOjgT57I3DcT0+OOP6zo9evSghx9+mEqF8K3AI1SO8swzz6gKFSqohx9+WL311lvq0EMPVccee6wKhUJJrZOp7N69W7e/S5cu6p133lF33323ys/PV1OmTLGtM3ToUHXOOeeoSZMmqWnTpqmrrrpKFRYWqlmzZqls5KOPPtLHPGrUKPXee++pbt26qRYtWqjt27fvte78+fNVw4YN1f7776+GDx+uspXTTjtNHXzwwerNN99UTz31lKpcubK67777yq0zefJk/Rzcdttt6tNPP1VPPPGEOu+881Q2wiF9q1Spou/lDz74QF144YWqVq1a5YacfOCBB1SlSpXUY489po9//PjxKi8vT73yyisqG2nbtq0+7n79+uljN+Gaa65RderUUS+99JK+Hzgs5sCBAz1vK9hDThrm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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", + "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", + "\n", + "fig, ax = plt.subplots(figsize=(5, 4))\n", + "mesh = ax.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", + "fig.colorbar(mesh, ax=ax, label=\"u(t, x)\")\n", + "ax.set_xlabel(\"x\")\n", + "ax.set_ylabel(\"t\")\n", + "ax.set_title(\"Space-time solution of the heat equation\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "f38a891e", + "metadata": {}, + "source": [ + "We now use the continuous time Kalman filter to obtain the marginal densities $p(\\theta | y_{1:T})$ and run MCMC. In this case, the Kalman filter provides exact marginals." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "4976ab95", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 150/150 [01:32<00:00, 1.62it/s, 3 steps of size 1.06e-01. acc. prob=0.98] \n" + ] + } + ], + "source": [ + "def filtered_parameter_model():\n", + " with Filter(\n", + " filter_config=ContinuousTimeKFConfig( # the continuous-time Kalman filter.\n", + " record_filtered_states_mean=True,\n", + " )\n", + " ):\n", + " return heat_equation(obs_times=obs_time, obs_values=observations)\n", + "\n", + "\n", + "nuts = NUTS(filtered_parameter_model)\n", + "mcmc = MCMC(nuts, num_warmup=75, num_samples=75)\n", + "mcmc.run(jr.PRNGKey(2))\n", + "posterior = mcmc.get_samples()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "3ac31625", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior mu mean: 0.4999424984828169\n", + "Posterior mu std: 0.00044981278817763694\n", + "True mu: 0.5\n" + ] + } + ], + "source": [ + "print(\"Posterior mu mean:\", float(jnp.mean(posterior[\"mu\"])))\n", + "print(\"Posterior mu std:\", float(jnp.std(posterior[\"mu\"])))\n", + "print(\"True mu:\", mu_true)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dynestyx", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/tutorials/pde/reaction_diffusion_inference.ipynb b/docs/tutorials/pde/reaction_diffusion_inference.ipynb new file mode 100644 index 00000000..2316fa19 --- /dev/null +++ b/docs/tutorials/pde/reaction_diffusion_inference.ipynb @@ -0,0 +1,382 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 9, + "id": "99dc002b", + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "jax.config.update(\"jax_enable_x64\", True)" + ] + }, + { + "cell_type": "markdown", + "id": "e35d5123", + "metadata": {}, + "source": [ + "# A second model: non-linear reaction-diffusion equation\n", + "This notebook assumes that you have read the previous on the heat equation. If you are unfamiliar with finite discretization schemes for PDEs, please refer to the previous notebook on the heat equation for a (very) short introduction. We now consider the nonlinear KPP-Fisher reaction diffusion-equation with zero Dirichlet boundary condition:\n", + "\n", + "$$\n", + "\\begin{aligned}\n", + "&\\frac{\\partial u}{\\partial t} = \\nu\\Delta u + ru(1-u) \\quad && (x,t) \\in (0, T) \\times (0,1)\\\\\n", + "& u(t, 0) = u(t, 1) = 0 \\quad && x \\in \\{0,1\\}\\\\\n", + "& u(0, x)= u_0 \\quad && x \\in [0,1]\n", + "\\end{aligned}\n", + "$$\n", + "After discretization using a finite difference scheme $\\mathbf{u}^t_i = u(t, x_i)$ , the resulting ODE system is \n", + "$$\n", + "\\frac{d\\mathbf{u}}{dt}(t) = \\nu A \\mathbf{u}(t) + f(\\mathbf{u})\n", + "$$\n", + "where $f(\\mathbf{u})_i = r\\mathbf{u}_i(1-\\mathbf{u}_i)$. Here we will aim to recover the reaction parameters $r$.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "c4eabed1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import jax.numpy as jnp\n", + "import matplotlib.pyplot as plt\n", + "import numpyro\n", + "import numpyro.distributions as dist\n", + "\n", + "import dynestyx as dsx\n", + "from dynestyx import ContinuousTimeStateEvolution, DynamicalModel, LinearGaussianObservation\n", + "import diffrax as dfx\n", + "\n", + "\n", + "import jax.random as jr\n", + "from numpyro.infer import Predictive\n", + "\n", + "from dynestyx import ODESimulator\n", + "from dynestyx import Filter\n", + "from dynestyx.inference.filter_configs import ContinuousTimeEnKFConfig\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "153b1450", + "metadata": {}, + "outputs": [], + "source": [ + "# Discretization parametes (if the simulation is too slow, try reducing these)\n", + "spatial_discretization = 2**6\n", + "dt = 1e-2 # (only an initial guess, the ODE solver will adaptively choose the time step)\n", + "obs_time = jnp.linspace(0, 1, 2**6)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8fd820e0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True r: 1.091723649484995\n" + ] + } + ], + "source": [ + "# Building the discrete laplacian operator for the heat equation (interior nodes only)\n", + "nu = 1e-2 # diffusion coefficient\n", + "key = jr.PRNGKey(42)\n", + "r_true = dist.Gamma(concentration=1.0, rate=1.0).sample(key) # sample the true reaction rate from a prior distribution\n", + "print(\"True r:\", float(r_true))\n", + "\n", + "\n", + "n = spatial_discretization\n", + "x_full = jnp.linspace(0, 1, n, endpoint=True)\n", + "h = x_full[1] - x_full[0]\n", + "x = x_full[1:-1] # interior nodes; boundary values are fixed at 0 by the Dirichlet BC\n", + "\n", + "n_interior = n - 2\n", + "A = (jnp.diag(-2.0 * jnp.ones(n_interior))\n", + " + jnp.diag(jnp.ones(n_interior - 1), 1)\n", + " + jnp.diag(jnp.ones(n_interior - 1), -1)) / h**2 * nu\n", + " \n", + "f = lambda x: r_true * x * (1 - x) # reaction term\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "43de3d49", + "metadata": {}, + "outputs": [], + "source": [ + "# define the initial condition a function of x.\n", + "def initial_condition(x):\n", + " mu = 0.5\n", + " envelope = jnp.exp(-(x - mu)**2 / (2 * 0.5**2)) * jnp.sin(jnp.pi * x)\n", + " wiggle = 1.0 + 0.3 * jnp.sin(6 * jnp.pi * x)\n", + " return 0.8 * envelope * wiggle\n", + "\n", + "ic_noise = 1e-2 # the noise on the initial condition\n", + "obs_noise = 1e-2 # the noise on the observations\n", + "\n", + "def reaction_diffusion_equation_model(r=None, obs_times=None, obs_values=None, predict_times=None):\n", + " r = numpyro.sample(\"r\", dist.Gamma(concentration=1.0, rate=1.0), obs=r)\n", + "\n", + " dynamics = DynamicalModel(\n", + " initial_condition=dist.MultivariateNormal(\n", + " loc=initial_condition(x), covariance_matrix=ic_noise**2 * jnp.eye(n_interior)\n", + " ),\n", + " state_evolution=ContinuousTimeStateEvolution(\n", + " drift=lambda x, u, t: A @ x + r * x * (1 - x),\n", + " ),\n", + " observation_model=LinearGaussianObservation(\n", + " H=jnp.eye(n_interior), R=obs_noise**2 * jnp.eye(n_interior)\n", + " ),\n", + " )\n", + " return dsx.sample(\"f\", dynamics, obs_times=obs_times, obs_values=obs_values, predict_times=predict_times)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "5cabf7bf", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(x, initial_condition(x))\n", + "plt.title(\"Initial condition for the reaction_diffusion_equation_model equation\")\n", + "plt.xlabel(\"x\")\n", + "plt.ylabel(\"u(x, t=0)\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "de4bfd36", + "metadata": {}, + "source": [ + "## Generating the solution " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "34bdad7d", + "metadata": {}, + "outputs": [], + "source": [ + "prng_key = jr.PRNGKey(0)\n", + "key, subkey = jr.split(prng_key)\n", + "predictive_model = Predictive(reaction_diffusion_equation_model, num_samples=1)\n", + "\n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(), # note the use of an implicit solver.\n", + " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", + " dt0=dt,\n", + " max_steps=10**6,\n", + "):\n", + " pde_solution = predictive_model(predict_times=obs_time, obs_values=None, r=r_true, rng_key=subkey)" + ] + }, + { + "cell_type": "markdown", + "id": "7b3d35f1", + "metadata": {}, + "source": [ + "## Visualizing the solution\n", + "\n", + "We plot the sampled realization as a space-time heatmap. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "6e5895fb", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", + "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", + "\n", + "fig, ax = plt.subplots(figsize=(5, 4))\n", + "mesh = ax.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", + "fig.colorbar(mesh, ax=ax, label=\"u(t, x)\")\n", + "ax.set_xlabel(\"x\")\n", + "ax.set_ylabel(\"t\")\n", + "ax.set_title(\"Space-time solution of the KPP equation\")\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "900d496b", + "metadata": {}, + "source": [ + "# Inferring the reaction rate by running MCMC through the simulator\n", + "\n", + "`reaction_diffusion_equation_model` is fully deterministic given `r` (no process noise, small-noise Gaussian\n", + "observation model), so we run NUTS directly under `ODESimulator`: NUTS backpropagates\n", + "straight through the PDE solve (\"unrolling\"), the same \"direct simulation\" pattern used\n", + "for the heat equation. " + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "4a157038", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 75/75 [01:50<00:00, 1.48s/it, 255 steps of size 1.62e-03. acc. prob=0.85] \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior r mean: 1.0895972102153126\n", + "Posterior r std: 0.0027094033006313\n", + "True r: 1.091723649484995\n" + ] + } + ], + "source": [ + "from numpyro.infer import MCMC, NUTS\n", + "from numpyro.infer.reparam import LocScaleReparam\n", + "from numpyro.handlers import reparam\n", + "\n", + "with ODESimulator(\n", + " solver=dfx.ImplicitEuler(),\n", + " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", + " dt0=dt,\n", + " max_steps=10**6,\n", + "):\n", + " nuts_kernel = NUTS(reaction_diffusion_equation_model, step_size=1e-4)\n", + " mcmc = MCMC(nuts_kernel, num_warmup=50, num_samples=25)\n", + " mcmc.run(\n", + " jr.PRNGKey(1),\n", + " obs_times=pde_solution[\"f_times\"][0, 0],\n", + " obs_values=pde_solution[\"f_observations\"][0, 0],\n", + " )\n", + "posterior = mcmc.get_samples()\n", + "print(\"Posterior r mean:\", float(jnp.mean(posterior[\"r\"])))\n", + "print(\"Posterior r std:\", float(jnp.std(posterior[\"r\"])))\n", + "print(\"True r:\", float(r_true))" + ] + }, + { + "cell_type": "markdown", + "id": "5af136da", + "metadata": {}, + "source": [ + "# Inference with the continuous time Ensemble Kalman filter\n", + "\n", + "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. " + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "d2e136e5", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "sample: 100%|██████████| 150/150 [02:34<00:00, 1.03s/it, 7 steps of size 2.04e-01. acc. prob=0.95] \n" + ] + } + ], + "source": [ + "def filtered_parameter_model():\n", + " with Filter(\n", + " filter_config=ContinuousTimeEnKFConfig( # continuous-time ensemble Kalman filter\n", + " record_filtered_states_mean=True,\n", + " )\n", + " ):\n", + " return reaction_diffusion_equation_model(obs_times=pde_solution[\"f_times\"][0, 0], obs_values=pde_solution[\"f_observations\"][0, 0])\n", + "\n", + "nuts = NUTS(filtered_parameter_model)\n", + "mcmc = MCMC(nuts, num_warmup=75, num_samples=75)\n", + "mcmc.run(jr.PRNGKey(2))\n", + "posterior = mcmc.get_samples()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "4f5f5e7c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Posterior r mean: 1.0946497820379353\n", + "Posterior r std: 0.0031052409082442454\n", + "True r: 1.091723649484995\n" + ] + } + ], + "source": [ + "print(\"Posterior r mean:\", float(jnp.mean(posterior[\"r\"])))\n", + "print(\"Posterior r std:\", float(jnp.std(posterior[\"r\"])))\n", + "print(\"True r:\", float(r_true))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dynestyx", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ad92403671c271347431f4d9abc954c68a6ab6f0 Mon Sep 17 00:00:00 2001 From: Matthieu Darcy <68646255+MatthieuDarcy@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:34:19 -0400 Subject: [PATCH 03/10] Update reaction_diffusion_inference.ipynb --- .../pde/reaction_diffusion_inference.ipynb | 84 ++++++++++++++----- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/docs/tutorials/pde/reaction_diffusion_inference.ipynb b/docs/tutorials/pde/reaction_diffusion_inference.ipynb index 2316fa19..99fde93c 100644 --- a/docs/tutorials/pde/reaction_diffusion_inference.ipynb +++ b/docs/tutorials/pde/reaction_diffusion_inference.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 9, + "execution_count": 16, "id": "99dc002b", "metadata": {}, "outputs": [], @@ -35,7 +35,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 17, "id": "c4eabed1", "metadata": {}, "outputs": [], @@ -57,12 +57,14 @@ "from dynestyx import ODESimulator\n", "from dynestyx import Filter\n", "from dynestyx.inference.filter_configs import ContinuousTimeEnKFConfig\n", + "\n", + "from numpyro.infer import MCMC, NUTS\n", "\n" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 18, "id": "153b1450", "metadata": {}, "outputs": [], @@ -75,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 19, "id": "8fd820e0", "metadata": {}, "outputs": [ @@ -110,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 20, "id": "43de3d49", "metadata": {}, "outputs": [], @@ -144,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 21, "id": "5cabf7bf", "metadata": {}, "outputs": [ @@ -177,7 +179,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 22, "id": "34bdad7d", "metadata": {}, "outputs": [], @@ -188,7 +190,7 @@ "\n", "with ODESimulator(\n", " solver=dfx.ImplicitEuler(), # note the use of an implicit solver.\n", - " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", + " stepsize_controller=dfx.PIDController(rtol=1e-3, atol=1e-3),\n", " dt0=dt,\n", " max_steps=10**6,\n", "):\n", @@ -207,13 +209,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 23, "id": "6e5895fb", "metadata": {}, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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zHcS8bTJaMPMUwX3338/LV68ODJdMGvWLKpatSr16NHD/M0j4eXLl9Nhhx1m3mA0bcpT/gL+7wKX7bilwS0xbaUyprB4veoYN6hqAW+ZpyzzGxuVZQAknj179pgZxkTAIio2dPEua61Zs2bMwIvtAPuGy8+e8rbKZ/CrVq2a+U4injYZbZh79+5t1G9XXHEFPfLII7R9+3ajsL7zzjupVq1aESPasWNHev755+mqq65StamMpk2b0oYNG0x97nx8wfnv2rVrU7bB5zebj5/J9nOQ7cfP4Bz87xz89NNPxkjxczJR8MCJA0KVd0NqsSwrxnCWHy0z9evXp8LCQjpw4IDZZkXaJDdtMj5WNsvTx40bR/fdd5850Q899BDdcMMNke95iuGYY44xAi9tm8rgaQoegTPhi80PpGx9KDHZfvxMtp+DbD9+BueAzCjZi37ARi/a8HnB8ccfb/5dsGCBGcSFXZ0///wzHXfccQlrkwwCVrZGCf/vWyJ3RPY7Z+NDKduPn8n2c5Dtx8/gHGTOOejRo4dxe7777rtGLDxixAiaOXMmrV69mqpXr27qnHvuuXTyySebtcraNskG2aUAAABkBDNmzKBBgwZR48aNzQidZ0h5ljXawH777bd0+OGHO2qTbLLaMPNUOIsIJH9FNpDtx89k+znI9uNncA4y5xwceeSRtHTpUlq5cqXxabdv396MgqN58803jW/ZSZtkk9VT2QAAAIDfSHnaRwAAAAD8DxhmAAAAwEfAMAMAAAA+IqMNMyvrWG3Xr18/uvfee01AES/a+JUdO3aY4CscMe28886LCWdaHpYbsDCCM6uceuqpdP3119OyZcsonZk3bx5ddNFF1LdvX7M8gtOGauFUcLyU4sknn6R0hYMn8Fr//v3708CBA2n69Omqdl999ZUJ6s/3we23326C+aQrixYtMn2al8hce+21ZhlMZfzzn/+M9JshQ4aYCIPpCseCfumll+iMM84wuew1cNTFJ554wrThoE6TJk2iUiG8KfAIK0OZPHmyVaVKFWvSpEnWW2+9ZR177LFW7969rVAolNA2fqW4uNjsf69evay3337bevjhh628vDzr1VdftW0zatQo67zzzrNefPFFa86cOdaIESOsgoIC64svvrDSkffff98c8wMPPGC9++67Vr9+/aw2bdpY+/btq7TtkiVLrObNm1uN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", "text/plain": [ "
" ] @@ -251,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "id": "4a157038", "metadata": {}, "outputs": [ @@ -273,10 +275,6 @@ } ], "source": [ - "from numpyro.infer import MCMC, NUTS\n", - "from numpyro.infer.reparam import LocScaleReparam\n", - "from numpyro.handlers import reparam\n", - "\n", "with ODESimulator(\n", " solver=dfx.ImplicitEuler(),\n", " stepsize_controller=dfx.PIDController(rtol=1e-5, atol=1e-5),\n", @@ -303,28 +301,46 @@ "source": [ "# Inference with the continuous time Ensemble Kalman filter\n", "\n", - "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. " + "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. \n", + "\n", + "**A note about solvers used for filtering:** the ``ContinuousTimeEnKF`` will integrate the ODE using its own default solver (which assumes the model is an SDE) Here we specify the solver to match the solver used to generate the solution. If this is too slow, try running the ``ContinuousTimeEnKF``with default setting as it yields very similar performance on this particular problem. \n" ] }, { "cell_type": "code", - "execution_count": 18, - "id": "d2e136e5", + "execution_count": 13, + "id": "2d4c28ef", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "sample: 100%|██████████| 150/150 [02:34<00:00, 1.03s/it, 7 steps of size 2.04e-01. acc. prob=0.95] \n" + "/opt/anaconda3/envs/dynestyx/lib/python3.13/site-packages/equinox/_jit.py:55: UserWarning: `ImplicitEuler` is not marked as converging to either the Itô or the Stratonovich solution.\n", + " out = fun(*args, **kwargs)\n", + "/opt/anaconda3/envs/dynestyx/lib/python3.13/site-packages/equinox/_jit.py:55: UserWarning: `ImplicitEuler` is not marked as converging to either the Itô or the Stratonovich solution.\n", + " out = fun(*args, **kwargs)\n", + "/opt/anaconda3/envs/dynestyx/lib/python3.13/site-packages/equinox/_jit.py:55: UserWarning: `ImplicitEuler` is not marked as converging to either the Itô or the Stratonovich solution.\n", + " out = fun(*args, **kwargs)\n", + " 0%| | 0/150 [00:00 Date: Thu, 23 Jul 2026 09:36:14 -0400 Subject: [PATCH 04/10] Update reaction_diffusion_inference.ipynb --- docs/tutorials/pde/reaction_diffusion_inference.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/pde/reaction_diffusion_inference.ipynb b/docs/tutorials/pde/reaction_diffusion_inference.ipynb index 99fde93c..1963a996 100644 --- a/docs/tutorials/pde/reaction_diffusion_inference.ipynb +++ b/docs/tutorials/pde/reaction_diffusion_inference.ipynb @@ -303,12 +303,12 @@ "\n", "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. \n", "\n", - "**A note about solvers used for filtering:** the ``ContinuousTimeEnKF`` will integrate the ODE using its own default solver (which assumes the model is an SDE) Here we specify the solver to match the solver used to generate the solution. If this is too slow, try running the ``ContinuousTimeEnKF``with default setting as it yields very similar performance on this particular problem. \n" + "**A note about solvers used for filtering:** the ``ContinuousTimeEnKF`` will integrate the ODE using its own default solver (which assumes the model is an SDE). Here we specify the solver to match the solver used to generate the solution. If this is too slow, try running the ``ContinuousTimeEnKF``with default setting as it yields very similar performance on this particular problem. \n" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "id": "2d4c28ef", "metadata": {}, "outputs": [ @@ -338,7 +338,7 @@ " diffeqsolve_dt0=dt,\n", " diffeqsolve_max_steps=10**6,\n", " diffeqsolve_kwargs={\n", - " \"solver\": dfx.ImplicitEuler(),\n", + " \"solver\": dfx.ImplicitEuler(), # we use the same implicit solver as before\n", " \"stepsize_controller\": dfx.PIDController(rtol=1e-3, atol=1e-3, error_order=2),\n", " },\n", " )\n", From 7753c228e41d57ab62797b6b64df4e03f9b1a8b0 Mon Sep 17 00:00:00 2001 From: Matthieu Darcy <68646255+MatthieuDarcy@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:37:13 -0400 Subject: [PATCH 05/10] Update reaction_diffusion_inference.ipynb --- docs/tutorials/pde/reaction_diffusion_inference.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/pde/reaction_diffusion_inference.ipynb b/docs/tutorials/pde/reaction_diffusion_inference.ipynb index 1963a996..1006948e 100644 --- a/docs/tutorials/pde/reaction_diffusion_inference.ipynb +++ b/docs/tutorials/pde/reaction_diffusion_inference.ipynb @@ -303,7 +303,7 @@ "\n", "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. \n", "\n", - "**A note about solvers used for filtering:** the ``ContinuousTimeEnKF`` will integrate the ODE using its own default solver (which assumes the model is an SDE). Here we specify the solver to match the solver used to generate the solution. If this is too slow, try running the ``ContinuousTimeEnKF``with default setting as it yields very similar performance on this particular problem. \n" + "**A note about solvers used for filtering:** the ``ContinuousTimeEnKF`` will integrate the ODE using its own default solver (which assumes the model is an SDE). Here we specify the solver to match the solver used to generate the solution (which is the more accurate, but slower, implicit Euler solver). If this is too slow, try running the ``ContinuousTimeEnKF``with default setting as it yields very similar performance on this particular problem. \n" ] }, { From 2bba6e81497290110c5eadd8fe225e53dec55be3 Mon Sep 17 00:00:00 2001 From: Matthieu Darcy <68646255+MatthieuDarcy@users.noreply.github.com> Date: Thu, 23 Jul 2026 17:52:41 -0400 Subject: [PATCH 06/10] updated the heat equation tutorial 1. Simplified some elements (no more generating the data twice) 2. Added a short explanation about the current limitations of the KF filter (SDE definition and default solver). --- .../pde/heat_equation_inference.ipynb | 105 +++++------------- .../pde/reaction_diffusion_inference.ipynb | 6 +- 2 files changed, 30 insertions(+), 81 deletions(-) diff --git a/docs/tutorials/pde/heat_equation_inference.ipynb b/docs/tutorials/pde/heat_equation_inference.ipynb index 4c172b15..dfb3d010 100644 --- a/docs/tutorials/pde/heat_equation_inference.ipynb +++ b/docs/tutorials/pde/heat_equation_inference.ipynb @@ -99,12 +99,12 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "c4eabed1", "metadata": {}, "outputs": [], "source": [ - "\n", + "import equinox as eqx\n", "import jax.numpy as jnp\n", "import matplotlib.pyplot as plt\n", "import numpyro\n", @@ -121,13 +121,12 @@ "\n", "from dynestyx import ODESimulator\n", "from numpyro.infer.reparam import TransformReparam\n", - "from numpyro.distributions.transforms import LowerCholeskyAffine\n", - "\n" + "from numpyro.distributions.transforms import LowerCholeskyAffine\n" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 3, "id": "153b1450", "metadata": {}, "outputs": [], @@ -140,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 4, "id": "8fd820e0", "metadata": {}, "outputs": [], @@ -163,7 +162,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 29, "id": "43de3d49", "metadata": {}, "outputs": [], @@ -208,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 30, "id": "5cabf7bf", "metadata": {}, "outputs": [ @@ -241,7 +240,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 31, "id": "8e8aac05", "metadata": {}, "outputs": [], @@ -250,6 +249,7 @@ "key, subkey = jr.split(prng_key)\n", "predictive_model = Predictive(heat_equation_model, num_samples=1)\n", "\n", + "from dynestyx import SDESimulator\n", " \n", "with ODESimulator(\n", " solver=dfx.ImplicitEuler(), # note the implcit solver is used here\n", @@ -272,7 +272,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 32, "id": "a44a243e", "metadata": {}, "outputs": [ @@ -314,7 +314,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 9, "id": "4a157038", "metadata": {}, "outputs": [ @@ -322,7 +322,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "sample: 100%|██████████| 150/150 [03:02<00:00, 1.21s/it, 1023 steps of size 4.70e-04. acc. prob=0.93]\n" + "sample: 100%|██████████| 150/150 [03:02<00:00, 1.22s/it, 1023 steps of size 4.70e-04. acc. prob=0.93]" ] }, { @@ -333,6 +333,13 @@ "Posterior mu std: 0.00016874902994593196\n", "True mu: 0.5\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] } ], "source": [ @@ -371,20 +378,14 @@ "source": [ "# Inference with the continuous-time Kalman filter\n", "\n", - "Since the discretized `heat_equation` is a linear-Gaussian state-space model, we can a continuous-time Kalman to get the exact densities and use this within MCMC, as an alternative to running MCMC through the simulation. Further, this allows us to use the LTI module to efficiently solve the linear ODE." - ] - }, - { - "cell_type": "markdown", - "id": "019f5991", - "metadata": {}, - "source": [ - "We first define a new model that uses the LTI module present within dynestyx. " + "Since the discretized `heat_equation` is a linear-Gaussian state-space model, we can a continuous-time Kalman to get the exact densities and use this within MCMC, as an alternative to running MCMC through the simulation. \n", + "\n", + "**A note about solvers used for filtering.** We must first define a new model that uses the LTI module present within dynestyx. This model is mathematically identical to the previous, but under the hood will call an SDE solver instead. This limitation is due to the use of the ``ContinuousTimeKalmanFilter`` which assumes that system is stochastic and will run its own default internal SDE solver (as of version 0.1.0 this cannot yet be customized). Other filters, such as the ``EnsembleKalmanFilter`` do not suffer from these limitations and for an example of this in practice, please consult the tutorial on the reaction diffusion PDE." ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 36, "id": "39970910", "metadata": {}, "outputs": [], @@ -393,7 +394,7 @@ " mu = numpyro.sample(\"mu\", dist.Uniform(0.0, 1.0))\n", " dynamics =dsx.LTI_continuous(\n", " A=A, \n", - " L=jnp.eye(x.shape[0])*0.0, # no diffusion: deterministic heat equation\n", + " L=jnp.eye(x.shape[0])*0.0, # no diffusion (note that under the hood, this will use an SDE solver)\n", " H=jnp.eye(x.shape[0]), # observe the full state \n", " R=obs_noise**2 * jnp.eye(x.shape[0]), # small observation noise \n", " initial_mean=initial_condition(mu), # initial condition mean\n", @@ -408,58 +409,6 @@ " )" ] }, - { - "cell_type": "code", - "execution_count": 18, - "id": "62bc2534", - "metadata": {}, - "outputs": [], - "source": [ - "data_predictive = Predictive(\n", - " heat_equation,\n", - " params={\"mu\": mu_true},\n", - " num_samples=1,\n", - " exclude_deterministic=False,\n", - ")\n", - "\n", - "with Simulator(n_simulations=1):\n", - " pde_solution = data_predictive(jr.PRNGKey(0), predict_times=obs_time)\n", - "\n", - "u = pde_solution[\"f_states\"][0, 0]\n", - "observations = pde_solution[\"f_observations\"][0, 0]" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "d5ae120e", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeYAAAGGCAYAAACuZyKVAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvctoD+AAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUbNJREFUeJztnQeYFMXWhk/PBnJQEAHJiChRBQUxISKKEQMG9IKCVxQwgYqYCIIYMWf9FVRUvF7M6QIGDCgiklQkiCICkpewwO5M/c8p7syd2Tm9VE9PT+rv9WmXqenqrk5zuup8dY6llFIEAAAAgIwgkO4GAAAAAOB/wDADAAAAGQQMMwAAAJBBwDADAAAAGQQMMwAAAJBBwDADAAAAGQQMMwAAAJBBwDADAAAAGQQMMwAAAJBBwDDnIJ999hlZlkXTpk2jXMTL48uWc/fnn39Sr169qFatWrq9999/v+NtvPXWW7rurFmzPGljqvcDsuseBj40zL/++itddtlldOCBB1LlypWpadOmdPbZZ9N7771HoVCIsp2PPvpIP3z8EAL/nbshQ4bQkiVLaNGiRcRRdW+44YacPVY35Orx5+pxgT3kUw4yb948Ovroo6l9+/b08ssvU7t27WjNmjX00EMP0ZlnnklffPEFHXPMMZSrdO3aVf9Yg9w9d59//jn17duX6tatm+6mgAwjW+5h4DPD/PDDD9P27dvp9ddfpwYNGuiyZs2a0SOPPEInnHACVahQId1NBCBhgsEgbd68mSpVqoSzCEAuonKQs846S+Xl5andu3fvdd2pU6fyq6X6+uuv1Z133qnq16+vKlasqLp27armzJkTs+7PP/+s1w0vFSpUUK1bt1b33XefCgaDMetu2rRJDRs2TDVv3lyvx39vvvlmVVRUFLPO9ddfr5o0aaIKCgpUvXr11KBBg9TmzZvLbfOTTz4Z047wwuXMp59+qj//5z//EY9z3Lhx+jirVaumLr74YrVt2zYVCoXU2LFj1QEHHKCP//TTT1dr166N23eibS4uLtbHz+eBt8/1L7vsMrVixYqY9X777Tfdpv32208VFhaqFi1aqNGjR8dcS+n4Hn30UV22cuVK8Zq98MILCZ8703aFz/E333yjJkyYoBo2bKiv/bHHHqvmzZtX7vkx3c/48ePF9m/dujVuW3s7VqftTfTae7Efk2dxb8dvh+lxLlq0SJ188smqUqVKqk6dOuqmm25Sv/zyi97Hs88+6/jeTNZxpfseBu7JScPMNzHfXLfeeutejXP4RjznnHPUvffeq9avX68WL16sunfvrg0X/9uODRs26IeKH0zeZ/SDffDBB+sH+7333tMP9LJly9Q999yjnn/+eb3Oli1bVKtWrdRBBx2kpk+frn9Yv//+e9WuXTt1xBFH7LXdH374oW43P4RlKc8wn3/++eqRRx5RGzduVN9++63+QRkwYIB+QB988EF9TLNnz1Z169ZV5513Xsx23bR5yJAh+gfhs88+Uzt27FB//vmnmjhxon55CbNq1Sq1//77q/bt2+vt8nl75ZVXVJUqVdTZZ59d7vE5+fFzeu5M2xU+x/zjd//996t169bp++fQQw9VzZo1UyUlJbbnx8l+eDu8n+HDh5e7vb0dq5P2urn2qdiP3bNY3vFLmO6f77NatWqpo446Si1YsEA/T0888YTq3bu3K8OcjONK5z0MkkNOGmZ+eC655BJlWZaqXr26OvXUU9Utt9yib9iyPdvoGzEaftDYMPfp02ev+7vyyivVgQceGPnMPcNAIKDmzp1rW+f222/X6yxcuDCmnD9ze1566SVPDPPll18es+4dd9yh356vuOKKmHI21Nw+fslIRpvbtGmjf7TK45prrtEjHb/++qv4ohU+1lQbZtN2hc9x//79Y9Z7//33dfnHH3+clONPtmE2aa+ba5+q/UjPolPDbLr/q6++Wj83/IJZ9gU0mYY5keNK5z0MkkNOqrILCgropZdeot9//50efPBBOuigg+iDDz7Q/uWjjjpKTzUpC4vCotlnn33o+OOPpxkzZsSUv/jii9SlSxeqXr26VkXy8tRTT9Hy5csjam/eV6tWrejQQw+1beO7776r12ndunVMOX9mQQ+Le3bu3BnZR3hhAZsbevbsGfP54IMPpt27d9OJJ54YU37IIYfo41mxYoWjNtvBQjyuP378eFq8eLG4zvTp06lt27bUokWLmPLzzjsv8n06cNqu0047LeZzmzZt9F++R5K5n2Rh0l43196r/Zg8i04x3T9fiw4dOtABBxwQsx5PYXOLF8eVqnsYJIecNMxhGjZsSP3799fGee7cuTRlyhSaPXs2DR48OG7d/fffXyxbv3595DM/HDwF6/TTT9fTVEpKSiJTVfiBCT80f//9d9wDWxZW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VdIjhATfqJxAJZh0H7P8LJj66k2fTbPn3153YiX8O2Ni5MLbchLYwxxulRfbzUFUmvjiiy/4Cqkff/wxUvb444+rihUrqqKiIv05GAyqBQsWqE2bNhnX2RsrV67U28CCc4B7APcA7gH5HuDfyWRRXFys6tatm/C5rlu3rt6Gn7D4f+l6KeCA4dzj5SDiGzdupEGDBtE111wTGXrmucrsQ37hhRfo0ksvNaqzN3jY+6+//qJq1arpOKnc0y47R84vsL/dz8fP+P0c+P34GZyD/52DP/74QyuTORIWa3eSxc6dOxMO2FFYWKiDgPiJtAYYYXn6uHHj6I477tDz0saOHasNbXRotNatW8co6PZWZ2/wzdagQQP973C0l/DcOL/i9+Nn/H4O/H78DM4B6ahaXtwHbFj9Zlyz1jCzHF0KrRaGe7ULFy50VAcAAADIZtIeKxsAAAAA/8PXhpmHwkeOHCmGd/MDfj9+xu/nwO/Hz+Ac4BxkGmkVfwEAAAAgFl/3mAEAAIBMA4YZAAAAyCBgmAEAAIAMIqcNM895Puuss6hbt250++2364AiXtTJVDZt2kQ33XQTnXDCCXTOOefEhTMtC8sNpk6dSn379qXu3bvTlVdeSYsWLaJsZsaMGXT++edT165d6brrrtNpQ035v//7P+rcuTM98cQTlK0UFxfruf4nnnginX766fTyyy8b1fvuu++of//++jm44YYbdDCfbOXHH3/U9zTHSL788stp6dKle63D2YXC902fPn3o/fffp2yFk/i88sorOjgT57I3DcT0+OOP6zo9evSghx9+mEqF8K3AI1SO8swzz6gKFSqohx9+WL311lvq0EMPVccee6wKhUJJrZOp7N69W7e/S5cu6p133lF33323ys/PV1OmTLGtM3ToUHXOOeeoSZMmqWnTpqmrrrpKFRYWqlmzZqls5KOPPtLHPGrUKPXee++pbt26qRYtWqjt27fvte78+fNVw4YN1f7776+GDx+uspXTTjtNHXzwwerNN99UTz31lKpcubK67777yq0zefJk/Rzcdttt6tNPP1VPPPGEOu+881Q2wiF9q1Spou/lDz74QF144YWqVq1a5YacfOCBB1SlSpXUY489po9//PjxKi8vT73yyisqG2nbtq0+7n79+uljN+Gaa65RderUUS+99JK+Hzgs5sCBAz1vK9hDThrm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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "u = pde_solution[\"f_states\"][0, 0] # (n_times, n_interior)\n", - "u_full = jnp.pad(u, ((0, 0), (1, 1))) # add back the fixed zero boundary values\n", - "\n", - "fig, ax = plt.subplots(figsize=(5, 4))\n", - "mesh = ax.pcolormesh(x_full, obs_time, u_full, shading=\"auto\", cmap=\"inferno\")\n", - "fig.colorbar(mesh, ax=ax, label=\"u(t, x)\")\n", - "ax.set_xlabel(\"x\")\n", - "ax.set_ylabel(\"t\")\n", - "ax.set_title(\"Space-time solution of the heat equation\")\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, { "cell_type": "markdown", "id": "f38a891e", @@ -470,7 +419,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 34, "id": "4976ab95", "metadata": {}, "outputs": [ @@ -478,7 +427,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "sample: 100%|██████████| 150/150 [01:32<00:00, 1.62it/s, 3 steps of size 1.06e-01. acc. prob=0.98] \n" + "sample: 100%|██████████| 150/150 [01:29<00:00, 1.67it/s, 3 steps of size 1.06e-01. acc. prob=0.98] \n" ] } ], @@ -500,7 +449,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 37, "id": "3ac31625", "metadata": {}, "outputs": [ diff --git a/docs/tutorials/pde/reaction_diffusion_inference.ipynb b/docs/tutorials/pde/reaction_diffusion_inference.ipynb index 1006948e..38294302 100644 --- a/docs/tutorials/pde/reaction_diffusion_inference.ipynb +++ b/docs/tutorials/pde/reaction_diffusion_inference.ipynb @@ -253,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "4a157038", "metadata": {}, "outputs": [ @@ -303,12 +303,12 @@ "\n", "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. \n", "\n", - "**A note about solvers used for filtering:** the ``ContinuousTimeEnKF`` will integrate the ODE using its own default solver (which assumes the model is an SDE). Here we specify the solver to match the solver used to generate the solution (which is the more accurate, but slower, implicit Euler solver). If this is too slow, try running the ``ContinuousTimeEnKF``with default setting as it yields very similar performance on this particular problem. \n" + "**A note about solvers used for filtering:** the ``ContinuousTimeEnKF`` will integrate the ODE using its own default solver (which assumes the model is really an SDE). Here we specify the solver to match the solver used to generate the solution (which is the more accurate, but slower, implicit Euler solver). If this is too slow, try running the ``ContinuousTimeEnKF``with default setting as it yields very similar performance on this particular problem. \n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "2d4c28ef", "metadata": {}, "outputs": [ From b54b84802d502eafaaaff464bbff6f42e1241575 Mon Sep 17 00:00:00 2001 From: Matthew Levine Date: Thu, 23 Jul 2026 18:59:00 -0400 Subject: [PATCH 07/10] adding notebooks to Examples page --- mkdocs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index a54eca58..f394f25d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,6 +47,9 @@ nav: - Discrete time LTI profile likelihood: deep_dives/discrete_time_lti_profile_likelihood.ipynb - Continuous-time LTI profile likelihood: deep_dives/continuous_time_lti_profile_likelihood.ipynb - GP prior on drift (FitzHugh-Nagumo): deep_dives/gp_drift.ipynb + - PDEs: + - "Heat equation: Inferring an initial condition": tutorials/pde/heat_equation_inference.ipynb + - "Reaction-diffusion equation: Inferring a reaction rate": tutorials/pde/reaction_diffusion_inference.ipynb - API Reference: - api_reference/index.md - Public API: From 13779ff467b7830b5c7816c818ca23d3c344a9b0 Mon Sep 17 00:00:00 2001 From: Matthieu Darcy <68646255+MatthieuDarcy@users.noreply.github.com> Date: Thu, 23 Jul 2026 21:04:01 -0400 Subject: [PATCH 08/10] Update heat_equation_inference.ipynb --- .../pde/heat_equation_inference.ipynb | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/tutorials/pde/heat_equation_inference.ipynb b/docs/tutorials/pde/heat_equation_inference.ipynb index dfb3d010..b02f05b9 100644 --- a/docs/tutorials/pde/heat_equation_inference.ipynb +++ b/docs/tutorials/pde/heat_equation_inference.ipynb @@ -162,7 +162,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "id": "43de3d49", "metadata": {}, "outputs": [], @@ -173,12 +173,11 @@ "obs_noise = 1e-2 # the noise on the observations\n", "\n", "\n", - "\n", "def heat_equation_model(mu=None, obs_times=None, obs_values=None, predict_times=None):\n", " mu = numpyro.sample(\"mu\", dist.Uniform(0, 1), obs=mu)\n", "\n", " # Create the dynamical model with sampled mu\n", - " # Reparameterize the initial condition\n", + " # Reparameterize the initial condition (this will be relevant when running MCMC directly on the model)\n", " standard_x0 = dist.MultivariateNormal(\n", " loc=jnp.zeros(n_interior),\n", " scale_tril=jnp.eye(n_interior),\n", @@ -309,12 +308,26 @@ "# Inferring the initial condition using NUTS through the solver\n", "\n", "We can now run NUTS directly under `ODESimulator`: NUTS backpropagates straight through the PDE solve (\"unrolling\"), the same\n", - "pattern used in the ODE tutorial." + "pattern used in the ODE tutorial.\n", + "\n", + "**A note about reparametrization and the funnel issue in MCMC.**\n", + "\n", + "In the above, we have defined\n", + "$$\n", + "u_0 \\mid \\mu \\sim \\mathcal N\\big(m(\\mu),\\ \\sigma^2 I\\big), \\qquad \\sigma = \\texttt{ic\\_noise} = 10^{-2},\n", + "$$\n", + "with $m(\\mu) = $ `initial_condition(mu)`. Because $\\sigma$ is small, this creates a funnel and MCMC stalls when trying to explore $(\\mu, u_0)$. Instead we reparametrize as\n", + "$$\n", + "z \\sim \\mathcal N(0, I), \\qquad u_0 = m(\\mu) + \\sigma z.\n", + "$$\n", + "Under the prior, $\\mu$ and $z$ are independent: the $\\sigma$-scale coupling is now a fixed deterministic map rather than part of the sampled density, so NUTS explores $(\\mu, z)$ under a far better-conditioned posterior. This is done using `TransformedDistribution(N(0,I), LowerCholeskyAffine(loc=m(\\mu), scale_tril=\\sigma I))` in the model definition plus `TransformReparam` below.\n", + "\n", + "Importantly, this issue is not present when running the Kalman Filter below, as we automatically marginalize over $u_0$, preventing this issue." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "4a157038", "metadata": {}, "outputs": [ @@ -346,10 +359,7 @@ "from numpyro.infer import MCMC, NUTS\n", "from numpyro.handlers import reparam\n", "\n", - "# `f_x_0` (dynestyx's internal initial-state site) is a 62-dim latent tightly coupled to\n", - "# the scalar `mu` via a narrow Gaussian (ic_noise). Sampled directly, this is a funnel:\n", - "# NUTS gets stuck with 0% acceptance regardless of warmup/samples. LocScaleReparam\n", - "# non-centers it (raw ~ N(0,1), f_x_0 = loc + ic_noise * raw), which fixes the geometry.\n", + "# This applies the reparameterization to the initial state latent variable `f_x_0` (dynestyx's internal initial-state site).\n", "reparam_model = reparam(heat_equation_model, config={\"f_x_0\": TransformReparam()})\n", "\n", "with ODESimulator(\n", @@ -419,7 +429,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "id": "4976ab95", "metadata": {}, "outputs": [ @@ -432,6 +442,7 @@ } ], "source": [ + "# note how no reparameterization is used here becauea the KF marginalizes out the initial state\n", "def filtered_parameter_model():\n", " with Filter(\n", " filter_config=ContinuousTimeKFConfig( # the continuous-time Kalman filter.\n", From 7694dcb78b304841436e174f9e796f23148d2151 Mon Sep 17 00:00:00 2001 From: Dan Waxman Date: Fri, 24 Jul 2026 10:32:07 -0400 Subject: [PATCH 09/10] Move to deep_dives; link heat eq notebook --- .../pde/heat_equation_inference.ipynb | 0 .../pde/reaction_diffusion_inference.ipynb | 2 +- mkdocs.yml | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename docs/{tutorials => deep_dives}/pde/heat_equation_inference.ipynb (100%) rename docs/{tutorials => deep_dives}/pde/reaction_diffusion_inference.ipynb (99%) diff --git a/docs/tutorials/pde/heat_equation_inference.ipynb b/docs/deep_dives/pde/heat_equation_inference.ipynb similarity index 100% rename from docs/tutorials/pde/heat_equation_inference.ipynb rename to docs/deep_dives/pde/heat_equation_inference.ipynb diff --git a/docs/tutorials/pde/reaction_diffusion_inference.ipynb b/docs/deep_dives/pde/reaction_diffusion_inference.ipynb similarity index 99% rename from docs/tutorials/pde/reaction_diffusion_inference.ipynb rename to docs/deep_dives/pde/reaction_diffusion_inference.ipynb index 38294302..11ac98b7 100644 --- a/docs/tutorials/pde/reaction_diffusion_inference.ipynb +++ b/docs/deep_dives/pde/reaction_diffusion_inference.ipynb @@ -17,7 +17,7 @@ "metadata": {}, "source": [ "# A second model: non-linear reaction-diffusion equation\n", - "This notebook assumes that you have read the previous on the heat equation. If you are unfamiliar with finite discretization schemes for PDEs, please refer to the previous notebook on the heat equation for a (very) short introduction. We now consider the nonlinear KPP-Fisher reaction diffusion-equation with zero Dirichlet boundary condition:\n", + "This notebook assumes that you have read the previous on the heat equation. If you are unfamiliar with finite discretization schemes for PDEs, please refer to the [previous notebook on the heat equation](../heat_equation_inference) for a (very) short introduction. We now consider the nonlinear KPP-Fisher reaction diffusion-equation with zero Dirichlet boundary condition:\n", "\n", "$$\n", "\\begin{aligned}\n", diff --git a/mkdocs.yml b/mkdocs.yml index f394f25d..f9488ef3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -48,8 +48,8 @@ nav: - Continuous-time LTI profile likelihood: deep_dives/continuous_time_lti_profile_likelihood.ipynb - GP prior on drift (FitzHugh-Nagumo): deep_dives/gp_drift.ipynb - PDEs: - - "Heat equation: Inferring an initial condition": tutorials/pde/heat_equation_inference.ipynb - - "Reaction-diffusion equation: Inferring a reaction rate": tutorials/pde/reaction_diffusion_inference.ipynb + - "Heat equation: Inferring an initial condition": deep_dives/pde/heat_equation_inference.ipynb + - "Reaction-diffusion equation: Inferring a reaction rate": deep_dives/pde/reaction_diffusion_inference.ipynb - API Reference: - api_reference/index.md - Public API: From 42235fc710a613f25d33b94bfa2d8040a57d06a1 Mon Sep 17 00:00:00 2001 From: Dan Waxman Date: Fri, 24 Jul 2026 10:36:05 -0400 Subject: [PATCH 10/10] Capitalization of titles --- docs/deep_dives/pde/heat_equation_inference.ipynb | 12 ++++++------ .../pde/reaction_diffusion_inference.ipynb | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/deep_dives/pde/heat_equation_inference.ipynb b/docs/deep_dives/pde/heat_equation_inference.ipynb index b02f05b9..b00cb7fd 100644 --- a/docs/deep_dives/pde/heat_equation_inference.ipynb +++ b/docs/deep_dives/pde/heat_equation_inference.ipynb @@ -16,7 +16,7 @@ "id": "ee947373", "metadata": {}, "source": [ - "# A quick introduction to modeling dynamical systems driven by partial differential equations\n", + "# An Introduction to Modeling Dynamical Systems Driven by Partial Differential Equations\n", "\n", "Consider a time-dependent function $u(t,x)$ representing the state of some underlying physical system. In many cases, this function is characterized as the solution of a partial differential equation\n", "\n", @@ -51,7 +51,7 @@ "id": "15d89a8d", "metadata": {}, "source": [ - "# A first model: linear heat equation\n", + "# A First Model: Linear Heat Equation\n", "\n", "As a first example, we consider the linear heat equation with zero Dirichlet boundary conditions:\n", "\n", @@ -234,7 +234,7 @@ "id": "de4bfd36", "metadata": {}, "source": [ - "## Generating the solution " + "## Generating the Solution " ] }, { @@ -264,7 +264,7 @@ "id": "7b3d35f1", "metadata": {}, "source": [ - "## Visualizing the solution\n", + "## Visualizing the Solution\n", "\n", "We plot the sampled realization as a space-time heatmap. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." ] @@ -305,7 +305,7 @@ "id": "900d496b", "metadata": {}, "source": [ - "# Inferring the initial condition using NUTS through the solver\n", + "# Inferring the Initial Condition Using NUTS Through the Solver\n", "\n", "We can now run NUTS directly under `ODESimulator`: NUTS backpropagates straight through the PDE solve (\"unrolling\"), the same\n", "pattern used in the ODE tutorial.\n", @@ -386,7 +386,7 @@ "id": "f40db08a", "metadata": {}, "source": [ - "# Inference with the continuous-time Kalman filter\n", + "# Inference With the Continuous-Time Kalman Filter\n", "\n", "Since the discretized `heat_equation` is a linear-Gaussian state-space model, we can a continuous-time Kalman to get the exact densities and use this within MCMC, as an alternative to running MCMC through the simulation. \n", "\n", diff --git a/docs/deep_dives/pde/reaction_diffusion_inference.ipynb b/docs/deep_dives/pde/reaction_diffusion_inference.ipynb index 11ac98b7..c86cdc6f 100644 --- a/docs/deep_dives/pde/reaction_diffusion_inference.ipynb +++ b/docs/deep_dives/pde/reaction_diffusion_inference.ipynb @@ -16,7 +16,7 @@ "id": "e35d5123", "metadata": {}, "source": [ - "# A second model: non-linear reaction-diffusion equation\n", + "# A Second Model: Non-Linear Reaction-Diffusion Equation\n", "This notebook assumes that you have read the previous on the heat equation. If you are unfamiliar with finite discretization schemes for PDEs, please refer to the [previous notebook on the heat equation](../heat_equation_inference) for a (very) short introduction. We now consider the nonlinear KPP-Fisher reaction diffusion-equation with zero Dirichlet boundary condition:\n", "\n", "$$\n", @@ -174,7 +174,7 @@ "id": "de4bfd36", "metadata": {}, "source": [ - "## Generating the solution " + "## Generating the Solution " ] }, { @@ -202,7 +202,7 @@ "id": "7b3d35f1", "metadata": {}, "source": [ - "## Visualizing the solution\n", + "## Visualizing the Solution\n", "\n", "We plot the sampled realization as a space-time heatmap. Since we solved for the interior nodes only, we pad the state back out with the (fixed, zero) Dirichlet boundary values before plotting." ] @@ -243,7 +243,7 @@ "id": "900d496b", "metadata": {}, "source": [ - "# Inferring the reaction rate by running MCMC through the simulator\n", + "# Inferring the Reaction Rate via MCMC Through The Simulator\n", "\n", "`reaction_diffusion_equation_model` is fully deterministic given `r` (no process noise, small-noise Gaussian\n", "observation model), so we run NUTS directly under `ODESimulator`: NUTS backpropagates\n", @@ -299,7 +299,7 @@ "id": "5af136da", "metadata": {}, "source": [ - "# Inference with the continuous time Ensemble Kalman filter\n", + "# Inference with the Continuous Time Ensemble Kalman filter\n", "\n", "Similarly, we can run a continuous time Ensemble Kalman filter as an alternative to running MCMC through the simulation. \n", "\n",