Heat kernel¶
Empirical and analytic heat kernel on the unit sphere, for comparing a simulated distribution against the exact answer.
This module needs SciPy, which the numpy-only core install does not pull in,
so it is deliberately not re-exported at the top level. ww.heat_kernel will
not resolve. Import it by path:
See the heat kernel tutorial for a worked
comparison, and note the generator convention discussed there: this project
uses (1/2) Laplacian, so the spectral expansion carries exp(-l(l+1)t/2).
Empirical and theoretical heat kernel on the unit sphere S^2.
Estimates the heat kernel two ways so they can be compared: empirically, by running many Brownian paths and applying a kernel density estimate with the sphere's Riemannian volume normalization, and analytically, from the Legendre spectral expansion.
This module needs SciPy, which ships in the notebooks extra rather than
the numpy-only core install, so it is deliberately not re-exported from
wanderwalk/__init__.py. Import it explicitly:
from wanderwalk.heat_kernel import estimate_heat_kernel
estimate_heat_kernel ¶
Runs 2000 Brownian paths from the north pole and samples four times.
Each path starts at (0, 0, 1) and is advanced one step at a time with
Sphere.euler_maruyama_step at dt = 0.01 for 200 steps. Positions
are recorded at steps 10, 50, 100, and 200, which correspond to times
0.1, 0.5, 1.0, and 2.0.
This is deliberately a single-particle loop rather than a call to
sphere_simulator, so the samples come from the same stepping code the
manifold exposes. It takes a few seconds to run.
Returns:
| Type | Description |
|---|---|
|
A (2000, 4, 3) array of positions on the sphere, indexed by path, |
|
|
then by time (0.1, 0.5, 1.0, 2.0), then by Cartesian coordinate. |
Source code in src/wanderwalk/heat_kernel.py
estimate_density ¶
Estimates the empirical heat kernel density at one sampled time.
Fits a Gaussian kernel density estimate to the sampled positions in ambient R^3, evaluates it on a 50 by 50 grid in spherical coordinates, then renormalizes by the sphere's area element sin(theta) d(theta) d(phi) so the result integrates to 1 over the surface rather than over R^3.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
samples
|
A (paths, times, 3) array as returned by estimate_heat_kernel. |
required | |
time_index
|
Which of the sampled times to estimate, indexing the second axis of samples. With estimate_heat_kernel's defaults, 0, 1, 2, and 3 mean t = 0.1, 0.5, 1.0, and 2.0. |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple (theta_grid, phi_grid, normalized_density, dtheta, dphi). |
|
|
theta_grid is 50 polar angles over [0, pi] and phi_grid is 50 |
|
|
azimuthal angles over [0, 2*pi); normalized_density is the |
|
|
(50, 50) density over that grid, indexed as [theta, phi]; dtheta |
|
|
and dphi are the grid spacings, returned so callers can integrate |
|
|
the density without recomputing them. |
Source code in src/wanderwalk/heat_kernel.py
estimate_theoretical_heat_kernel ¶
Evaluates the analytic heat kernel on S^2 from its Legendre expansion.
The heat kernel from the north pole depends only on the polar angle, and has the spectral expansion
p(t, theta) = (1/4*pi) * sum_l (2l+1) exp(-l(l+1)t/2) P_l(cos theta)
where P_l is the Legendre polynomial of degree l and l(l+1) is the eigenvalue of the Laplace-Beltrami operator on the sphere. The sum is truncated at l = 50. The exponential decay makes that ample for the times sampled by estimate_heat_kernel, but the series converges slowly as t approaches 0, where many more terms would be needed.
The factor of 1/2 in the exponent is the generator convention this project uses throughout: Brownian motion is the diffusion generated by (1/2)*Laplacian, not the Laplacian (see ONBOARDING.md). Sources that state this expansion as exp(-l(l+1)t) are using the other convention, and their t is half of this one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
theta_grid
|
Polar angles over [0, pi], as returned by estimate_density. |
required | |
phi_grid
|
Azimuthal angles over [0, 2*pi), as returned by estimate_density. Used only to set the output shape, since the kernel is symmetric about the axis through the starting point. |
required | |
t
|
The time at which to evaluate the kernel. |
required |
Returns:
| Type | Description |
|---|---|
|
A (len(theta_grid), len(phi_grid)) array of density values, indexed |
|
|
as [theta, phi] to match estimate_density's output. |