optde_parallel/
optde_parallel.rs1use math_audio_optimisation::{
2 DEConfig, Mutation, ParallelConfig, Strategy, differential_evolution,
3};
4use ndarray::Array1;
5use std::time::Instant;
6
7fn main() {
8 let dimension = 10;
10 let rastrigin = move |x: &Array1<f64>| -> f64 {
11 let mut sum = 0.0;
13 for _ in 0..1000 {
14 for &xi in x.iter() {
15 sum += xi.sin().cos().exp().ln_1p();
16 }
17 }
18
19 let a = 10.0;
21 let n = x.len() as f64;
22 let result = a * n
23 + x.iter()
24 .map(|&xi| xi * xi - a * (2.0 * std::f64::consts::PI * xi).cos())
25 .sum::<f64>();
26 result + sum * 1e-10 };
28
29 let bounds: Vec<(f64, f64)> = vec![(-5.12, 5.12); dimension];
30
31 println!("Testing Sequential Evaluation:");
33 let mut cfg_seq = DEConfig::default();
34 cfg_seq.maxiter = 100;
35 cfg_seq.popsize = 15;
36 cfg_seq.strategy = Strategy::Best1Bin;
37 cfg_seq.mutation = Mutation::Factor(0.8);
38 cfg_seq.recombination = 0.9;
39 cfg_seq.seed = Some(42);
40 cfg_seq.disp = true;
41 cfg_seq.parallel.enabled = false; let start_seq = Instant::now();
44 let report_seq =
45 differential_evolution(&rastrigin, &bounds, cfg_seq).expect("optimization failed");
46 let duration_seq = start_seq.elapsed();
47
48 println!("\nSequential Results:");
49 println!(" Success: {}", report_seq.success);
50 println!(" Best f: {:.6e}", report_seq.fun);
51 println!(" Iterations: {}", report_seq.nit);
52 println!(" Function evaluations: {}", report_seq.nfev);
53 println!(" Time: {:.3} seconds", duration_seq.as_secs_f64());
54
55 println!("\n\nTesting Parallel Evaluation:");
57 let mut cfg_par = DEConfig::default();
58 cfg_par.maxiter = 100;
59 cfg_par.popsize = 15;
60 cfg_par.strategy = Strategy::Best1Bin;
61 cfg_par.mutation = Mutation::Factor(0.8);
62 cfg_par.recombination = 0.9;
63 cfg_par.seed = Some(42);
64 cfg_par.disp = true;
65 cfg_par.parallel = ParallelConfig {
66 enabled: true,
67 num_threads: None, };
69
70 let start_par = Instant::now();
71 let report_par =
72 differential_evolution(&rastrigin, &bounds, cfg_par).expect("optimization failed");
73 let duration_par = start_par.elapsed();
74
75 println!("\nParallel Results:");
76 println!(" Success: {}", report_par.success);
77 println!(" Best f: {:.6e}", report_par.fun);
78 println!(" Iterations: {}", report_par.nit);
79 println!(" Function evaluations: {}", report_par.nfev);
80 println!(" Time: {:.3} seconds", duration_par.as_secs_f64());
81
82 println!("\n\nComparison:");
84 println!(
85 " Speedup: {:.2}x",
86 duration_seq.as_secs_f64() / duration_par.as_secs_f64()
87 );
88 println!(
89 " Result difference: {:.6e}",
90 (report_seq.fun - report_par.fun).abs()
91 );
92
93 println!("\n\nTesting with different thread counts:");
95 for num_threads in [1, 2, 4, 8] {
96 let mut cfg_threads = DEConfig::default();
97 cfg_threads.maxiter = 50;
98 cfg_threads.popsize = 15;
99 cfg_threads.strategy = Strategy::Best1Bin;
100 cfg_threads.mutation = Mutation::Factor(0.8);
101 cfg_threads.recombination = 0.9;
102 cfg_threads.seed = Some(42);
103 cfg_threads.disp = false;
104 cfg_threads.parallel = ParallelConfig {
105 enabled: true,
106 num_threads: Some(num_threads),
107 };
108
109 let start = Instant::now();
110 let _ =
111 differential_evolution(&rastrigin, &bounds, cfg_threads).expect("optimization failed");
112 let duration = start.elapsed();
113
114 println!(
115 " {} thread(s): {:.3} seconds",
116 num_threads,
117 duration.as_secs_f64()
118 );
119 }
120}