Metadata-Version: 2.4
Name: sequince
Version: 0.1.0
Summary: Modular, composable Sequential Monte Carlo framework.
Author: Michael J. Williams, Christian Chapman-Bird
License: MIT License
        
        Copyright (c) 2024 Michael J. Williams
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://sequince.readthedocs.io/en/latest/
Project-URL: Repository, https://github.com/sequince-dev/sequince
Project-URL: Documentation, https://sequince.readthedocs.io/en/latest/
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: acai-control>=0.1.0
Requires-Dist: scipy>=1.16
Requires-Dist: matplotlib>=3.5
Requires-Dist: numpy>=1.25.2
Requires-Dist: array-api-compat>=1.13
Requires-Dist: array-api-extra>=0.10
Requires-Dist: optree>=0.19
Requires-Dist: orng>=0.2.1
Provides-Extra: minipcn
Requires-Dist: minipcn>=0.3.0a1; extra == "minipcn"
Provides-Extra: jax
Requires-Dist: jax>0.5.3; extra == "jax"
Requires-Dist: jaxlib; extra == "jax"
Provides-Extra: blackjax
Requires-Dist: blackjax>=1.2; extra == "blackjax"
Provides-Extra: emcee
Requires-Dist: emcee>=3.0; extra == "emcee"
Provides-Extra: eryn
Requires-Dist: eryn>=1.2.6; extra == "eryn"
Requires-Dist: numpy<2.4; extra == "eryn"
Provides-Extra: corner
Requires-Dist: corner; extra == "corner"
Provides-Extra: hdf5
Requires-Dist: h5py>=3; extra == "hdf5"
Dynamic: license-file

# sequince

Sequince is a modular Sequential Monte Carlo (SMC) library for Bayesian inference,
particle filtering, and related sequential methods.

## Installation

`sequince` targets Python 3.11+ and can be installed directly from PyPI:

```bash
pip install sequince
```

## Features

- Array API support for NumPy, JAX, PyTorch, and CuPy backends.
- Compose SMC pipelines from reusable weighting, resampling, mutation, and control steps.
- Prebuilt pipelines with `make_standard_bayesian_smc` and other pre-built recipes.
- Analyse runs via `SMCResult`, including posterior resampling and diagnostics helpers.
- Estimate Bayesian evidence alongside posterior sampling.
- Save checkpoints and resume sampling runs.

## Quick start

Below, we show a short example of how to use `sequince`, for more detailed examples,
see the [documentation](https://sequince.readthedocs.io).

Here, we fit a straight line, `y = slope * x + intercept`, to synthetic data with
independent Gaussian measurement errors and uniform priors on both parameters.
The log-prior and log-likelihood callbacks accept particles shaped
`(n_particles, n_parameters)` and return one log density per particle.

```python
import numpy as np
from sequince import ParticleState, make_standard_bayesian_smc


def log_prior(theta, context):
    """Uniform log-prior"""
    # log-prior and -likelihood can optionally accept context to access shared data.
    lower, upper = context.shared["bounds"]
    inside = np.all((theta >= lower) & (theta <= upper), axis=-1)
    log_density = -theta.shape[-1] * np.log(upper - lower)
    return np.where(inside, log_density, -np.inf)


def log_likelihood(theta, context):
    """Gaussian log-likelihood"""
    x = context.shared["x"]
    y = context.shared["y"]
    sigma = context.shared["sigma"]
    slope = theta[..., 0, None]
    intercept = theta[..., 1, None]
    residual = (y - (slope * x + intercept)) / sigma
    return -0.5 * np.sum(
        residual**2 + np.log(2 * np.pi * sigma**2), axis=-1
    )


# Construct the runner
# `smc` is the main runner
# `posterior` contains definitions of the tempered posterior
# `metadata` contains metadata passed between the SMC steps
smc, posterior, metadata = make_standard_bayesian_smc(
    log_prior,
    log_likelihood,
)

rng = np.random.default_rng(42)

# Generate observations with true slope 2 and intercept 1.
x = np.linspace(-1, 1, 20)
sigma = 0.5
y = 2 * x + 1 + rng.normal(scale=sigma, size=x.shape)

bounds = [-5, 5]

# Draw initial (slope, intercept) particles from the prior.
n = 1000
initial_particles = rng.uniform(*bounds, size=(n, 2))
# Construct the initial state
initial_state = ParticleState(particles=initial_particles)

# Construct the shared context dictionary that will be exposed to the log_prior
# and log_likelihood
shared_context = dict(bounds=bounds, x=x, y=y, sigma=sigma)

# Run the SMC
results = smc.run(
    initial_state,
    rng=rng,
    shared_context=shared_context,
    metadata=metadata,
)

# Obtain equal-weight posterior samples and their weights
samples, sample_weights = results.posterior_samples(
    rng=rng, method="rejection"
)

# Compare the posterior means with the true slope 2 and intercept 1.
mean_slope, mean_intercept = np.average(
    samples, weights=sample_weights, axis=0
)
print(f"Posterior mean slope: {mean_slope:.2f}")
print(f"Posterior mean intercept: {mean_intercept:.2f}")
```

See the [documentation](https://sequince.readthedocs.io) for details on the
different components (shared context, metadata, results), composing custom pipelines and implementing additional steps.

## Documentation

Full documentation is maintained in the `docs/` directory and published to Read
the Docs: <https://sequince.readthedocs.io>

## Examples

The [`sequince-examples`](https://github.com/sequince-dev/sequince-examples)
repository and corresponding documentation contain examples highlighting
different features in `sequince`.

## Contributing

Bug reports, feature requests, and pull requests are welcome via the GitHub
repository. Please see the [contributing guidelines](https://github.com/sequince-dev/sequince/blob/main/CONTRIBUTING.md)
and [AI policy](https://github.com/sequince-dev/sequince/blob/main/AI_POLICY.md).


## Related repositories

The following repositories are part of the `sequince` ecosystem:

- [`sequince-density`](https://github.com/sequince-dev/sequince-density): provides density estimators for `sequince`, supporting preconditioned SMC and ASPIRE-style analyses
- [`sequince-bilby`](https://github.com/sequince-dev/sequince-bilby): provides an interface for using prebuilt `sequince` samplers with `bilby`
- [`orng`](https://github.com/sequince-dev/orng): provides cross-backend random number generation
- [`acai`](https://github.com/sequince-dev/acai): provides array-API compatible control flow and iteration


## License

Licensed under the [MIT License](LICENSE).
