Skip to main content

Anneal

Anneal

Start here. Bound-constrained global optimization with a single budget knob, or classical simulated-annealing presets you can swap without rewriting a driver.

Simulated-annealing components on the eindir typed primitives. One surface, many drivers: classical presets, Bayesian pilot+mixer, generalized Langevin equation (GLE) colored noise, rank-1 additive independence, quasi-Monte Carlo (QMC) polish, device/ensemble scale. All obey the same five-component algebra (Obj / Cool / Neigh / Move / Accept) and four composition laws checked at construction.

Docs https://anneal.rgoswami.me
License MIT
Software DOI https://zenodo.org/doi/10.5281/zenodo.10672746
Paper reproducibility https://github.com/HaoZeke/anneal_repro — Zenodo 10.5281/zenodo.20672620
History Continuous development since 2023-02 (see git log); multi-author CITATION.cff

Generic global minimization

The primary optimizers are implemented in Rust. Objective and gradient capabilities come from eindir. Box chains compose bounded local polishing, the native Langevin stepper, descriptor coverage and shared-deposit exchange. Their projected polisher has its own L-BFGS memory; rgmin backs the separate WarmLbfgs integration, not every local-improvement path. The Python minimize binding and C interfaces call Rust. The optional Array API backend uses one Rust controller for single and batched preset runs. Cooling, acceptance and GSA visiting parameters come from the native components; Python supplies array/device adapters and result containers. Arrays remain in their backend namespace. These batched preset chains are independent: they do not consume box coverage or census messages.

Device results distinguish n_evals (objective callbacks) from evaluated_points (callbacks times the batch size), and retain the best finite evaluated candidate even when its transition is rejected. Device proposals are clipped to the declared box; this is not a manifold retraction or the unconstrained domain of the classical scalar presets.

The Rust box search and noise guide shows the typed configuration and its common work contract. Native regression targets box_search_contract and box_langevin_exploration check energy-origin invariance, effective coverage and sustained exploration. The communication contract separates coverage from optional minimum certification and coordinate adoption.

For a scalar objective on a finite box, the configurable Rust entry is ensemble_hop_optimize_with_config. It selects the existing engine from the gradient capability and retains the requested escape and coverage settings. Here objective supplies eindir_core::Objective<f64> and gradient supplies eindir_core::Gradient<f64> on the same declared box:

use anneal_core::methods::{
    BoxCoverageConfig, BoxEnsembleConfig, BoxEscape, GleEscapeConfig,
    ensemble_hop_optimize_with_config,
};
use anneal_core::methods::ensemble::HistoryMode;

let config = BoxEnsembleConfig {
    budget: 8_000,
    replicas: 4,
    history: HistoryMode::None,
    escape: BoxEscape::Langevin(GleEscapeConfig::default()),
    ..BoxEnsembleConfig::default()
};
let coverage = BoxCoverageConfig::default();
let result = ensemble_hop_optimize_with_config(
    &objective, Some(&gradient), 7, None, &config, &coverage,
);
assert_eq!(result.charged, result.n_evals + result.n_grads);
assert!(result.charged <= config.budget);

Coverage sharing in this example requires no minimum ledger. The native box_configured_dispatch tests compare complete callback traces and results against the directly selected engines, including white/colored noise and values-only chains.

Python exposes the default policy through the optional minimize binding. Every callback receives the declared design dimension, including fixed coordinates. A vector length divisible by three does not select atomic geometry.

import anneal

result = anneal.minimize(
    lambda x: float(x @ x),
    x0=[1.0, 0.0, 1.0, 1.0, 1.0],
    bounds=[(-2.0, 2.0), (0.0, 0.0), (-2.0, 2.0), (-2.0, 2.0), (-2.0, 2.0)],
    jac=lambda x: 2.0 * x,
    budget=256,
    replicas=4,
    seed=7,
)
assert result.charged == result.nfev + result.njev <= 256
assert result.x[1] == 0.0
coverage = result.diagnostics["coverage_regions_per_chain"]

With a gradient, replicas propose and locally improve candidates. Without a gradient, multiple replicas use values-only hop chains; one replica uses the values-only portfolio. Shared coverage records explored regions without requiring stationary points. Certified-minimum history is separate information, not the definition of exploration. The returned incumbent uses the original objective, independently of the exploration penalty and occupied chain state.

