Unified benchmarking framework for evolutionary and quasi-Newton optimization algorithms (DES, CMA-ES, MF-CMA-ES, L-BFGS-B)
Project description
declivity
A unified benchmarking framework and modern Python port for evolutionary and quasi-Newton optimization algorithms. Thesis project by Jedrzej Grabski.
What this is
Two things, glued together:
- A unified framework for fairly comparing optimizers under identical conditions (shared budgets, shared seeds, shared problem definitions).
- Modern Python implementations of algorithms that previously only existed as inconsistent academic ports — CMA-ES variants from R, L-BFGS-B from Fortran 77 — rewritten as clean, type-checked Python that plugs into the framework.
The current algorithm roster:
| Algorithm | Family | Notes |
|---|---|---|
| DES | Evolutionary | Adaptive Ft via evolution-path history (ring buffer) |
| CMA-ES | Evolutionary | Full covariance matrix, rank-1 + rank-μ updates |
| MF-CMA-ES | Evolutionary | Matrix-free CMA-ES (Arabas), optional PPMF |
| L-BFGS-B | Quasi-Newton | Pure-Python port of Fortran v3.0, configurable B₀ |
L-BFGS-B is the newest addition and ships with the more involved studies (rotated Ellipsoid, CMA-ES → L-BFGS-B covariance handoff).
Quick start
pdm install
pdm run run-example # Sphere demo (DES on 10D Sphere)
pdm run run-r # CEC2017 F10, 10 seeds, writes CSVs for R cross-check
Or directly:
PYTHONPATH=. pdm run python experiments/basic/declarative_plotting.py
PYTHONPATH=. pdm run python experiments/handoff/multimodal.py --num-seeds 25
Minimal example
Run one optimizer:
import numpy as np
from declivity import AlgorithmFactory
from declivity.algorithms.choices import AlgorithmChoice
from declivity.plotting import plot_metrics
from declivity.utils.benchmark_functions import Sphere
func = Sphere(dimensions=10)
initial_point = np.random.uniform(-50, 50, 10)
optimizer = AlgorithmFactory.create_optimizer(
algorithm=AlgorithmChoice.CMAES,
func=func,
initial_point=initial_point,
lower_bounds=-100,
upper_bounds=100,
)
result = optimizer.optimize()
print(f"f* = {result.best_fitness:.4e} after {result.evaluations} evals")
plot_metrics(result, save_path="cmaes.png") # every default panel for CMA-ES
Compare two algorithms:
from declivity.plotting import plot_comparison
plot_comparison(
{"CMA-ES": cmaes_result, "L-BFGS-B": lbfgsb_result},
save_path="comparison.png",
)
# Auto-picks the panels both algorithms expose (convergence + step_size by
# default). CMA-ES sigma and L-BFGS-B step_length end up on the same axes
# under one "Step Size" panel — semantic comparability is the point.
Multi-seed benchmark:
from declivity.benchmarking import Benchmark, Problem, SingleAlgorithm, CMAESLBFGSBHandoff
from declivity.plotting import plot_benchmark_convergence, plot_benchmark_boxplot
bench = Benchmark(problems=[...], algorithms=[...], seeds=range(25), output_dir=...)
bench.run()
plot_benchmark_convergence(bench.traces, problems, algorithms, save_path="conv.png")
plot_benchmark_boxplot (bench.traces, problems, algorithms, save_path="box.png")
See DOCUMENTATION.md for the full API.
Project layout
declivity/
├── declivity/ Library code (algorithms, framework)
│ ├── core/ BaseOptimizer, AlgorithmFactory, BaseConfig
│ ├── algorithms/ DES, CMA-ES, MF-CMA-ES, L-BFGS-B
│ ├── benchmarking/ Problem, Benchmark, RunTrace
│ │ + BenchmarkAlgorithm / HandoffAlgorithm ABCs
│ ├── utils/ Benchmark functions, constraint handlers,
│ │ repair strategies, initial-point generators,
│ │ population initializers, helpers
│ ├── logging/ BaseLogData / PopulationLogData + per-algo loggers
│ └── plotting/ Declarative panel system (Panel + 8 entry points)
│
├── experiments/ Runnable studies (one script per study)
│ ├── basic/ Tutorial demos, sanity checks, declarative API demos
│ ├── cross_validation/ Cross-checks against R reference impls
│ ├── lbfgsb/ L-BFGS-B feature studies
│ ├── handoff/ CMA-ES → L-BFGS-B handoff studies
│ └── report/ Plot regeneration utilities
│
├── plots/ Experiment outputs (gitignored, mirrors experiments/)
├── docs/ Algorithm lectures + design notes + reports
├── reference/ Reference R implementations and their outputs
└── notes/ Local scratch notes (gitignored)
Where to look next
- API reference:
DOCUMENTATION.md - Framework design principles:
docs/framework_design.md - Experiment index:
experiments/README.md - L-BFGS-B internals:
docs/lbfgsb_lecture.md - Initial-Hessian design:
docs/lbfgsb_initial_hessian_design.md - CMA-ES → L-BFGS-B handoff study:
docs/covariance_handoff_when_it_matters.md - CMA-ES diagnostic plot legend:
docs/cmaes_diagnostic_plots.md
Tech stack
- Python 3.12 (strict), managed with PDM
- NumPy 2.x, SciPy 1.15+, Matplotlib 3.10+
opfunufor CEC2017 benchmark functionsjoblibfor optional parallel benchmark execution
Status
Thesis-in-progress. There is no formal test suite — correctness is
validated by cross-comparison against the R reference implementations in
reference/ and by the supervisor-report experiments under
plots/report/.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file declivity-0.1.0.tar.gz.
File metadata
- Download URL: declivity-0.1.0.tar.gz
- Upload date:
- Size: 115.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6753f481a15be3bbbf8234da4cc1ded3df276b8a9198f5d5b410926699eb7f2d
|
|
| MD5 |
00e87a7279d8d2330d985670f411bde9
|
|
| BLAKE2b-256 |
938bdcd5ccc5d37a180fa22e3372f9877bc3ed043bbb6637e54b75975a064d8c
|
File details
Details for the file declivity-0.1.0-py3-none-any.whl.
File metadata
- Download URL: declivity-0.1.0-py3-none-any.whl
- Upload date:
- Size: 144.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8c9831321e692660df017f71178eba553d2a77aee3f2c15eaf8f181321fb2cb
|
|
| MD5 |
260700e7475d943594f9c5c734f0b137
|
|
| BLAKE2b-256 |
85c01ff2bc45dc16d5d6574955ee2b276bf2e138f725f4111192b1b29738e5f4
|