Skip to main content

NISMO: Nested Importance Sampling Morph Optimisation

PyPI version Python versions License

NISMO is a Python sampler for Bayesian evidence estimation and weighted posterior inference. It combines nested importance sampling (NIS) with a normalized Morph approximation, concentrating the nested sampling calculation in the regions that matter most to the posterior.

NISMO provides:

  • log-evidence estimates and weighted posterior samples;
  • three replacement schemes: fixed_morph, s-rwalk, and en-rwalk;
  • multiprocessing with FIFO replacement prefetching;
  • configurable scientific stopping criteria and hard resource limits;
  • reproducible run histories, diagnostics, and plotting helpers.

Nested importance sampling

For likelihood $L(\theta)$ and normalized prior $\pi(\theta)$, the marginal likelihood (Bayesian evidence) is

$$ Z = p(y) = \int_{\Theta} L(\theta),\pi(\theta),d\theta. $$

NIS introduces a normalized importance density $q_0(\theta)$ and the transformed integrand

$$ \Psi(\theta) = \frac{L(\theta),\pi(\theta)}{q_0(\theta)}. $$

The evidence can then be written as an expectation under $q_0$, or as the usual one-dimensional nested-sampling integral:

$$ Z = \int_{\Theta} \Psi(\theta),q_0(\theta),d\theta = \int_0^1 \Psi(X),dX, $$

where

$$ X(\lambda) = \int_{\Psi(\theta)>\lambda}q_0(\theta),d\theta $$

is the remaining probability mass under the importance density.

How NISMO implements NIS

  1. A normalized Morph density $q_0$ is fitted to representative posterior samples and then fixed for the evidence calculation.
  2. The initial $N_{\rm live}$ points are drawn independently from $q_0$.
  3. NISMO evaluates log_psi0 = log_likelihood + log_prior - log_q0 and removes the live point with the smallest transformed integrand.
  4. Deterministic nested-volume shrinkage is used: $X_i=\exp(-i/N_{\rm live})$. Each dead point contributes $(X_{i-1}-X_i)\Psi_i$ to the evidence quadrature.
  5. A replacement is drawn from $q_0$, subject to the current $\Psi$-constraint. The fixed_morph, s-rwalk, and en-rwalk schemes are available.
  6. At termination, the remaining live-point contribution is added and all contributions are normalized to produce posterior weights.

The fixed importance density must have support everywhere that $L(\theta)\pi(\theta)$ is nonzero. A missing mode cannot be recovered by the quadrature and can bias both the evidence and posterior. As with any evidence sampler, validate the complete configuration with repeated seeds and suitable benchmark problems.

Installation

Install NISMO 0.1.2 and all user-facing optional features from PyPI:

python -m pip install "nismo[all]==0.1.2"

The core package requires only NumPy and SciPy. Optional extras can be installed individually:

Extra Provides
nismo[morph] MorphZ proposal fitting
nismo[plot] Matplotlib diagnostics
nismo[progress] tqdm terminal and notebook progress displays
nismo[all] All user-facing optional features

NISMO supports Python 3.10 or newer and is tested on Python 3.10–3.12.

API example

The example below defines a normalized one-dimensional model, fits the fixed Morph importance density, runs NISMO, and extracts posterior samples.

import numpy as np

from nismo import CallableModel, MorphProposal, NISMOSampler

LOG_2PI = np.log(2.0 * np.pi)


def log_likelihood(theta: np.ndarray) -> np.ndarray:
    """N(x=0 | theta, sigma=1), evaluated in batches."""
    return -0.5 * (theta[:, 0] ** 2 + LOG_2PI)


def log_prior(theta: np.ndarray) -> np.ndarray:
    """Normalized N(theta | 0, 2) prior."""
    return -0.5 * ((theta[:, 0] / 2.0) ** 2 + LOG_2PI) - np.log(2.0)


model = CallableModel(
    ndim=1,
    parameter_names=("x",),
    log_likelihood_fn=log_likelihood,
    log_prior_fn=log_prior,
)

# Representative posterior draws used only to fit q0.
training_rng = np.random.default_rng(7)
posterior_samples = training_rng.normal(
    scale=np.sqrt(0.8),
    size=(2_000, 1),
)

importance_morph = MorphProposal.fit(
    posterior_samples,
    param_names=model.parameter_names,
    groups=[],
)

sampler = NISMOSampler(
    model=model,
    importance_morph=importance_morph,
    proposal_scheme="fixed_morph",
    n_live=200,
    rng=42,
    n_workers=1,
    output_path="runs/example",
)

