Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Sparse-grid quadrature

The question this method answers

How can we integrate a smooth function of several variables without paying the full cost of a high-order tensor product? Sparse grids replace one large Cartesian rule by a structured sum of smaller tensor increments. They are most useful when the integrand has mixed smoothness or when only a few coordinate directions need high resolution.

Why tensor products become expensive

Suppose a one-dimensional rule uses (n) nodes. Its (d)-dimensional tensor product uses

Ntensor=ndN_{\mathrm{tensor}}=n^d

nodes. This is appropriate when every direction needs the same resolution, but it becomes wasteful when most high-order interactions contribute little. Sparse grids organize the calculation by incremental resolution instead.

Build a hierarchy in one dimension

Let (Q_{\ell}) be the nested Clenshaw-Curtis rule at level (\ell). Jaxstro uses the midpoint as the base rule,

Q1[f]=f(12),Q_1[f]=f\left(\frac{1}{2}\right),

and uses (2^{\ell-1}+1) Clenshaw-Curtis nodes for (\ell\geq 2). Define the hierarchical difference

Δ=QQ1,Q0=0.\Delta_{\ell}=Q_{\ell}-Q_{\ell-1}, \qquad Q_0=0.

The telescoping identity

QL==1LΔQ_L=\sum_{\ell=1}^{L}\Delta_{\ell}

shows why the differences are useful: each (\Delta_{\ell}) asks what changed when one more resolution level was introduced.

Lift the hierarchy to several dimensions

For a multi-index (\boldsymbol{\ell}=(\ell_1,\ldots,\ell_d)), define

Δ=Δ1Δd.\Delta_{\boldsymbol{\ell}} = \Delta_{\ell_1}\otimes\cdots\otimes\Delta_{\ell_d}.

A downward-closed index set (\mathcal{I}) produces the Smolyak formula

AI[f]=IΔ[f].A_{\mathcal{I}}[f] = \sum_{\boldsymbol{\ell}\in\mathcal{I}} \Delta_{\boldsymbol{\ell}}[f].

Downward closure means that whenever (\boldsymbol{\ell}\in\mathcal{I}) and (\ell_j>1), the immediate predecessor (\boldsymbol{\ell}-\boldsymbol{e}_j) also belongs to (\mathcal{I}). The formula never claims a high-resolution interaction without including the lower-resolution information on which it depends.

Fixed isotropic and anisotropic sets

Smolyak(level=L) uses the isotropic set

j=1d(j1)L1.\sum_{j=1}^{d}(\ell_j-1)\leq L-1.

Static positive anisotropy weights (w_j) change the budget to

j=1dwj(j1)L1.\sum_{j=1}^{d}w_j(\ell_j-1)\leq L-1.

A larger (w_j) makes refinement along axis (j) more expensive. These weights are algorithm configuration, not differentiable scientific parameters.

Let the frontier choose the next direction

AdaptiveSmolyak begins with a downward-closed set and considers admissible forward neighbors. A candidate is admissible only after every valid immediate backward neighbor has been accepted. Its selection profit is

P=Δ[f]max(1,ΔN),P_{\boldsymbol{\ell}} = \frac{ \left\|\Delta_{\boldsymbol{\ell}}[f]\right\| }{ \max\left(1,\Delta N_{\boldsymbol{\ell}}\right) },

where (\Delta N_{\boldsymbol{\ell}}) is the number of genuinely new nodes. The largest profit is selected, with lexicographic tie breaking for determinism.

The reported stopping evidence is the active-frontier surplus sum,

Efrontier=FΔ[f].E_{\mathrm{frontier}} = \sum_{\boldsymbol{\ell}\in\mathcal{F}} \left\|\Delta_{\boldsymbol{\ell}}[f]\right\|.

Reuse nested nodes exactly

Clenshaw-Curtis nodes can recur at several levels and in several tensor increments. Jaxstro identifies each one-dimensional node by its reduced integer dyadic-angle identity before a floating coordinate is constructed. A multidimensional node identity is the tuple of those axis identities.

This gives three auditable properties:

  1. repeated mathematical nodes are evaluated once;

  2. work counts report unique physical evaluations; and

  3. node reuse does not depend on approximate floating-point equality.

Use the public API

import jax.numpy as jnp

from jaxstro import quad

domain = quad.Hyperrectangle(jnp.zeros(4), jnp.ones(4))

fixed = quad.integrate(
    lambda x: jnp.exp(-jnp.sum(x, axis=-1)),
    domain,
    method=quad.Smolyak(level=5),
    epsabs=1.0e-8,
    epsrel=1.0e-8,
    max_evaluations=4096,
    max_indices=1024,
    max_frontier=1024,
    max_nodes=4096,
    gradient="stop",
)

adaptive = quad.integrate(
    lambda x: jnp.exp(-8.0 * x[:, 0]),
    domain,
    method=quad.AdaptiveSmolyak(initial_level=1),
    epsabs=1.0e-8,
    epsrel=1.0e-8,
    max_evaluations=512,
    max_indices=8,
    max_frontier=33,
    max_nodes=512,
    gradient="stop",
)

max_indices, max_frontier, and max_nodes are distinct static capacities. max_evaluations is the logical integrand-evaluation budget. For adaptive integration, the declared frontier capacity must satisfy

Nfrontier,max1+dNindices,max.N_{\mathrm{frontier,max}} \geq 1+dN_{\mathrm{indices,max}}.

Astrophysical research patterns

Sparse grids are a strong candidate when a deterministic integral has a small to moderate number of continuous nuisance dimensions:

For example, an extinction-sensitive selection function may vary sharply with one dust coordinate but slowly with several calibration coordinates. Dimension-adaptive profit can discover that imbalance instead of refining every tensor direction equally.

What has been validated

The B2 gate checks analytic product, exponential, rotated-quadratic, localized Gaussian, and strongly anisotropic integrands. Fixed-grid truth checks cover dimensions (2), (4), (8), and (16) where declared by each case. Adaptive dimension-(16) evidence is deliberately anisotropic; it is not a claim that every smooth sixteen-dimensional integral is cheap.

The current methods support eager execution, jax.jit, and jax.vmap in gradient="stop" mode for real, array, and complex payloads. Replay derivatives, quantity certification, backend-wide performance claims, and cross-method memory optimization remain Phase B4 work.

Audit a sparse-grid result

Record at least:

The implementation and validation contracts are linked from the quadrature API page.