Source code for pypomp.functional.pmcmc

"""
Pure-functional PMCMC entry point.

This is a thin wrapper around :func:`pypomp.core.algorithms.pmcmc._vmapped_pmcmc_internal`
that takes a compiled :class:`pypomp.functional.structs.PompStruct` and runs
``n_chains`` independent PMCMC chains in parallel via ``jax.vmap``.
"""

from typing import Callable

import jax

from .structs import PompStruct
from ..core.algorithms.pmcmc import _vmapped_pmcmc_internal
from ..core.algorithms.types import PmcmcConfig, PmcmcInputs


[docs] def pmcmc( struct: PompStruct, thetas_array: jax.Array, proposal, dprior: Callable, M: int, J: int, thresh: float, keys: jax.Array, ) -> tuple[jax.Array, jax.Array, jax.Array, jax.Array]: """ Functional PMCMC entry point. Runs ``n_chains`` independent particle-MCMC chains in parallel. Each chain starts at the corresponding row of ``thetas_array`` using the corresponding PRNG key in ``keys``. Intended for users who need to compose PMCMC inside larger JAX programs; see :meth:`pypomp.core.pomp.Pomp.pmcmc` for a higher-level interface. Parameters ---------- struct : PompStruct Compiled POMP model (see :class:`PompStruct`). thetas_array : jax.Array Starting parameter vectors, shape ``(n_chains, d)``. proposal Proposal object (see :mod:`pypomp.proposals`). Shared across chains; per-chain state is initialised internally. dprior : Callable Log-prior density. Pure JAX function with signature ``dprior(theta_arr) -> scalar``. M : int Number of MCMC iterations per chain. J : int Number of particles per filter evaluation. thresh : float Adaptive resampling threshold for the particle filter. keys : jax.Array PRNG keys, shape ``(n_chains, ...)``. Returns ------- tuple[jax.Array, jax.Array, jax.Array, jax.Array] Tuple ``(loglik_traces, log_prior_traces, theta_traces, accepts)``: * ``loglik_traces``: shape ``(n_chains, M + 1)``. * ``log_prior_traces``: shape ``(n_chains, M + 1)``. * ``theta_traces``: shape ``(n_chains, M + 1, d)``. * ``accepts``: shape ``(n_chains,)`` -- count of accepted proposals per chain. """ if struct.dmeas_pf is None: raise ValueError("PMCMC requires struct.dmeas_pf to be non-None.") config = PmcmcConfig.from_pmcmc_struct( struct=struct, M=M, J=J, dprior=dprior, thresh=thresh, should_trans=False, ) inputs = PmcmcInputs.from_pmcmc_struct(struct) return _vmapped_pmcmc_internal( thetas_array, proposal, config, inputs, keys, )