opensrdk_optimization/numerical_diff.rs
1/// Returns the gradients of each inputs.
2///
3/// - `func`: Function for differentiate
4/// - `x`: Input value
5/// - `h`: Width for numerical differential. Just only needed is to be a small value.
6pub fn numerical_diff(func: &dyn Fn(&[f64]) -> f64, x: &[f64], h: f64) -> Vec<f64> {
7 let res = (0..x.len())
8 .into_iter()
9 .map(|i| -> f64 {
10 let mut add = x.to_vec();
11 let mut sub = x.to_vec();
12 let h = if x[i] == 0.0 { h } else { x[i].abs() * h };
13 add[i] += h;
14 sub[i] -= h;
15
16 (func(&add) - func(&sub)) / 2.0 * h
17 })
18 .collect::<Vec<_>>();
19
20 res
21}