From 544e9cf1ea3609f2ca5034efd9b7459fa67a32f9 Mon Sep 17 00:00:00 2001 From: "Michael J. Williams" Date: Thu, 22 Oct 2026 16:50:45 +0200 Subject: [PATCH 1/2] DOC: add basic documentation and contributing guidelines --- .gitignore | 2 +- .readthedocs.yaml | 14 ++ CONTRIBUTING.md | 340 ++++++++++++++++++++++++++ README.md | 6 +- docs/Makefile | 20 ++ docs/conf.py | 54 ++++ docs/developer_guide/CONTRIBUTING.rst | 2 + docs/developer_guide/index.rst | 19 ++ docs/examples.rst | 11 + docs/gaussian_mixtures.rst | 36 +++ docs/index.rst | 42 ++++ docs/installation.rst | 34 +++ docs/normalizing_flows.rst | 47 ++++ docs/proposals.rst | 32 +++ docs/requirements.txt | 4 + pyproject.toml | 18 ++ 16 files changed, 677 insertions(+), 4 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 CONTRIBUTING.md create mode 100644 docs/Makefile create mode 100644 docs/conf.py create mode 100644 docs/developer_guide/CONTRIBUTING.rst create mode 100644 docs/developer_guide/index.rst create mode 100644 docs/examples.rst create mode 100644 docs/gaussian_mixtures.rst create mode 100644 docs/index.rst create mode 100644 docs/installation.rst create mode 100644 docs/normalizing_flows.rst create mode 100644 docs/proposals.rst create mode 100644 docs/requirements.txt diff --git a/.gitignore b/.gitignore index d99a8b0..721af4f 100644 --- a/.gitignore +++ b/.gitignore @@ -119,7 +119,7 @@ ipython_config.py # pixi # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. -# pixi.lock +pixi.lock # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one # in the .venv directory. It is recommended not to include this directory in version control. .pixi diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..2bf35dc --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,14 @@ +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "3.13" + +python: + install: + - requirements: docs/requirements.txt + +sphinx: + configuration: docs/conf.py + fail_on_warning: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c8715f0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,340 @@ +# Contributing to sequince-density + +Contributions to sequince-density are welcome, including bug reports, tests, +performance improvements, and new density estimators and flow adapters. This guide describes the development +workflow and conventions we use to keep changes easy to review and maintain. + +## Community and responsibility + +Treat other contributors with respect and follow the +[Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/). +Contributions must comply with the project's +[license](https://github.com/sequince-dev/sequince-density/blob/main/LICENSE). Preserve required +attribution when incorporating third-party material. + +AI-assisted contributions are welcome under our +[AI policy](https://github.com/sequince-dev/sequince/blob/main/AI_POLICY.md). +Contributors are responsible for understanding, validating, and explaining their +changes, including their numerical correctness and performance. + +## Scope of contributions + +Keep each pull request focused on one problem or a closely related set of changes. +Discuss substantial API changes, new dependencies, or new algorithms in an issue +before investing significant implementation effort. Small fixes can go directly +to a pull request. + +sequince-density provides fitted proposal distributions and normalizing-flow +adapters for Sequince. Core sampling algorithms belong in Sequince; +application-specific likelihoods and workflows belong in downstream packages. +Prefer existing interfaces and helpers; introduce abstractions when they simplify +the implementation or serve a concrete shared need. Avoid unrelated cleanup in +bug fixes and feature changes. + +## Development setup + +Fork [sequince-dev/sequince-density](https://github.com/sequince-dev/sequince-density) on GitHub, +then clone your fork and configure local `main` to track `upstream/main`: + +```bash +git clone git@github.com:YOUR_USERNAME/sequince-density.git +cd sequince-density +git remote add upstream https://github.com/sequince-dev/sequince-density.git +git fetch upstream +git switch main +git branch --set-upstream-to=upstream/main main +``` + +Keep local `main` for upstream changes and do development on separate branches. +Before starting each contribution, update `main` and create a branch: + +```bash +git switch main +git pull --ff-only +git switch -c fix-descriptive-name +``` + +Here, `upstream` is the sequince-density repository and `origin` is your fork. The tracking +setting makes `git pull --ff-only` on `main` fetch from upstream. Push contribution +branches explicitly to `origin`, as shown in the pull request instructions below. + +Create a Python 3.11 or later virtual environment and install the package with +its development dependencies: + +```bash +python -m venv .venv +source .venv/bin/activate +python -m pip install --upgrade pip +python -m pip install -e . --group dev +pre-commit install +``` + +The `dev` dependency group includes the test dependencies for scikit-learn, +Zuko/PyTorch, and FlowJAX/JAX, plus pre-commit and mypy. The editable installation +makes source changes available without reinstalling the package. Dependencies +and tool configuration are defined in `pyproject.toml`. + +When developing against a local Sequince checkout, install it first, for example +with `python -m pip install -e ../sequince`, before installing sequince-density. +CI also installs Sequince from a checkout before running the tests. + +Use Pixi for the documentation environment, as described below. Generated lock +files and local environments should stay out of pull requests. + +## Code style + +- Follow the existing module's conventions and use Ruff for formatting and import + ordering. Python code uses four-space indentation and a 79-character line limit. +- Use descriptive names. Conventional mathematical names are appropriate when + their meaning is clear locally. +- Document public functions and classes with NumPy-style docstrings, including + array shapes, return values, and important assumptions where relevant. +- Use comments to explain numerical reasoning, constraints, and non-obvious + choices. Avoid comments that simply restate the code. +- Preserve supported array backends, devices, and dtypes. Use the existing array + helpers and RNG interfaces rather than introducing implicit NumPy conversions + or global random state. +- Keep eager and functional behavior consistent where both are supported. Keep + host scalar conversions outside compiled operations and validate results at + appropriate boundaries. +- Avoid unnecessary array copies, repeated target evaluations, and retention of + unused histories. Expensive diagnostics and logging should not add work when + disabled. Support performance claims with reproducible measurements. + +## Typing + +Add parameter and return annotations to new functions and methods, including +private helpers and tests where practical. When changing an existing interface, +update its annotations and affected callers together. Annotate stored attributes +when their types are not clear from initialization. + +- Use modern Python syntax supported by Python 3.11, such as `list[str]`, + `dict[str, float]`, and `ParticleState | None`. Prefer collection interfaces + such as `Mapping` or `Sequence` when callers need not supply a concrete container. +- Use the existing `Array` and `ArrayLike` aliases from `sequince.typing` for + backend-neutral numerical interfaces. Reserve backend-specific types such as + `numpy.ndarray` for code that requires that backend. Use `ArrayLike` only when + the function actually accepts and converts those inputs. +- Describe array shapes, dtype restrictions, and scalar-versus-batch behavior in + docstrings. An `Array` annotation alone does not express these constraints; + validate them at appropriate runtime boundaries. +- Give callbacks explicit signatures and reuse existing protocols and type + aliases. Prefer a precise union or protocol to `Any` when the accepted values + have a known contract. Keep `Any` limited to genuinely dynamic interfaces. +- Use `TYPE_CHECKING` for annotation-only imports when needed to avoid import + cycles or loading optional dependencies. Ensure annotations do not introduce + new runtime dependency requirements. +- Treat `cast` and `# type: ignore[error-code]` as exceptions. Keep them narrowly + scoped and explain non-obvious reasons; neither replaces runtime validation. + Fix inaccurate annotations instead of broadly suppressing errors. + +The pre-commit hooks run mypy using the configuration in `pyproject.toml`. +For a standalone type check during development, use `python -m mypy`. +Passing type checks complements numerical and runtime tests; it does not replace +them. + +### Docstring example + +Include types in NumPy-style docstrings even when the signature is annotated. +Keep both consistent, and use the docstring to explain shapes, constraints, and +meaning. Use `array` for backend-native arrays and `array_like` only when the +function also accepts and converts inputs such as lists. + +```python +from sequince.typing import Array +from sequince.array_api import namespace + + +def particle_mean(particles: Array) -> Array: + """Compute the unweighted mean of a particle population. + + Parameters + ---------- + particles : array, shape (n_particles, n_dimensions) + Floating-point particle coordinates. The population must be nonempty. + + Returns + ------- + mean : array, shape (n_dimensions,) + Arithmetic mean along the particle axis, using the input array backend. + """ + xp = namespace(particles) + return xp.mean(particles, axis=0) +``` + +## Building the documentation + +The documentation uses Sphinx and lives in `docs/`. From the repository root, +build the HTML documentation with the dedicated Pixi environment: + +```bash +pixi run -e docs docs +``` + +Pixi installs the documentation dependencies defined in `pyproject.toml` when +preparing this environment. Open `docs/_build/html/index.html` in a browser to +review the result. Rebuild after editing documentation or API docstrings. + +With Sphinx available in your environment, the standard Makefile also supports: + +```bash +make -C docs html +make -C docs clean +``` + +Run `make -C docs help` to list available targets. Use `SPHINXOPTS` to pass +additional options, for example `make -C docs html SPHINXOPTS=-W`. + +The developer guide embeds this file using MyST and links to the shared +[Sequince AI policy](https://github.com/sequince-dev/sequince/blob/main/AI_POLICY.md). +Edit this root Markdown file to update the guidelines on GitHub and in the +documentation. + +## Checks and tests + +Run the following checks before requesting review: + +```bash +pre-commit run --all-files +python -m pytest tests/ +``` + +Pre-commit covers Ruff linting and formatting, mypy type checking, spelling, +whitespace, YAML validation, and large-file checks. It does not run the test +suite, so run pytest separately with `python -m pytest tests/`. + +Pre-commit may modify files to fix formatting or other issues. Review those +changes, stage the relevant files, and rerun the checks before committing. +Configuration in `.pre-commit-config.yaml` and `pyproject.toml` is authoritative. + +Tests use pytest and live in `tests/`, including tests of integration with +Sequince proposal and transform interfaces. Follow the existing test layout, fixtures, and +parameterization. During development, run the relevant file or individual test: + +```bash +python -m pytest tests/test_gmm.py +python -m pytest tests/test_gmm.py -k reproducible +``` + +Add regression tests for bug fixes and tests for new behavior. Test observable +outcomes and numerical invariants rather than implementation details. Use fixed +RNG seeds and justified numerical tolerances for stochastic tests. Cover relevant +edge cases, such as zero support, degenerate weights, particle shapes, and dtype +precision. Changes to checkpointing should exercise save/resume behavior; changes +to sampling algorithms should include checks against a known target. + +For changes affecting a particular backend, run its tests explicitly: + +```bash +python -m pytest tests/test_gmm.py +python -m pytest tests/test_zuko.py +python -m pytest tests/test_flowjax.py +``` + +The development dependencies install all three density backends. GPU testing +requires a compatible PyTorch or JAX installation and hardware. Report the +backends, devices, and dtypes tested, along with any skips or unavailable +backends. A skipped backend test does not verify that backend. + +## Commit messages + +Use uppercase SciPy-style prefixes with optional parenthesized scopes for commit +subjects and pull request titles: + +```text +PREFIX(scope): short imperative summary +PREFIX: short imperative summary +PREFIX/PREFIX(scope): short imperative summary +``` + +The scope identifies the affected module or area, such as `gmm`, `zuko`, +or `flowjax`. Start it with a lowercase letter and use only lowercase letters, +digits, dots, underscores, or hyphens. Keep it short, and omit it when the change +spans the project or a scope would add little information. + +Choose the prefix that best describes the change: + +| Prefix | Use | +| --- | --- | +| `BUG` | Fix incorrect behavior | +| `ENH` | Add or extend functionality | +| `PERF` | Improve runtime or memory use without changing intended behavior | +| `API` | Change a public interface or introduce an incompatibility | +| `DEP` | Deprecate functionality | +| `MAINT` | Refactor or maintain code without changing intended behavior | +| `TST` | Add or improve tests | +| `DOC` | Update documentation | +| `BLD` | Change packaging, dependencies, or build configuration | +| `CI` | Change continuous integration workflows | +| `REL` | Prepare or maintain a release | +| `STY` | Make formatting-only changes | + +Use `BUG` consistently for bug fixes rather than alternating with `FIX`. A bug fix +that includes a regression test still uses `BUG`; choose the prefix for the main +purpose of the change. + +Use one prefix by default, or two separated by `/` when both describe the change, +for example `MAINT/PERF(resampling): avoid duplicate reductions`. The optional +scope follows both prefixes. More than two prefixes are not supported. + +Keep the subject concise, preferably within 72 characters, and omit its trailing +period. Keep the prefix uppercase and start the summary after `: ` with a +lowercase letter. Use imperative wording such as "guard", "add", or "avoid". +When useful, add a blank line and a body explaining the problem, the resulting +behavior, and any important tradeoffs. Reference related issues; use +`Closes #123` only when the change fully resolves that issue. + +Examples: + +```text +BUG(gmm): reject nonuniform fitting weights + +The scikit-learn mixture fit does not support sample weights. Reject +nonuniform weights explicitly and add a regression test for this case. +``` + +```text +PERF(gmm): reduce copies during density evaluation +DOC: clarify contribution guidelines +REL: prepare release 0.1.0 +``` + +Make commits in coherent units. Pull requests are squash-merged, so their titles +should also follow this format and describe the final change. + +## Pull requests and review + +Push your branch and open a pull request targeting `sequince-dev/sequince-density:main`: + +```bash +git push --set-upstream origin fix-descriptive-name +``` + +Use a draft pull request for work in progress or early feedback. In the description: + +- Explain the problem and resulting behavior, and link related issues. +- Describe relevant API changes, numerical assumptions, and compatibility effects. +- Summarize validation, including test commands and results. Include reproducible + benchmark conditions for performance changes. + +Respond to reviewer feedback and keep the description aligned with the final +implementation. Reviewers should distinguish required changes from suggestions, +explain their reasoning, and raise unrelated findings in separate issues. + +Maintainers should wait for applicable CI checks and review discussions to be +resolved before merging. Check the squash commit title and message, link or close +resolved issues, and delete merged branches in the main repository when no longer +needed. + +## Releases + +Releases are coordinated by maintainers. Versions are derived from Git tags by +`setuptools-scm`; do not maintain a separate hard-coded version number. Use tags +such as `v0.1.0` and release notes describing user-visible changes and any +incompatibilities. + +Before publishing, verify the intended commit, applicable CI results, and the +built distribution in a clean environment. Publishing a GitHub release triggers +the PyPI workflow in `.github/workflows/publish.yml`. Check that the workflow +completes successfully. Published distributions cannot be overwritten, so verify +the tag and artifacts before publishing. diff --git a/README.md b/README.md index ba860ae..8563192 100644 --- a/README.md +++ b/README.md @@ -117,8 +117,8 @@ Full proposal examples will be linked here once published in ## Documentation -See the [sequince density documentation](https://sequince.readthedocs.io/projects/sequince-density) for the SMC -framework and its proposal and transform interfaces. +See the [sequince density documentation](https://sequince.readthedocs.io/projects/sequince-density/en/latest/) for installation, +density fitting, and integration with Sequince proposals and transforms. ## Examples @@ -129,7 +129,7 @@ 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) +repository. Please see the [contributing guidelines](CONTRIBUTING.md) and [AI policy](https://github.com/sequince-dev/sequince/blob/main/AI_POLICY.md). diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..dc033ba --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation. +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..cc1a4ae --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,54 @@ +"""Sphinx configuration for the sequince-density documentation.""" + +from __future__ import annotations + +from datetime import datetime +from importlib import metadata + +project = "sequince-density" +copyright = f"{datetime.now():%Y}, Sequince Developers" +author = "Sequince Developers" + +try: + release = metadata.version("sequince-density") +except metadata.PackageNotFoundError: + release = "dev" +version = release + +extensions = [ + "autoapi.extension", + "myst_parser", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "sphinx.ext.intersphinx", +] + +autodoc_typehints = "description" +napoleon_google_docstring = False +napoleon_numpy_docstring = True +napoleon_use_ivar = True + +# Generate API pages without importing optional density backends. +autoapi_dirs = ["../src/sequince_density"] +autoapi_add_toctree_entry = False +autoapi_options = [ + "members", + "undoc-members", + "show-inheritance", + "show-module-summary", +] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +intersphinx_mapping = { + "sequince": ("https://sequince.readthedocs.io/en/latest/", None), + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy/", None), +} + +html_theme = "sphinx_book_theme" +html_theme_options = { + "repository_url": "https://github.com/sequince-dev/sequince-density", + "use_repository_button": True, + "use_fullscreen_button": False, +} diff --git a/docs/developer_guide/CONTRIBUTING.rst b/docs/developer_guide/CONTRIBUTING.rst new file mode 100644 index 0000000..7a661a3 --- /dev/null +++ b/docs/developer_guide/CONTRIBUTING.rst @@ -0,0 +1,2 @@ +.. include:: ../../CONTRIBUTING.md + :parser: myst_parser.sphinx_ diff --git a/docs/developer_guide/index.rst b/docs/developer_guide/index.rst new file mode 100644 index 0000000..d87aaf3 --- /dev/null +++ b/docs/developer_guide/index.rst @@ -0,0 +1,19 @@ +Developer guide +=============== + +These guidelines describe how to contribute to ``sequince-density`` and the +responsibilities that apply to contributions. + +* The :doc:`contribution guidelines ` cover development setup, + code style, typing, validation, documentation, and the pull request process. +* The `Sequince AI policy + `_ + explains contributor ownership, review expectations, and validation of + AI-assisted work. This policy also applies to ``sequince-density``. + +.. toctree:: + :maxdepth: 1 + :caption: Contents + + Contributing + AI policy diff --git a/docs/examples.rst b/docs/examples.rst new file mode 100644 index 0000000..cfd8979 --- /dev/null +++ b/docs/examples.rst @@ -0,0 +1,11 @@ +Examples +======== + +The `sequince-examples repository +`_ and its +`documentation +`_ +contain worked examples highlighting different features in Sequince. + +The pages on :doc:`normalizing_flows`, :doc:`gaussian_mixtures`, and +:doc:`proposals` contain short usage examples for ``sequince-density``. diff --git a/docs/gaussian_mixtures.rst b/docs/gaussian_mixtures.rst new file mode 100644 index 0000000..8c730c3 --- /dev/null +++ b/docs/gaussian_mixtures.rst @@ -0,0 +1,36 @@ +Gaussian mixture models +======================= + +GMM support is provided via +`scikit-learn `_. +Install it with: + +.. code-block:: bash + + python -m pip install "sequince-density[gmm]" + +.. warning:: + + The GMM backend uses NumPy on the CPU. Fitting and density evaluation do not + run natively on other array backends or GPUs; inputs from other backends + are converted to NumPy for computation. + +Fit a mixture to a sample population, then draw samples and evaluate their log +densities: + +.. code-block:: python + + import numpy as np + + from sequince_density import GaussianMixtureProposal + + particles = np.random.default_rng(42).normal(size=(2000, 2)) + proposal = GaussianMixtureProposal(n_components=4).fit(particles, rng=42) + samples, log_q = proposal.sample_and_log_prob(256, rng=43) + +Fitting expects particles shaped ``(n_particles, n_dimensions)``. Nonuniform +weights are not supported; use an equal-weight population, such as particles +after resampling. + +``GaussianMixtureProposal`` implements Sequince's proposal interface directly. +See :doc:`proposals` for using it as a fitted starting distribution for SMC. diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..d0c2e32 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,42 @@ +sequince-density documentation +============================== + +``sequince-density`` provides density estimators for use with the +`Sequince `_ SMC framework, +including fitted proposal distributions and normalizing flows for +preconditioned sampling. + +Features +-------- + +* Normalizing-flow adapters for `Zuko `_ + (PyTorch) and `FlowJAX `_ (JAX). +* Gaussian-mixture proposals fitted with scikit-learn. +* Integration with Sequince's ``FlowTransform`` for mutation in a learned latent + space and ``FlowProposal`` for fitted proposal distributions. + +.. toctree:: + :maxdepth: 1 + :caption: Contents + + installation + normalizing_flows + gaussian_mixtures + proposals + examples + API reference + developer_guide/index + +Related projects +---------------- + +* `Sequince repository `_: the main SMC framework. +* `sequince-bilby `_: an interface + for using prebuilt Sequince samplers with Bilby. +* `orng `_: cross-backend random number + generation. +* `acai `_: Array API compatible control + flow and iteration. + +``sequince-density`` is licensed under the +`MIT License `_. diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..b170900 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,34 @@ +Installation +============ + +``sequince-density`` requires Python 3.11 or later. Install it from PyPI: + +.. code-block:: bash + + python -m pip install sequince-density + +Install the optional dependencies for the features you plan to use: + +.. list-table:: + :header-rows: 1 + + * - Extra + - Provides + * - ``gmm`` + - Gaussian-mixture proposals fitted with scikit-learn + * - ``zuko`` + - Zuko normalizing flows using PyTorch + * - ``flowjax`` + - FlowJAX normalizing flows using JAX + +For example, install Zuko support with: + +.. code-block:: bash + + python -m pip install "sequince-density[zuko]" + +Extras can be combined: + +.. code-block:: bash + + python -m pip install "sequince-density[gmm,zuko,flowjax]" diff --git a/docs/normalizing_flows.rst b/docs/normalizing_flows.rst new file mode 100644 index 0000000..5812efe --- /dev/null +++ b/docs/normalizing_flows.rst @@ -0,0 +1,47 @@ +Normalizing flows +================= + +Install the optional dependencies for your chosen backend: + +.. code-block:: bash + + python -m pip install "sequince-density[zuko]" + # Alternatively, for the JAX backend: + python -m pip install "sequince-density[flowjax]" + +Fit a Zuko flow to a two-dimensional sample population, then draw samples and +evaluate their log densities: + +.. code-block:: python + + import numpy as np + + from sequince_density import ZukoFlow + + rng = np.random.default_rng(42) + particles = rng.normal(size=(2000, 2)) + + flow = ZukoFlow(dims=2, flow_class="MAF", hidden_features=[32, 32]) + flow.fit(particles, n_epochs=100, batch_size=500, rng=42) + samples, log_q = flow.sample_and_log_prob(256, rng=43) + +``ZukoFlow`` returns PyTorch tensors; ``FlowJax`` returns JAX arrays. + +Preconditioned sampling +----------------------- + +For preconditioned SMC, pass an unfitted flow to ``FlowTransform`` and use the +transform as the ``particle_transform`` argument to +``make_standard_bayesian_smc``. The mutation step fits it to the current particle +population: + +.. code-block:: python + + from sequince.transforms import FlowTransform + + transform = FlowTransform( + ZukoFlow(dims=2, flow_class="MAF", hidden_features=[32, 32]), + fit_kwargs={"n_epochs": 100, "batch_size": 500}, + ) + +See :doc:`proposals` to use a flow as a fitted starting distribution instead. diff --git a/docs/proposals.rst b/docs/proposals.rst new file mode 100644 index 0000000..6716a07 --- /dev/null +++ b/docs/proposals.rst @@ -0,0 +1,32 @@ +Proposal distributions +====================== + +Both Gaussian mixtures and normalizing flows can provide a fitted starting +distribution for SMC. ``GaussianMixtureProposal`` implements Sequince's proposal +interface directly. Wrap a flow in ``FlowProposal`` to use the same interface, +including conversion to the SMC particle backend: + +.. code-block:: python + + import numpy as np + from sequince.proposals import FlowProposal + + from sequince_density import ZukoFlow + + particles = np.random.default_rng(42).normal(size=(2000, 2)) + proposal = FlowProposal( + ZukoFlow(dims=2, flow_class="MAF", hidden_features=[32, 32]), + fit_kwargs={"n_epochs": 100, "batch_size": 500}, + ).fit(particles, rng=42) + +For either fitted proposal type, pass ``proposal`` as ``log_proposal`` to +``make_standard_bayesian_smc`` and draw the initial particles from that same +proposal. SMC then bridges from the proposal to the target posterior. + +In an ASPIRE-style analysis, a flow is fitted to samples from an initial +analysis and used as the starting proposal for a new SMC run with an updated +likelihood. + +See the `Sequince documentation `_ +for the sampler and its proposal interface, and :doc:`examples` for the +examples repository. diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..72ef109 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,4 @@ +sphinx>=7.2 +sphinx-book-theme>=1.1 +sphinx-autoapi>=3.8,<4 +myst-parser>=4,<5 diff --git a/pyproject.toml b/pyproject.toml index c7d40d3..50ded6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,3 +82,21 @@ mypy_path = ["src"] ignore_missing_imports = true warn_unused_configs = true show_error_codes = true + +[tool.pixi.workspace] +channels = ["conda-forge"] +platforms = ["linux-64", "osx-arm64"] +requires-pixi = ">=0.78" + +[tool.pixi.environments] +docs = { features = ["doc"] } + +[tool.pixi.feature.doc.dependencies] +python = "3.13.*" +sphinx = ">=7.2" +sphinx-book-theme = ">=1.1" +sphinx-autoapi = ">=3.8,<4" +myst-parser = ">=4,<5" + +[tool.pixi.feature.doc.tasks] +docs = "python -m sphinx -b html -W --keep-going docs docs/_build/html" From e4ca2636e34d3ed0998d5b7b621f8c86e0b6cebd Mon Sep 17 00:00:00 2001 From: "Michael J. Williams" Date: Fri, 23 Oct 2026 14:36:41 +0200 Subject: [PATCH 2/2] BLD: update project urls --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 50ded6e..66d6b57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,8 +35,9 @@ flowjax = [ ] [project.urls] -Homepage = "https://github.com/sequince-dev/sequince-density" +Homepage = "https://sequince.readthedocs.io/projects/sequince-density/en/latest/" Repository = "https://github.com/sequince-dev/sequince-density" +Documentation = "https://sequince.readthedocs.io/projects/sequince-density/en/latest/" [tool.setuptools] package-dir = {"" = "src"}