turboswarm¶
Particle Swarm Optimization with a compute core in Rust and an API in Python. Extensible, supports real, integer and mixed variables, with visualization first, easy algorithm comparison, and readable code.
Highlights¶
- Velocity variants: inertia (Shi-Eberhart), constriction (Clerc-Kennedy) and FIPS (Fully Informed PSO).
- Topologies: global (gbest), ring (lbest), Von Neumann (2D grid) and random.
- Spaces: continuous, integer, binary, mixed (per-dimension type) and grey / interval (uncertain values).
- Multi-objective (MOPSO): Pareto front via archive + crowding distance.
- Constraints (penalty), run control (target / budgets / stagnation / callback) and boundary handling (clamp, reflect, wrap, reinit).
- Performance: velocity clamp, parallel evaluation (
rayon) and a vectorized objective path. - Benchmarks: sphere, rastrigin, rosenbrock, ackley, griewank and schwefel, each with metadata (recommended bound and known optimum).
- Visualization (Python): convergence curves, variant comparison, a 2D animated swarm, 3D landscape + animated 3D swarm, and Pareto-front plots.
- Integrations: SciPy drop-in,
scikit-learn
PSOSearchCV, Optuna sampler, pandas, Joblib/Dask, and an LLM agent tool. - Reproducibility: every experiment accepts a
seed.
The core idea¶
The PSO loop knows nothing about any concrete variant. Everything that changes
between variants lives behind three traits — SearchSpace, Velocity and
Topology. Adding a new variant means implementing one trait, without touching
the core. See Architecture and Extending.
Two ways to use it¶
import turboswarm as pso
# Same (min, max) on every axis -> pass the pair once with `dim`.
dim = 2
search_domain = (-5.12, 5.12)
result = pso.minimize(
"rastrigin",
bounds=search_domain,
dim=dim,
velocity="fips",
topology="ring",
seed=1,
)
print(result.best_position, result.best_value)
# ≈ [0.0, 0.0] with best_value ≈ 3e-4 — near the rastrigin optimum (f = 0)
use turboswarm_core::prelude::*;
use turboswarm_core::benchmarks::rastrigin;
let space = ContinuousSpace::new(vec![(-5.12, 5.12); 2]);
let velocity = InertiaVelocity::new(0.729, 1.49445, 1.49445);
let params = PsoParams { seed: Some(42), ..Default::default() };
let result = Pso::new(space, velocity, GlobalBest::new(), params)
.minimize(rastrigin);
// result.best_position ≈ [0.0, 0.0], result.best_value ≈ 0 (rastrigin optimum)
Start with Installation and the Getting started tutorial.