Expand description
Differential Evolution optimization library.
This crate provides a Rust implementation of the Differential Evolution (DE) algorithm, a population-based stochastic optimizer for continuous optimization problems. The implementation is inspired by SciPy’s differential_evolution.
§Features
- Multiple mutation strategies (Best1, Rand1, CurrentToBest1, etc.)
- Binomial and exponential crossover
- Adaptive parameter control (SHADE-style)
- L-SHADE: Linear population size reduction for faster convergence
- External Archive: Maintains diversity by storing discarded solutions
- Current-to-pbest/1: SHADE mutation strategy for balanced exploration
- Parallel population evaluation
- Constraint handling via penalty methods
- Latin Hypercube initialization
§Example
use math_audio_optimisation::{differential_evolution, DEConfigBuilder};
// Minimize the sphere function: f(x) = sum(x_i^2)
let bounds = vec![(-5.0, 5.0), (-5.0, 5.0)];
let config = DEConfigBuilder::new()
.maxiter(100)
.seed(42)
.build()
.expect("invalid config");
let result = differential_evolution(
&|x| x.iter().map(|&xi| xi * xi).sum(),
&bounds,
config,
).expect("optimization should succeed");
assert!(result.fun < 1e-6);§L-SHADE Example
use math_audio_optimisation::{differential_evolution, DEConfigBuilder, Strategy, LShadeConfig};
let bounds = vec![(-5.0, 5.0), (-5.0, 5.0)];
let lshade_config = LShadeConfig {
np_init: 18,
np_final: 4,
p: 0.11,
arc_rate: 2.1,
..Default::default()
};
let config = DEConfigBuilder::new()
.maxiter(100)
.strategy(Strategy::LShadeBin)
.lshade(lshade_config)
.seed(42)
.build()
.expect("invalid config");
let result = differential_evolution(
&|x| x.iter().map(|&xi| xi * xi).sum(),
&bounds,
config,
).expect("optimization should succeed");
assert!(result.fun < 1e-6);§Math Audio Differential Evolution
This crate provides a pure Rust implementation of Differential Evolution (DE) global optimization algorithm with advanced features including L-SHADE.
§Features
- Pure Rust Implementation: No external dependencies for core optimization
- Multiple DE Strategies: Various mutation and crossover strategies
- L-SHADE: Linear population size reduction for faster convergence
- External Archive: Maintains diversity by storing discarded solutions
- Current-to-pbest/1: SHADE mutation strategy for balanced exploration
- Constraint Handling: Linear and nonlinear constraint support
- Adaptive Parameters: Self-adjusting F and CR parameters (SHADE-style)
- Evaluation Recording: Track optimization progress and convergence
- Visualization Tools: Plot test functions and optimization traces
§Optimization Strategies
§Mutation Strategies
DE/rand/1:x_trial = x_r1 + F * (x_r2 - x_r3)DE/best/1:x_trial = x_best + F * (x_r1 - x_r2)DE/current-to-best/1: Combines current and best vectorsDE/rand/2: Uses five random vectors for mutationDE/current-to-pbest/1: Blends current with top-p% individual (SHADE)
§L-SHADE Strategy
L-SHADE combines three key improvements:
- Linear Population Reduction: Starts with large population (18×dim), reduces to minimum (4)
- External Archive: Stores discarded solutions for diversity
- Current-to-pbest/1: Selects pbest from top p% of population
use math_audio_optimisation::{
differential_evolution, DEConfigBuilder, Strategy, LShadeConfig
};
let bounds = vec![(-5.0, 5.0); 10]; // 10D problem
let lshade_config = LShadeConfig {
np_init: 18, // Initial NP = 18 × dim = 180
np_final: 4, // Final NP = 4
p: 0.11, // Select from top 11%
arc_rate: 2.1, // Archive size = 2.1 × current NP
..Default::default()
};
let config = DEConfigBuilder::new()
.maxiter(500)
.strategy(Strategy::LShadeBin)
.lshade(lshade_config)
.seed(42)
.build()
.expect("invalid config");
let result = differential_evolution(
&|x| x.iter().map(|&xi| xi * xi).sum(),
&bounds,
config,
).expect("optimization should succeed");§Crossover Strategies
- Binomial: Random parameter-wise crossover
- Exponential: Sequential parameter crossover
§Usage
use math_audio_optimisation::{differential_evolution, DEConfigBuilder, Strategy, Mutation};
use ndarray::Array1;
// Example objective function (Rosenbrock)
let objective = |x: &Array1<f64>| {
let a = 1.0;
let b = 100.0;
(a - x[0]).powi(2) + b * (x[1] - x[0].powi(2)).powi(2)
};
// Define bounds for 2D problem
let bounds = vec![(-5.0, 5.0), (-5.0, 5.0)];
let config = DEConfigBuilder::new()
.strategy(Strategy::Rand1Bin)
.maxiter(1000)
.popsize(50)
.mutation(Mutation::Factor(0.8))
.recombination(0.9)
.seed(42)
.build()
.expect("invalid config");
let result = differential_evolution(&objective, &bounds, config)
.expect("optimization should succeed");
println!("Best solution: {:?}", result.x);
println!("Best fitness: {}", result.fun);§Constraint Support
§Linear Constraints
use math_audio_optimisation::{LinearConstraintHelper, DEConfig};
use ndarray::{Array1, Array2};
// Linear constraint: x1 + x2 <= 1.0
let constraint = LinearConstraintHelper {
a: Array2::from_shape_vec((1, 2), vec![1.0, 1.0]).unwrap(),
lb: Array1::from_vec(vec![f64::NEG_INFINITY]),
ub: Array1::from_vec(vec![1.0]),
};
// Apply to configuration with penalty weight
let mut config = DEConfig::default();
constraint.apply_to(&mut config, 1000.0); // penalty weight§Nonlinear Constraints
let nonlinear_constraint = |x: &[f64]| -> f64 {
x[0].powi(2) + x[1].powi(2) - 1.0 // circle constraint
};§Visualization
The crate includes a plot_functions binary for visualizing test functions and optimization traces:
# Plot test functions as contour plots
cargo run --bin plot_functions -- --functions rosenbrock,sphere
# Show optimization traces from CSV files
cargo run --bin plot_functions -- --csv-dir traces/ --show-traces§Integration
This crate is part of the Math Audio ecosystem:
- Used by
autoeqfor filter parameter optimization - Integrates with
math-audio-testfunctionsfor validation - Works with
math-audio-iir-firfor audio filter optimization
§Examples
The crate includes several example programs demonstrating different DE capabilities:
basic_de: Simple unconstrained optimizationlinear_constraints: Linear constraint handlingnonlinear_constraints: Complex constraint optimization
§Performance Tips
- Use L-SHADE for high-dimensional problems (>10 dimensions)
- Start with default LShadeConfig and tune p if needed
- Lower p values (0.05-0.1) favor exploitation
- Higher p values (0.15-0.25) favor exploration
§References
§License
GPL-3.0-or-later
§References
- https://en.wikipedia.org/wiki/Differential_evolution
- https://www.sfu.ca/~ssurjano/optimization.html
- https://ch.mathworks.com/matlabcentral/fileexchange/23147-test-functions-for-global-optimization-algorithms
§Scipy
@ARTICLE{2020SciPy-NMeth,
author = {Virtanen, Pauli and Gommers, Ralf and Oliphant, Travis E. and
Haberland, Matt and Reddy, Tyler and Cournapeau, David and
Burovski, Evgeni and Peterson, Pearu and Weckesser, Warren and
Bright, Jonathan and {van der Walt}, St{\'e}fan J. and
Brett, Matthew and Wilson, Joshua and Millman, K. Jarrod and
Mayorov, Nikolay and Nelson, Andrew R. J. and Jones, Eric and
Kern, Robert and Larson, Eric and Carey, C J and
Polat, {\.I}lhan and Feng, Yu and Moore, Eric W. and
{VanderPlays}, Jake and Laxalde, Denis and Perktold, Josef and
Cimrman, Robert and Henriksen, Ian and Quintero, E. A. and
Harris, Charles R. and Archibald, Anne M. and
Ribeiro, Ant{\^o}nio H. and Pedregosa, Fabian and
{van Mulbregt}, Paul and {SciPy 1.0 Contributors}},
title = {{{SciPy} 1.0: Fundamental Algorithms for Scientific Computing in Python}},
journal = {Nature Methods},
year = {2020},
volume = {17},
pages = {261--272},
adsurl = {https://rdcu.be/b08Wh},
doi = {10.1038/s41592-019-0686-2},
}§A large review in 2020 of the DE space
@article{BILAL2020103479,
title = {Differential Evolution: A review of more than two decades of research},
journal = {Engineering Applications of Artificial Intelligence},
volume = {90},
pages = {103479},
year = {2020},
issn = {0952-1976},
doi = {https://doi.org/10.1016/j.engappai.2020.103479},
url = {https://www.sciencedirect.com/science/article/pii/S095219762030004X},
author = { Bilal and Millie Pant and Hira Zaheer and Laura Garcia-Hernandez and Ajith Abraham},
keywords = {Meta-heuristics, Differential evolution, Mutation, Crossover, Selection},
abstract = {Since its inception in 1995, Differential Evolution (DE) has emerged as one of the most frequently used algorithms for solving complex optimization problems. Its flexibility and versatility have prompted several customized variants of DE for solving a variety of real life and test problems. The present study, surveys the near 25 years of existence of DE. In this extensive survey, 283 research articles have been covered and the journey of DE is shown through its basic aspects like population generation, mutation schemes, crossover schemes, variation in parameters and hybridized variants along with various successful applications of DE. This study also provides some key bibliometric indicators like highly cited papers having citations more than 500, publication trend since 1996, journal citations etc. The main aim of the present document is to serve as an extended summary of 25 years of existence of DE, intended for dissemination to interested parties. It is expected that the present survey would generate interest among the new users towards the philosophy of DE and would also guide the experience researchers.}
}§JADE
@ARTICLE{5208221,
author={Zhang, Jingqiao and Sanderson, Arthur C.},
journal={IEEE Transactions on Evolutionary Computation},
title={JADE: Adaptive Differential Evolution With Optional External Archive},
year={2009},
volume={13},
number={5},
pages={945-958},
keywords={Genetic mutations;Programmable control;Adaptive control;Convergence;Automatic control;Evolutionary computation;Feedback;Robustness;Particle swarm optimization;Performance analysis;Adaptive parameter control;differential evolution;evolutionary optimization;external archive},
doi={10.1109/TEVC.2009.2014613}}Re-exports§
pub use error::DEError;pub use error::Result;pub use differential_evolution::differential_evolution;pub use external_archive::ExternalArchive;pub use lshade::LShadeConfig;pub use parallel_eval::ParallelConfig;pub use recorder::OptimizationRecord;pub use recorder::OptimizationRecorder;pub use run_recorded::run_recorded_differential_evolution;
Modules§
- apply_
integrality - Integer variable handling for mixed-integer optimization.
- apply_
wls - Wrapper Local Search (WLS) application for local refinement.
- crossover_
binomial - Binomial (uniform) crossover implementation.
- crossover_
exponential - Exponential crossover implementation.
- differential_
evolution - Main differential evolution algorithm implementation.
- distinct_
indices - Utilities for selecting distinct random indices from a population.
- error
- Error types for the Differential Evolution optimizer.
- external_
archive - External archive for L-SHADE algorithm. External Archive for L-SHADE
- function_
registry - Registry of standard test functions for benchmarking.
- impl_
helpers - Internal helper functions for DE implementation.
- init_
latin_ hypercube - Latin Hypercube Sampling initialization strategy.
- init_
random - Random uniform initialization strategy.
- lshade
- L-SHADE configuration. L-SHADE (Linear Population Size Reduction SHADE) Configuration
- metadata
- Metadata-driven optimization examples and tests. Tests for metadata-driven optimization examples
- mutant_
adaptive - Adaptive mutation strategy with dynamic parameter control.
- mutant_
best1 - Best/1 mutation strategy: uses best individual plus one difference vector.
- mutant_
best2 - Best/2 mutation strategy: uses best individual plus two difference vectors.
- mutant_
current_ to_ best1 - Current-to-best/1 mutation: blends current with best individual.
- mutant_
current_ to_ pbest1 - Current-to-pbest/1 mutation: blends current with p-best individual (SHADE). Current-to-pbest/1 mutation strategy
- mutant_
rand1 - Rand/1 mutation strategy: uses random individual plus one difference vector.
- mutant_
rand2 - Rand/2 mutation strategy: uses random individual plus two difference vectors.
- mutant_
rand_ to_ best1 - Rand-to-best/1 mutation: blends random with best individual.
- parallel_
eval - Parallel population evaluation support.
- recorder
- Optimization recording for analysis and debugging.
- run_
recorded - Recorded optimization wrapper for testing. Recording wrapper for differential evolution for testing purposes
- stack_
linear_ penalty - Linear penalty stacking utilities for combining multiple constraints.
Structs§
- Adaptive
Config - Adaptive differential evolution configuration
- DEConfig
- Configuration for the Differential Evolution optimizer.
- DEConfig
Builder - Fluent builder for
DEConfigfor ergonomic configuration. - DEIntermediate
- Information passed to callback after each generation.
- DEReport
- Result/report of a DE optimization run.
- Differential
Evolution - Differential Evolution optimizer.
- Linear
Constraint Helper - SciPy-like linear constraint helper: lb <= A x <= ub.
- Linear
Penalty - Linear penalty specification: lb <= A x <= ub (component-wise).
- Nonlinear
Constraint Helper - SciPy-like nonlinear constraint helper: vector-valued fun(x) with lb <= fun(x) <= ub.
- Polish
Config - Polishing configuration using NLopt local optimizer within bounds.
Enums§
- Callback
Action - Action returned by callback to control optimization flow.
- Crossover
- Crossover type
- Init
- Initialization scheme for the population.
- Mutation
- Mutation setting: either a fixed factor, a uniform range (dithering), or adaptive.
- Strategy
- Differential Evolution mutation/crossover strategy.
- Updating
- Whether best updates during a generation (we use Deferred only).
Type Aliases§
- Callback
Fn - Callback function type
- Penalty
Tuple - Penalty tuple type (function, weight)
- Scalar
Constraint Fn - Scalar constraint function type
- Vector
Constraint Fn - Vector constraint function type