math_audio_differential_evolution/
impl_helpers.rs1use crate::{DEReport, DifferentialEvolution};
2use ndarray::{Array1, Array2};
3
4impl<'a, F> DifferentialEvolution<'a, F>
7where
8 F: Fn(&Array1<f64>) -> f64 + Sync,
9{
10 pub(crate) fn energy(&self, x: &Array1<f64>) -> f64 {
11 let base = (self.func)(x);
12 base + self.penalty(x)
13 }
14
15 pub(crate) fn penalty(&self, x: &Array1<f64>) -> f64 {
16 let mut p = 0.0;
17 for (f, w) in &self.config.penalty_ineq {
19 let v = f(x);
20 let viol = v.max(0.0);
21 p += w * viol * viol;
22 }
23 for (h, w) in &self.config.penalty_eq {
25 let v = h(x);
26 p += w * v * v;
27 }
28 if let Some(lp) = &self.config.linear_penalty {
30 let ax = lp.a.dot(&x.view());
31 for i in 0..ax.len() {
32 let v = ax[i];
33 let lo = lp.lb[i];
34 let hi = lp.ub[i];
35 if v < lo {
36 let d = lo - v;
37 p += lp.weight * d * d;
38 }
39 if v > hi {
40 let d = v - hi;
41 p += lp.weight * d * d;
42 }
43 }
44 }
45 p
46 }
47
48 #[allow(clippy::too_many_arguments)]
49 pub(crate) fn finish_report(
50 &self,
51 pop: Array2<f64>,
52 energies: Array1<f64>,
53 x: Array1<f64>,
54 fun: f64,
55 success: bool,
56 message: String,
57 nit: usize,
58 nfev: usize,
59 ) -> DEReport {
60 DEReport {
61 x,
62 fun,
63 success,
64 message,
65 nit,
66 nfev,
67 population: pop,
68 population_energies: energies,
69 }
70 }
71
72 pub(crate) fn polish(&self, x0: &Array1<f64>) -> (Array1<f64>, f64, usize) {
73 let f = self.energy(x0);
76 (x0.clone(), f, 1)
77 }
78}