Both values-only engines use the same Rust budgeted quasi-Newton local refiner. It estimates local derivatives from scalar values; no Jacobian or force callback is required. Every stencil and line-search probe counts as an objective call, including rejected probes, and can improve the returned raw incumbent. This local refinement does not make the two global controllers identical or certify global optimality.

To compare cooperation without changing controllers, use methods::portfolio::portfolio_ensemble_optimize, or Python global_optimize(..., replicas=4, coverage_shared=True). Every replica keeps one uninterrupted portfolio; coverage_shared=False gives the same controller and work split without peer samples. This differs from minimize's documented one-portfolio/multiple-hop convenience policy. Peer samples move nearby global proposals in normalized box coordinates, without a Jacobian, force callback, minimum certificate, or replacement of the raw objective. The portfolio interaction contract names the proposal paths, budget rules, and transport limits.

coverage_neighbors=1 restricts generic coverage to adjacent chains on a ring; 0 is all-to-all. Rust exposes the same rule as BoxCoverageConfig.neighbors. Both paid samples and coverage deposits follow the graph, without gradients or minimum certificates. This does not restrict the optional minimum ledger or remove the portfolio checkpoint barrier.

nfev and njev count actual objective and gradient calls; charged is their sum. diagnostics preserves the underlying work, history, and coverage fields. success means a finite feasible candidate was returned, not that global optimality was certified. An optional parameter store archives results and supplies a starting candidate; it does not serialize chain or coverage state.

The communication contract maps these interfaces to their actual channels. The Rust box configuration also selects persistent white or colored-noise escape through the same box search. Atomic symmetry-aware proposals and constrained geometry use explicit specialized entry points; box clipping does not provide a manifold retraction.

Cluster search and cooperative production

Config::recommended(n) composes surface relocations that pay one acceptance test for a whole excursion, Normal-Gamma Thompson allocation over move arms, and tabu response to a stalled walk. Config::for_cluster(n) retains the plain Wales-Doye protocol as a comparison baseline. Accuracy and efficiency claims come from sealed, evaluation-matched ensembles rather than reference energies or morphology labels supplied to the search.

Large-cluster production uses four synchronously cooperating replicas. Each replica spends an independently auditable charged-work sequence and submits a freshly validated quenched representative. The coordinator updates an exact basin census and bounded descriptor catalogue, then closes a population epoch only after all replicas submit. A target-free Feynman--Kac potential ranks energy, descriptor novelty, census scarcity, and latent-Gaussian transition uncertainty. Replayable systematic resampling assigns parents at fixed population size; family caps and distinct descriptor-space rejuvenation keep one funnel from consuming every processor element.

This population layer borrows fixed-population bookkeeping from diffusion Monte Carlo, not imaginary-time quantum propagation or fixed-node physics. The latent transition field is the Gaussian part of an INLA-style model; its Gaussian posterior is solved directly, so no Laplace approximation or R-INLA runtime is involved. Bayesian move allocation and quench screening retain their own evidence, while nested sampling remains a matched-budget comparison with separate live-point weights. Shared-catalogue and one-private-catalogue- per-replica ensembles form the causal communication comparison.

The optional census bus exchanges current validated minima directly between same-node replicas, independently of coordinator-mediated adoption:

Setting Effect
CENSUS_BUS_BASE Enables the bus and selects its endpoint namespace. Use a distinct value for each concurrent ensemble.
CENSUS_BUS_NEIGHBORS=0 Subscribes to every peer; the default.
CENSUS_BUS_NEIGHBORS=k Subscribes only to cyclic neighbours within positive ring distance k.
CENSUS_BUS_IPC=1 Uses Unix-domain IPC; the default transport is loopback TCP.
CATALOG_SHARED_BIAS=1 Enables shared repulsive bias deposits.
CENSUS_BUS_UNBOUNDED=1 Admits distant bus minima into that bias; the default admits only nearby packings.

Changed minima publish immediately at eligible checkpoints; unchanged minima refresh every eight eligible checkpoints. Hop-only refreshes update retained state without duplicating deposits. Checkpoint spacing is controlled by CATALOG_SLICE, in charged objective calls, not physical time.

