1use math_audio_optimisation::{
2 AdaptiveConfig, DEConfigBuilder, Mutation, Strategy, differential_evolution,
3};
4use math_audio_test_functions::{ackley, quadratic, rosenbrock};
5use ndarray::Array1;
6
7fn main() {
14 println!("🧬 Adaptive Differential Evolution Demo");
15 println!("=====================================");
16 println!();
17
18 let test_functions = [
20 (
21 "Quadratic (f(x) = x₁² + x₂²)",
22 quadratic as fn(&Array1<f64>) -> f64,
23 [(-5.0, 5.0), (-5.0, 5.0)],
24 ),
25 (
26 "Rosenbrock 2D",
27 rosenbrock as fn(&Array1<f64>) -> f64,
28 [(-5.0, 5.0), (-5.0, 5.0)],
29 ),
30 ("Ackley", ackley, [(-32.0, 32.0), (-32.0, 32.0)]),
31 ];
32
33 for (name, func, bounds) in test_functions.iter() {
34 println!("🎯 Function: {}", name);
35 println!(
36 " Bounds: [{:.1}, {:.1}] × [{:.1}, {:.1}]",
37 bounds[0].0, bounds[0].1, bounds[1].0, bounds[1].1
38 );
39
40 println!(" 📊 Traditional DE:");
42 let traditional_result = run_traditional_de(*func, bounds);
43
44 println!(" 🧬 Adaptive DE (SAM only):");
46 let sam_result = run_adaptive_de(*func, bounds, false);
47
48 println!(" 🔧 Adaptive DE (SAM + WLS):");
50 let sam_wls_result = run_adaptive_de(*func, bounds, true);
51
52 println!(" 🏆 Comparison:");
54 println!(
55 " Traditional: f = {:.6e}, {} iterations",
56 traditional_result.fun, traditional_result.nit
57 );
58 println!(
59 " SAM only: f = {:.6e}, {} iterations",
60 sam_result.fun, sam_result.nit
61 );
62 println!(
63 " SAM + WLS: f = {:.6e}, {} iterations",
64 sam_wls_result.fun, sam_wls_result.nit
65 );
66
67 let improvement_sam =
68 ((traditional_result.fun - sam_result.fun) / traditional_result.fun * 100.0).max(0.0);
69 let improvement_wls =
70 ((traditional_result.fun - sam_wls_result.fun) / traditional_result.fun * 100.0)
71 .max(0.0);
72
73 println!(" 📈 Improvement with SAM: {:.1}%", improvement_sam);
74 println!(" 📈 Improvement with WLS: {:.1}%", improvement_wls);
75 println!();
76 }
77
78 println!("🔄 Parameter Adaptation Demo");
80 println!("===========================");
81
82 let bounds = [(-5.0, 5.0), (-5.0, 5.0)];
84
85 let adaptive_config = AdaptiveConfig {
86 adaptive_mutation: true,
87 wls_enabled: true,
88 w_max: 0.9, w_min: 0.1, w_f: 0.9, w_cr: 0.9, f_m: 0.5, cr_m: 0.6, wls_prob: 0.2, wls_scale: 0.1, };
97
98 let config = DEConfigBuilder::new()
99 .seed(42)
100 .maxiter(50)
101 .popsize(40)
102 .strategy(Strategy::AdaptiveBin)
103 .mutation(Mutation::Adaptive { initial_f: 0.8 })
104 .adaptive(adaptive_config)
105 .disp(true) .build()
107 .expect("popsize must be >= 4");
108
109 println!("Running adaptive DE on Rosenbrock function with progress display...");
110 let result = differential_evolution(&rosenbrock, &bounds, config).expect("optimization failed");
111
112 println!(
113 "Final result: f = {:.6e} at x = [{:.4}, {:.4}]",
114 result.fun, result.x[0], result.x[1]
115 );
116 println!(
117 "Converged in {} iterations with {} function evaluations",
118 result.nit, result.nfev
119 );
120
121 if result.success {
122 println!("✅ Optimization succeeded: {}", result.message);
123 } else {
124 println!("⚠️ Optimization status: {}", result.message);
125 }
126}
127
128fn run_traditional_de(
129 func: fn(&Array1<f64>) -> f64,
130 bounds: &[(f64, f64)],
131) -> math_audio_optimisation::DEReport {
132 let config = DEConfigBuilder::new()
133 .seed(42)
134 .maxiter(100)
135 .popsize(30)
136 .strategy(Strategy::Best1Bin)
137 .mutation(Mutation::Factor(0.8))
138 .recombination(0.7)
139 .build()
140 .expect("popsize must be >= 4");
141
142 differential_evolution(&func, bounds, config).expect("optimization failed")
143}
144
145fn run_adaptive_de(
146 func: fn(&Array1<f64>) -> f64,
147 bounds: &[(f64, f64)],
148 enable_wls: bool,
149) -> math_audio_optimisation::DEReport {
150 let adaptive_config = AdaptiveConfig {
151 adaptive_mutation: true,
152 wls_enabled: enable_wls,
153 w_max: 0.9,
154 w_min: 0.1,
155 wls_prob: 0.15,
156 wls_scale: 0.1,
157 ..AdaptiveConfig::default()
158 };
159
160 let config = DEConfigBuilder::new()
161 .seed(42)
162 .maxiter(100)
163 .popsize(30)
164 .strategy(Strategy::AdaptiveBin)
165 .mutation(Mutation::Adaptive { initial_f: 0.8 })
166 .adaptive(adaptive_config)
167 .build()
168 .expect("popsize must be >= 4");
169
170 differential_evolution(&func, bounds, config).expect("optimization failed")
171}