This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.5.0 instead.
Reason given by maintainers: outdated and contains pi
AMM: budget-aware routing of classical solvers by online probes
AMM is a derivative-free optimizer for continuous black-box problems with a known evaluation budget and a known box. It does not run one algorithm: it spends a small, counted part of the budget on online probes (curvature, plateau, separability, kink, basin and fractal readings of the objective near the incumbent) and uses their outcomes to route the rest of the budget among quasi-Newton (SLSQP, L-BFGS-B), trust-region (COBYQA), coordinate (STEP), multistart (MLSL) and population (CMA-ES family, the ATM sampler) engines. A probe that does not fire leaves the run on a general path, so a misreading costs evaluations, not the run. Every rule reads only the dimension, the budget, the box and evaluated function values.
The method, its development protocol and its evaluation on COCO/bbob are described in the paper
(citation below). The package was developed under the code name ATM; the implementation therefore
lives in atm, and amm is an alias for the same objects.
Install
pip install amm-optimizer # NumPy and SciPy only
pip install -e ".[dev]" # from a checkout; add ",bench" for the COCO/bbob tooling
Quick start (the configuration frozen for the paper)
import numpy as np
import amm # `import atm` is equivalent
def f(x):
return float(np.sum((x - 1.0) ** 2))
result = amm.minimize(
f,
x0=np.zeros(10),
budget=100 * 10, # maximum number of function evaluations
seed=0, # runs are deterministic given the seed
bounds=(-5, 5), # required: the box (scalars or one value per coordinate)
config=amm.presets.get("c46"), # the frozen configuration; see docs/FREEZE_2026-10-22.md
)
print(result.x, result.fun, result.nfev)
bounds is required by this preset (it raises ValueError without it). The box is used, not
enforced as a constraint: samples are folded into it before the function is called. The objective
must be deterministic. Tested on noiseless, continuous, box-constrained problems with budgets of
10 to 1000 x the dimension.
Reproducing the paper. The code is that of git tag freeze-2026-10-22; the configuration hash of
amm.presets.get("c46").config_hash() is 2153948ebed51150. Pre-registrations and result notes of
every batch are in docs/research/batches/, and docs/FREEZE_2026-10-22.md records what was frozen
and why.
Citation. See CITATION.cff (the paper's reference will be added when it is public).
Legacy ATM presets
The sections below document the original ATM sampler and the older presets
(ATMConfig(), composite(), improved()); they are kept because every recorded result and test
depends on them. This repository is a clean, tested re-implementation of the original ATM that
reproduces its results exactly (see docs/DEVIATIONS.md).
import numpy as np
import atm
def sphere(x):
return np.sum((x - 2) ** 2)
result = atm.minimize(sphere, x0=np.zeros(10), budget=2000, seed=0)
print(result.x, result.fun, result.nfev)
budget is the maximum number of function evaluations, and ATM uses all of them (the
best point found is kept even if the budget ends mid-iteration). Pass seed= (or an
rng=np.random.RandomState) for reproducible runs. A starting point where the function is
NaN or infinite raises ValueError; NaN or infinite values elsewhere count as failed
evaluations and never win.
The defaults reproduce the original ATM exactly (see docs/DEVIATIONS.md);
ATMConfig(strict_budget=False) also restores the original's looser budget accounting.
Better results: the improved preset
If you know the search box, ATMConfig.improved() gets far more out of the same budget:
result = atm.minimize(
sphere,
x0=np.zeros(10),
budget=2000,
seed=0,
bounds=(-5, 5), # scalars or one value per coordinate
config=atm.ATMConfig.improved(),
)
print(result.fun)
The box is used, not enforced as a constraint: samples are folded back into it before the
function is called, so the function only ever sees points inside. Without bounds= the
preset raises ValueError. The objective must be deterministic.
This preset is a hybrid, not just ATM. It takes ATM's sampler with five improvements
(success-rate control of the search width, a uniform first pool over the box, bounds folded
with a 25 % corner clip, a pool sized from the budget, no re-evaluation of the incumbent) and
adds local-search stages: a simplex search in up to 4 dimensions and a (1+1)-ES above, for the
first part of small budgets; a learned covariance up to 10 dimensions; and, up to 10
dimensions, a simplex search over the last half of the budget. Each option is documented in
docs/DEVIATIONS.md and docs/EXPERIMENTS.md.
Presets, from simplest to largest:
| Preset | What it is | Evidence |
|---|---|---|
ATMConfig() |
the original ATM, bit for bit | tests/golden, 400-case parity sweep |
ATMConfig.composite() |
ATM's sampler plus the five improvements; stays pure ATM | +.101, +.097, +.099 on three untouched holdouts |
ATMConfig.improved() |
the composite plus the local stages above (recommended) | +.196 over the original, +.096 over the composite on a fourth holdout |
ATMConfig.improved_wave6() |
an earlier version, kept for reproducibility; loses on multimodal functions at medium budgets | Tier 4, docs/HOLDOUT_TIER4.md |
tests/golden/presets.json pins the exact cost traces of all of them.
What to expect from improved(), measured on COCO bbob (2021 suite) instances 96-100 that
were not used to design it (docs/HOLDOUT_TIER5.md, 18,000 runs per arm, raw COCO evaluation):
- ECDF value (fraction of targets reached) improves by +.196 [95 % CI +.180, +.212] over
the defaults, averaged over budgets of 30, 100 and 300 x dimension, and by +.096
[+.085, +.108] over
composite(). - The gain shrinks as the dimension grows: over the defaults +.412 at D = 2, +.197 at D = 5,
+.127 at D = 10, +.082 at D = 20, +.055 at D = 40; over
composite()+.215 at D = 2 down to +.017 at D = 40, where the two are almost the same algorithm. - It does not beat everything: a plain (1+1)-ES with the 1/5 rule is still ahead at 40 dimensions (-.031) and level at 20, and CMA-ES is far ahead of every ATM variant at large budgets (on the Tier 4 instances: .597 against .504 for the closest hybrid at 1000 x D).
- Only noiseless, continuous, box-constrained problems with budgets of 10 to 1000 x D were
tested. The three-algorithm design means its gain should not be described as an improvement
of ATM's sampler alone; use
composite()if you want that.
Development
pytest -m "not slow" # fast suite, includes golden-master and parity tests
pytest -m slow # 400 random cases against the frozen original in reference/
python tools/record_golden.py # re-record golden masters (only for deliberate changes)
python benchmarks/perf.py # repeatable speed benchmark, original vs this package
python benchmarks/block_profile.py # where the time goes, per algorithm block
| Path | What it is |
|---|---|
src/atm/ |
the package |
reference/ |
byte-identical copy of the original module, used only by tests |
tests/golden/ |
recorded trajectories from the original |
docs/AUDIT.md |
audit of the original, with severity and evidence |
docs/REFACTOR_PLAN.md |
phases, principles, definition of done |
docs/DEVIATIONS.md |
every difference from the original |
docs/PERF.md |
speed measurements, method and repeatability |
docs/BENCHMARKS.md |
COCO protocol, harness usage, parity and profiling results |
docs/EXPERIMENTS.md |
prioritized, lightweight experiments to improve ATM on bbob (protocol, cards, log) |
docs/research/ |
literature report, code-review report and their notes |
docs/WORKPLAN.md |
scan of the codebase and the plan for readability, tests, extensibility, profiling |
benchmarks/ |
speed harness (perf.py), per-block timing (block_profile.py), COCO/bbob harness (run_bbob.py, compare_bbob.py, postprocess_bbob.py) and stored results |
CI runs on your laptop
There is deliberately no GitHub Actions CI for now (it would use Actions minutes). Run the same checks locally with the project's virtual environment:
.venv\Scripts\python tools/ci.py # fast gate, about 2 minutes: lint, format, types, quick tests
.venv\Scripts\python tools/ci.py --full # about 3 minutes (longer on a busy machine): all tests incl. the 400-case parity sweep, 100 % coverage gate
Both stop at the first failing step and exit non-zero (--keep-going runs everything). To run the fast gate automatically before every git push, opt in with git config core.hooksPath .githooks (undo with git config --unset core.hooksPath; skip once with git push --no-verify). It is not enabled by default.
A GitHub Actions workflow is parked, switched to manual start, in ci/github-actions-ci.yml; moving it to .github/workflows/ needs a token with the workflow scope.
Licensed under Apache-2.0.
Metadata
Release files for amm-optimizer 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| amm_optimizer-0.2.0.tar.gz | 2.0 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| amm_optimizer-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.1 MB
Release files / amm_optimizer-0.2.0.tar.gz
| Download URL | amm_optimizer-0.2.0.tar.gz |
|---|---|
| Size | 2.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e82b7142bd0b86da7367525f12b3b591d0ffdc9bb3720f6597104999639f47f3
|
|
BLAKE2b-256 checksum How to use checksums |
b2706993102ea2bc615f78c1f1d07484dc3968513c964a3ef9408ec92ca74357
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Release files / amm_optimizer-0.2.0-py3-none-any.whl
| Download URL | amm_optimizer-0.2.0-py3-none-any.whl |
|---|---|
| Size | 153.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3c696d883e737a19d43dbdd8525716770c96467ee8f1d18bcd99b4ae1adcd347
|
|
BLAKE2b-256 checksum How to use checksums |
563f172242b8210ec808534b23df4b641f2d77f4fee507ae8027a1f108a06eb0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.10
|
Security for amm-optimizer 0.2.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.