The bus retains direct neighbours without forwarding their messages. A ring therefore supplies a local census, not a globally mixed gossip aggregate, and does not restrict the coordinator's parent selection or hearing. The packing gate uses nearby_packing with histogram L1 distance at most PACKING_LINK (0.35); it is distinct from exact-basin merge radii and supplies no guarantee of one population cluster per energy funnel. The bounded/unbounded switch applies to bus observations, not population-parent or own-visit history.

Packing comparisons reuse descriptor rows only when every ordered coordinate bit matches. A process-wide cache shared by validation and request threads retains at most 8 MiB of coordinate-key and descriptor payloads; bookkeeping and caller-held references are additional. Pairwise codebooks and histograms remain separate, so reuse does not introduce a shared classification map or delay census invalidation when an occupied minimum moves.

The communication contracts map the atomic, box-gradient and values-only entry points to their history, bias, census and coordinate-adoption channels, including certificate and charged-work boundaries.

The persistent box escape guide connects colored or scalar-white Langevin proposals to that same quench and history path, with per-chain noise memory and combined callback accounting.

use anneal_core::methods::cluster_hopping::{optimize, Config, Ledger};

let cfg = Config::recommended(38);
let mut ledger = Ledger::new(400_000);
// supply `relax` closing over your objective; see examples/lj_cluster_search.rs

The lj_joint_optimum release example also provides a controlled NVE minima-hopping communication comparison. With the ira feature enabled, mh-communication runs both private-history and shared-history ensembles:

ANNEAL_MH_REPLICAS=4 ./target/release/examples/lj_joint_optimum \
  75 200000 2 mh-communication

Here 200,000 is the total objective-call budget for each ensemble, divided among four replicas; two seeds give two paired comparisons. Both arms use matched starting coordinates, replica seeds, and escape controls. Shared history changes escape effort on rediscovery without copying coordinates or pooling acceptance thresholds. Descriptors order exact minimum-identity checks, and only freshly validated quenches enter the history. Trajectory integration constructs optimization proposals, not kinetic rates or physical residence times. JSON reports include aggregate first-discovery work, per-replica work by stage, history overhead, and ensemble wall time. Private minimum counts sum replica-local identities; shared counts describe one common history. These counts are not interchangeable measures of coverage.

The structural archive retains rejected proposals, but the default exclusion history contains only accepted minima. An energy-rejected proposal remains eligible for another threshold trial. Shared classification and acceptance publication are atomic; an unresolved quench contributes charged work, not a basin visit.

For an alternative exploration policy, set ANNEAL_MH_HISTORY_POLICY=observed-exclusion on an ensemble run. Every certified observation then enters exclusion history, including energy-rejected proposals, and rediscovery feedback uses total observation counts. This policy is distinct from accepted-minimum history; its output arm names carry -observed-exclusion. accepted is the default, and unrecognized policy names are rejected.

Exact matching uses a per-ensemble cache of immutable pair-distance spectra, keyed by complete coordinates. It only prunes impossible matches; survivors retain native matching and identity-context checks. The default coordinate-key and spectrum payload limit is 128 MiB, with map metadata additional. Set ANNEAL_MH_PAIR_CACHE_BYTES=0 to disable storage for a controlled comparison. Each relation applies its pair screen once; rejection stops at the first sufficient distance discrepancy, and survivors reuse the prepared screening work without changing the native identity decision. Ensemble records retain each replica's best coordinates for independent audits.

For a controlled escape probe, ANNEAL_START_COORDINATES selects a plain coordinate file containing one finite x y z triplet per atom, without an XYZ header or element labels. Every replica starts from that structure; the seed still controls its proposals. The configuration record reports start_protocol: "fixed-coordinate-file" and embeds the input coordinates. This input cannot be combined with ANNEAL_OPTBENCH_STARTS: a diagnostic shelf structure is not a published random-start archive. The mh-private-soft and mh-shared-soft selectors add velocity softening to the same comparison.

External potentials use the same optimizer driver. The molecular-cluster and slab examples share one persistent in-process profile adapter; selecting nwchemc loads libnwchemc once and serves the complete hop loop without an RPC server or a result cache. Molecular requests omit a simulation cell, while the slab driver sends the periodic cell through the same adapter.

POTENTIAL_CONFIG=/path/to/PotentialConfig.bin \
POTENTIAL_LIBRARY=/path/to/libnwchemc.so \
cargo run --locked --release --features rgpot-ex \
  --example molecular_cluster -- 6 1200 8 nwchemc