result = sampler.run(dlogz=1e-2, progress=True)

print(f"logZ = {result.logz:.6f} +/- {result.logzerr:.6f}")
print(result.success, result.termination_reason)

# The weighted representation is the primary posterior output.
points = result.all_points
weights = result.posterior_weights
posterior_mean = np.average(points, axis=0, weights=weights)

# Equal-weight samples are available when required by downstream software.
equal_weight_samples = result.resample_equal(rng=43, n_samples=10_000)

When output_path is set, every completed or valid partial run automatically writes weighted_samples.npz, run_history.npz, diagnostics.json, and three diagnostic figures. Install nismo[plot] to enable the PNG output; samples and diagnostics are still saved when Matplotlib is unavailable. The same bundle can be written later with result.save("runs/example").

Model functions receive batches with shape (n, ndim) and return one natural logarithm per row. The prior must be normalized and include every normalization constant. The samples used to fit the Morph are not reused as live points.

Replacement schemes

Select a scheme through NISMOSampler(..., proposal_scheme=...):

Scheme Replacement mechanism
fixed_morph Independent constrained rejection draws from the fixed Morph
s-rwalk Gaussian-covariance random walk targeting constrained $q_0$
en-rwalk Split-ensemble differential-evolution, stretch, and Gaussian move mixture

Finite-length MCMC replacements must be calibrated for the dimension and geometry of the target. See the configuration guide for move settings, parallel workers, queue size, stopping policies, and resource limits.

Configure replacement parallelism directly in the sampler constructor, for example with NISMOSampler(..., n_workers=8, queue_size=8).

Results and diagnostics

NISMOSampler.run(...) returns an immutable NISMOResult containing:

  • logz, logzerr, information, success, and termination_reason;
  • weighted dead and final-live points;
  • likelihood, prior, importance-density, transformed-integrand, and quadrature arrays;
  • per-iteration stopping, acceptance, cost, MCMC, and queue histories;
  • optional s-rwalk component timings through SRWalkSettings(profile=True) and result.srwalk_diagnostics;
  • reproducibility metadata and the initial and final random-number-generator states.

The theoretical logzerr = sqrt(H / n_live) estimate is not a complete error budget: it does not include missing importance support, imperfect finite-length MCMC mixing, or adaptive-proposal approximation error.

Documentation

Development

Clone the repository and create the development environment with uv:

git clone https://github.com/nz-gravity/nismo.git
cd nismo
uv sync --extra dev

Run the development checks and build the package:

uv run ruff format --check .
uv run ruff check .
uv run mypy
uv run pytest -m "not slow"
uv build
uvx twine check dist/*

See CONTRIBUTING.md for the contribution workflow and RELEASING.md for the release process.

Citation

If you use NISMO in research, cite the software using the repository's CITATION.cff or GitHub's Cite this repository menu. For version 0.1.2, a BibTeX entry is:

@software{nismo_2026,
  author  = {{NISMO contributors}},
  title   = {NISMO: Morphing Importance Nested Sampling},
  year    = {2026},
  version = {0.1.2},
  url     = {https://github.com/nz-gravity/nismo}
}

Configured replacement methods may require additional citations. Inspect them programmatically with sampler.citations.

License

NISMO is distributed under the BSD 3-Clause license.

Metadata

Release files for nismo 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nismo 0.1.4
File Size Uploaded
nismo-0.1.4.tar.gz 108.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nismo 0.1.4
File Interpreter ABI Platform
nismo-0.1.4-py3-none-any.whl Python 3 none any Details

Total release size: 174.7 kB

Release files / nismo-0.1.4.tar.gz

Download URL nismo-0.1.4.tar.gz
Size 108.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0cdd465da55f41c64b917a4480e19d78e035d1d006451f45236e4bfaae96cfe3
BLAKE2b-256 checksum
How to use checksums
11f47f6464e56d697661e7ff737a4393b6aab259adb92ba92f11fd2b9f7ac6f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.

Transparency log

Release files / nismo-0.1.4-py3-none-any.whl

Download URL nismo-0.1.4-py3-none-any.whl
Size 66.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5500769bc2faa9841c30046cb22b1323a2d6a80c302312b32a74b0efec42bf36
BLAKE2b-256 checksum
How to use checksums
279856c5f9fec7b6bc7960603522dde1cd7706448f4ff27fdc8f9f3208146183
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.4 This release

2 release files

0.1.2

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page