The shared adapter is examples/common/profile_engine.rs; the two consumers are examples/molecular_cluster.rs and examples/slab_adsorption.rs.

Rigid TIP4P water is a first-class objective, not an example-local potential. Each molecule is a rigid body (centre of mass plus an exponential-map rotation vector) with Jorgensen parameters, no cutoff, and an analytic gradient assembled from site forces and torques. Basin hopping uses a Wales--Hodges translation/rotation kernel rather than the atomic Cartesian moves. Compare putative global minima against Wales and Hodges, Chem. Phys. Lett. 286, 65 (1998):

cargo run --locked --release --example water_tip4p -- 6 20000 4

The vesin-nl feature compiles vesin's own cell-list sources into the neighbour list instead of the crate's reimplementation. Its build script reads VESIN_SRC, a checkout of vesin, so cargo test --all-features needs it set:

VESIN_SRC=/path/to/vesin cargo test --locked --all-features

Install

pip install anneal

Full stack (pinned Rust + Python + docs):

pixi install

Start here (budget-only portfolio)

The intended stand-alone tool for most users: pass an objective, box bounds, and a work-unit budget (objective and gradient evaluations share the counter).

import numpy as np
from anneal import global_optimize

def rastrigin(x):
    return 10.0 * len(x) + np.sum(x * x - 10.0 * np.cos(2.0 * np.pi * x))

low, high = np.full(5, -5.0), np.full(5, 5.0)
out = global_optimize(rastrigin, low, high, budget=4000, seed=0)
print(out["best_val"], out["best_pos"])

Pass x0= (a point inside the box) to start from known parameters; it is the first evaluation and the first incumbent.

Runnable copies:

Classical presets (same driver, different slots)

from anneal import Boltzmann, Fast, Gsa, run

h = run(rastrigin, low, high, Boltzmann(t_init=5.0, sigma=0.5),
        n_epochs=40, steps_per_epoch=50, seed=1)
print(h.best_val)

Every proposal is reflected into [low, high], so obj_fn is only ever called inside the box. Pass x0= to start the walk from a known point (global_optimize and run_qmc take it too). The start costs one call: a run makes 1 + n_epochs * steps_per_epoch evaluations.

ChemFit

Gradient-free fits go through anneal.chemfit. The chain starts at the fitter's initial parameters, and every candidate stays inside the box. fit_anneal, fit_chemfit, run_benchmark, and run_fitter drive the fitter's session: init, then evaluate / step on current ChemFit or ask / tell on ChemFit 3.1, then finish with the best evaluated parameters. A fitter with neither pair is refused before init, and so is any invalid argument; run_benchmark with evaluate or ask alone, and the few calls 0.10.0 accepted while ignoring an argument, still run with a FutureWarning. The first exception the fitter raises, or a loss that is not a real number, stops the fit and reaches the caller without finish. driver="portfolio" (the default) is the budget-only global optimizer. driver="boltzmann", "fast", and "gsa" are the classical presets.

from anneal.chemfit import run_benchmark

def run_anneal(benchmark_context):
    return run_benchmark(
        benchmark_context,
        method="portfolio",
        low=-3.0,
        high=3.0,
    )

A scalar low or high is broadcast across the flattened parameters. Bounds may also live on benchmark_context["bounds"] or fitter.bounds, as (lower, upper) pairs mirroring the parameters; each side is a scalar or an array of the parameter's shape. A parameter whose two bounds are equal is held fixed.

Optional arms (additive independence + QMC polish)

import numpy as np
from anneal import additive_independence, qmc_polish

def rastrigin(x):
    return 10.0 * len(x) + np.sum(x*x - 10.0 * np.cos(2.0 * np.pi * x))

def grad_rastrigin(x):
    return 2.0 * x + 20.0 * np.pi * np.sin(2.0 * np.pi * x)

low = np.full(5, -5.0)
high = np.full(5, 5.0)

# Values-only rank-1 independence (no gradient)
res = additive_independence(rastrigin, low, high, max_fevals=3000, seed=7)

# Polish with gradient
refined = qmc_polish(rastrigin, grad_rastrigin, low, high,
                     n_starts=32, max_fevals_per_start=50, seed=0, top_k=1)
print(refined["best_val"])

Full docs, tutorials (classical, Bayesian pilot+mixer, GLE, polish+device), algebra, how-tos, and reference at https://anneal.rgoswami.me .

Method catalog

Every algorithmic mechanism in the crate, with file:line references, constants, and how the pieces feed each other: docs/orgmode/methods/catalog.org. A narrative walk of one cooperative run end to end, naming each mechanism as it fires, plus a dataflow diagram: docs/orgmode/methods/composition.org.

Group Covers
Local search Quenching, screening, biased hopping, move kernels, stall escapes
Learned allocation Thompson/depth/contextual allocators, budget-window temperature, regime selection
Descriptors and identity SOAP/ACE spaces, featomic, IRA/SOFI shape matching, census calibration
Cooperative layer Catalog/census, policy, boundary transport, descriptor holes, Feynman-Kac population epochs, spectral referee, umbrella bridges, the Cap'n Proto protocol
Population methods CSA bank, archive search, splice, portfolio, replica exchange, warm L-BFGS
Statistics and accounting Cooperative and local ledgers, Good-Turing census accounting, paired-seed evaluation methodology

Development

pixi install
pixi run -e python python-test
pixi run -e docs docs-export
pixi run -e docs docs-build

See pixi.toml and docs/export.el (modeled on rgpycrumbs/rsx-rs patterns).

License and citation

MIT (see LICENSE.txt). Citation: CITATION.cff or the software Zenodo DOI. Multi-author software citation lists six authors. Project history since February 2023. Reproducibility package for paper tables and figures: HaoZeke/anneal_repro (Zenodo 10.5281/zenodo.20672620).

Metadata

Release files for anneal 0.11.1

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

Source distribution (sdist)

Source distribution for anneal 0.11.1
File Size Uploaded Provenance Actions
anneal-0.11.1.tar.gz 5.7 MB With provenance Details for anneal-0.11.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for anneal 0.11.1
File Actions
anneal-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details for anneal-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
anneal-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details for anneal-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
anneal-0.11.1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for anneal-0.11.1-cp310-abi3-macosx_11_0_arm64.whl
anneal-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for anneal-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 18.2 MB

Release files / anneal-0.11.1.tar.gz

Download URL anneal-0.11.1.tar.gz
Size 5.7 MB
Tags Source
SHA-256 checksum
How to use checksums
d3b34913c23cb6c68e1376096063fc705328360ba5ebaef698e0d6919e671bab
BLAKE2b-256 checksum
How to use checksums
df7a07d12ad94820728a28d516e8a2b7a4c1e92837d72adaf9569c2e15d1d2a6
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 Oct 11, 2026.

Transparency log

Release files / anneal-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL anneal-0.11.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.3 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
f0107c88a842fc29d7927e6b786de07f033192c4e325794972e7a8ae3705b4f2
BLAKE2b-256 checksum
How to use checksums
c1e2d5ad6eb1f20a3c8dfeb999fc34b77a5b8c216cd2c86f5ccc823b07797aa9
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 Oct 11, 2026.

Transparency log

Release files / anneal-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL anneal-0.11.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.1 MB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
132daf493a2794c3ca4808a0a45c2b86bcc5637b16f79ed2d3b069c3932ec3a2
BLAKE2b-256 checksum
How to use checksums
8893d1f48f53c88f2ecd613a95b4f1528197e743eee9868b41f85a21a67b0e19
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 Oct 11, 2026.

Transparency log

Release files / anneal-0.11.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL anneal-0.11.1-cp310-abi3-macosx_11_0_arm64.whl
Size 2.9 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
8fa53a4e5a9771e8fe564da4263432458cbe5a2f8b24f9980e2ce36ce0a04a1a
BLAKE2b-256 checksum
How to use checksums
81992c297ab241f5583bd29b4d8e919adf3b52fe1b76baf2ba181259f9f43f64
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 Oct 11, 2026.

Transparency log

Release files / anneal-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl

Download URL anneal-0.11.1-cp310-abi3-macosx_10_12_x86_64.whl
Size 3.2 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
c778d76567bdf5cc22d73ba7bc8c3963e26bb2da65d5e3f1b4be8d4b1331aaf4
BLAKE2b-256 checksum
How to use checksums
d6c326b6af826fec160cea4d304fd37016ec38d31ecf2e33f029c5e822c28960
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 Oct 11, 2026.

Transparency log

Security for anneal 0.11.1

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.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for anneal-0.11.1.tar.gz

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 Oct 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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