Skip to main content

optlib/tools/statistics/
mod.rs

1//! The module with the loggers ready for using. The loggers implements the `Logger` trait.
2
3use num::Float;
4
5use crate::{tools::logging::Logger, AlgorithmState, Goal, GoalValue, Solution};
6
7/// convergence[run number][iteration]
8type Convergence<T> = Vec<Vec<Option<Solution<T>>>>;
9
10/// The `Statistics` struct stores solutions for every algorithm running and every algorithm
11/// iteration.
12#[derive(Debug, Clone)]
13pub struct Statistics<T> {
14    /// The member stores final solution for every running. The index of vector is running number.
15    results: Vec<Option<Solution<T>>>,
16
17    /// The member stores current result for every algorithm running and every iteration. convergence[run number][iteration]
18    convergence: Convergence<T>,
19}
20
21/// The `CallCountData` struct used to store call count of goal function.
22#[derive(Debug, Clone)]
23pub struct CallCountData(Vec<usize>);
24
25/// The struct to calculate call count of goal function.
26pub struct GoalCalcStatistics<'a, T> {
27    goal: &'a mut dyn Goal<T>,
28    call_count: &'a mut CallCountData,
29}
30
31/// The trait contains methods for calculate statistics for Convergance<T>
32/// type Convergence<T> = Vec<Vec<Option<Solution<T>>>>;
33/// convergence[run number][iteration]
34pub trait StatFunctionsConvergence {
35    /// Calculate average goal function versus iteration number.
36    /// Average by run count.
37    /// Returns vector with: index - iteration, value - Option<GoalValue>.
38    /// Value is None if Solution is None for any running.
39    /// Length of result is minimal iterations count for all running.
40    /// # Params
41    /// self[run number][iteration]
42    fn get_average_convergence(&self) -> Vec<Option<GoalValue>>;
43    fn get_min_iterations(&self) -> usize;
44}
45
46/// The trait contains methods for calculate goal function statistics for Vec<Option<Solution<T>>>
47/// type Solution<T> = (T, GoalValue);
48pub trait StatFunctionsGoal {
49    /// Calculate an average of goal function.
50    /// Returns None if `self` is empty or `self` contains `None` only.
51    fn get_average_goal(&self) -> Option<GoalValue>;
52
53    /// Calculate a standard deviation of goal function.
54    /// Returns None if length of `self` less 2 or `self` contains `None` only.
55    fn get_standard_deviation_goal(&self) -> Option<GoalValue>;
56}
57
58/// The trait contains methods for calculate solution statistics for Vec<Option<Solution<T>>>
59/// type Solution<T> = (T, GoalValue);
60pub trait StatFunctionsSolution<T>: StatFunctionsGoal {
61    /// Calculate an average of solutions and goal function.
62    /// Returns None if `self` is empty or `self` contains `None` only.
63    fn get_average(&self) -> Option<Solution<T>>;
64
65    /// Calculate a standard deviation of solutions goal function.
66    /// Returns None if length of `self` less 2 or `self` contains `None` only.
67    fn get_standard_deviation(&self) -> Option<Solution<T>>;
68
69    /// Calculate success rate between 0 and 1.
70    /// Returns Some(SR) if running count > 0 and None otherwise.
71    /// # Params
72    /// `predicate` - function must return true for success solution and false otherwise.
73    fn get_success_rate<P>(&self, predicate: P) -> Option<f64>
74    where
75        P: Fn(&Solution<T>) -> bool;
76}
77
78/// Create a precate for `StatFunctionsSolution<T>::get_success_rate` method.
79/// The predicate compares goal function value with optimal goal.
80pub fn get_predicate_success_goal<T>(
81    expected_goal: GoalValue,
82    delta: GoalValue,
83) -> impl Fn(&Solution<T>) -> bool {
84    move |(_, goal): &(T, GoalValue)| (goal - expected_goal).abs() < delta
85}
86
87/// Create a precate for `StatFunctionsSolution<T>::get_success_rate` method.
88/// The predicate compares solution and valid answer.
89pub fn get_predicate_success_vec_solution<T: Float>(
90    expected: Vec<T>,
91    delta: Vec<T>,
92) -> impl Fn(&Solution<Vec<T>>) -> bool {
93    assert_eq!(expected.len(), delta.len());
94
95    move |(answer, _): &(Vec<T>, GoalValue)| {
96        for (x, (e, d)) in answer.iter().zip(expected.iter().zip(delta.iter())) {
97            if (*x - *e).abs() > *d {
98                return false;
99            }
100        }
101        true
102    }
103}
104
105impl CallCountData {
106    pub fn new() -> Self {
107        Self(vec![])
108    }
109
110    /// This method will be called before new optimization running
111    pub fn next_run(&mut self) {
112        self.0.push(0);
113    }
114
115    pub fn increment(&mut self) {
116        if self.0.len() == 0 {
117            self.0.push(0);
118        }
119        let index = self.0.len() - 1;
120
121        self.0[index] += 1;
122    }
123
124    pub fn add(&mut self, n: usize) {
125        if self.0.len() == 0 {
126            self.0.push(0);
127        }
128        let index = self.0.len() - 1;
129
130        self.0[index] += n;
131    }
132
133    /// Get call count for every running
134    pub fn get_call_count(&self) -> Vec<usize> {
135        self.0.clone()
136    }
137
138    /// Get average call count for all runnings
139    pub fn get_average_call_count(&self) -> Option<f64> {
140        let sum: usize = self.0.iter().sum();
141        let count = self.0.len();
142        if count == 0 {
143            None
144        } else {
145            Some((sum as f64) / (count as f64))
146        }
147    }
148
149    pub fn unite(&mut self, mut other: Self) {
150        self.0.append(&mut other.0);
151    }
152}
153
154impl<T: Clone> Statistics<T> {
155    pub fn new() -> Self {
156        Self {
157            results: vec![],
158            convergence: vec![],
159        }
160    }
161
162    pub fn get_run_count(&self) -> usize {
163        self.results.len()
164    }
165
166    pub fn get_results(&self) -> &Vec<Option<Solution<T>>> {
167        &self.results
168    }
169
170    pub fn get_convergence(&self) -> &Vec<Vec<Option<Solution<T>>>> {
171        &self.convergence
172    }
173
174    fn add_result(&mut self, state: &dyn AlgorithmState<T>) {
175        self.results.push(state.get_best_solution().clone());
176    }
177
178    fn add_convergence(&mut self, state: &dyn AlgorithmState<T>) {
179        let run_index = self.convergence.len() - 1;
180        self.convergence[run_index].push(state.get_best_solution().clone());
181    }
182
183    pub fn unite(&mut self, mut other: Self) {
184        self.results.append(&mut other.results);
185        self.convergence.append(&mut other.convergence);
186    }
187}
188
189impl<T> StatFunctionsConvergence for Convergence<T> {
190    /// Calculate average goal function versus iteration number.
191    /// Average by run count.
192    /// Returns vector with: index - iteration, value - Option<GoalValue>.
193    /// Value is None if Solution is None for any running.
194    /// Length of result is minimal iterations count for all running.
195    /// # Params
196    /// self[run number][iteration]
197    fn get_average_convergence(&self) -> Vec<Option<GoalValue>> {
198        let run_count = self.len();
199        let min_iterations = self.get_min_iterations();
200        let mut result = Vec::with_capacity(min_iterations);
201
202        for i in 0..min_iterations {
203            let mut sum_count = 0;
204            let mut sum = 0 as GoalValue;
205            for run in 0..run_count {
206                if let Some(solution) = &self[run][i] {
207                    sum += solution.1;
208                    sum_count += 1;
209                }
210            }
211
212            if sum_count != 0 {
213                result.push(Some(sum / (sum_count as GoalValue)));
214            } else {
215                result.push(None);
216            }
217        }
218
219        result
220    }
221
222    fn get_min_iterations(&self) -> usize {
223        if self.is_empty() {
224            0
225        } else {
226            self.iter().fold(self[0].len(), |min_len, x| {
227                if x.len() < min_len {
228                    x.len()
229                } else {
230                    min_len
231                }
232            })
233        }
234    }
235}
236
237impl<T> StatFunctionsGoal for Vec<Option<Solution<T>>> {
238    /// Calculate an average of goal function.
239    /// Returns None if `self` is empty or `self` contains `None` only.
240    fn get_average_goal(&self) -> Option<GoalValue> {
241        let success_solutions = self.iter().filter_map(|x| x.as_ref());
242        let count = success_solutions.clone().count();
243        let sum = success_solutions.fold(0 as GoalValue, |acc, (_, goal)| acc + goal);
244
245        if count == 0 {
246            None
247        } else {
248            Some(sum / (count as GoalValue))
249        }
250    }
251
252    fn get_standard_deviation_goal(&self) -> Option<GoalValue> {
253        let average = self.get_average_goal();
254        if self.len() < 2 || average == None {
255            return None;
256        }
257
258        let average_value = average.unwrap();
259
260        let success_solutions = self.iter().filter_map(|x| x.as_ref());
261        let count = success_solutions.clone().count();
262        let sum = success_solutions.fold(0 as GoalValue, |acc, (_, goal)| {
263            acc + (*goal - average_value) * (*goal - average_value)
264        });
265
266        if count < 2 {
267            None
268        } else {
269            Some((sum / ((count - 1) as GoalValue)).sqrt())
270        }
271    }
272}
273
274impl<T: Float + std::fmt::Debug> StatFunctionsSolution<Vec<T>> for Vec<Option<Solution<Vec<T>>>> {
275    fn get_average(&self) -> Option<Solution<Vec<T>>> {
276        let goal = self.get_average_goal();
277        if goal == None {
278            return None;
279        }
280
281        let success_solutions = self.iter().filter_map(|x| x.as_ref());
282        let count = success_solutions.clone().count();
283
284        let mut solution: Option<Vec<T>> = None;
285
286        for (current_solution, _) in success_solutions {
287            solution = match solution {
288                None => Some(current_solution.clone()),
289                Some(vector) => {
290                    assert_eq!(current_solution.len(), vector.len());
291                    Some(vectorize(&vector, &current_solution, |x, y| *x + *y))
292                }
293            }
294        }
295
296        match solution {
297            None => None,
298            Some(vector) => {
299                let result = vector
300                    .iter()
301                    .map(|x| *x / (T::from(count).unwrap()))
302                    .collect();
303                Some((result, goal.unwrap()))
304            }
305        }
306    }
307
308    fn get_standard_deviation(&self) -> Option<Solution<Vec<T>>> {
309        if let (Some(goal_deviation), Some((solution_average, _))) =
310            (self.get_standard_deviation_goal(), self.get_average())
311        {
312            let success_solutions = self.iter().filter_map(|x| x.as_ref());
313            let count = success_solutions.clone().count();
314            if count < 2 {
315                return None;
316            }
317
318            let mut sum: Option<Vec<T>> = None;
319
320            for (current_solution, _) in success_solutions {
321                sum = match sum {
322                    None => {
323                        let diff_2 = vectorize(&current_solution, &solution_average, |x, y| {
324                            (*x - *y) * (*x - *y)
325                        });
326
327                        Some(diff_2.clone())
328                    }
329                    Some(vector) => {
330                        assert_eq!(current_solution.len(), vector.len());
331                        let diff_2 = vectorize(&current_solution, &solution_average, |x, y| {
332                            (*x - *y) * (*x - *y)
333                        });
334                        Some(vectorize(&vector, &diff_2, |x, y| *x + *y))
335                    }
336                };
337            }
338
339            match sum {
340                None => None,
341                Some(vector) => {
342                    let result = vector
343                        .iter()
344                        .map(|x| (*x / (T::from(count - 1).unwrap())).sqrt())
345                        .collect();
346                    Some((result, goal_deviation))
347                }
348            }
349        } else {
350            None
351        }
352    }
353
354    /// Calculate success rate between 0 and 1.
355    /// Returns Some(SR) if running count > 0 and None otherwise.
356    /// # Params
357    /// `predicate` - function must return true for success solution and false otherwise.
358    fn get_success_rate<P>(&self, predicate: P) -> Option<f64>
359    where
360        P: Fn(&Solution<Vec<T>>) -> bool,
361    {
362        let count = self.len();
363        match count {
364            0 => None,
365            _ => {
366                let success_solutions = self
367                    .iter()
368                    .filter_map(|x| x.as_ref())
369                    .filter(|solution| predicate(solution));
370                Some(success_solutions.count() as f64 / (count as f64))
371            }
372        }
373    }
374}
375
376fn vectorize<T>(v1: &Vec<T>, v2: &Vec<T>, func: fn(&T, &T) -> T) -> Vec<T> {
377    assert_eq!(v1.len(), v2.len());
378    v1.iter().zip(v2.iter()).map(|(x, y)| func(x, y)).collect()
379}
380
381pub struct StatisticsLogger<'a, T> {
382    statistics: &'a mut Statistics<T>,
383}
384
385impl<'a, T> StatisticsLogger<'a, T> {
386    pub fn new(statistics: &'a mut Statistics<T>) -> Self {
387        Self { statistics }
388    }
389}
390
391impl<'a, T: Clone> Logger<T> for StatisticsLogger<'a, T> {
392    /// Will be called after algorithm initializing.
393    fn start(&mut self, _state: &dyn AlgorithmState<T>) {
394        self.statistics.convergence.push(vec![]);
395    }
396
397    /// Will be called before run algorithm (possibly after result algorithm after pause).
398    fn resume(&mut self, _state: &dyn AlgorithmState<T>) {}
399
400    /// Will be called in the end of iteration.
401    fn next_iteration(&mut self, state: &dyn AlgorithmState<T>) {
402        self.statistics.add_convergence(state);
403    }
404
405    /// Will be called when algorithm will be stopped.
406    fn finish(&mut self, state: &dyn AlgorithmState<T>) {
407        self.statistics.add_result(state);
408    }
409}
410
411impl<'a, T> GoalCalcStatistics<'a, T> {
412    pub fn new(goal: &'a mut dyn Goal<T>, call_count: &'a mut CallCountData) -> Self {
413        Self { goal, call_count }
414    }
415}
416
417impl<'a, T> Goal<T> for GoalCalcStatistics<'a, T> {
418    fn get(&mut self, x: &T) -> GoalValue {
419        self.call_count.increment();
420        self.goal.get(x)
421    }
422}
423
424#[cfg(test)]
425mod tests {
426    use super::*;
427
428    #[test]
429    fn get_min_iterations_empty() {
430        let convergence: Convergence<f32> = vec![];
431        assert_eq!(convergence.get_min_iterations(), 0);
432    }
433
434    #[test]
435    fn get_min_iterations_single_01() {
436        let mut convergence: Convergence<f32> = vec![];
437        convergence.push(vec![Some((1_f32, 0_f64))]);
438
439        assert_eq!(convergence.get_min_iterations(), 1);
440    }
441
442    #[test]
443    fn get_min_iterations_single_02() {
444        let mut convergence: Convergence<f32> = vec![];
445        convergence.push(vec![
446            Some((1_f32, 0_f64)),
447            Some((1_f32, 0_f64)),
448            Some((1_f32, 0_f64)),
449        ]);
450
451        assert_eq!(convergence.get_min_iterations(), 3);
452    }
453
454    #[test]
455    fn get_min_iterations_several_01() {
456        let mut convergence: Convergence<f32> = vec![];
457        convergence.push(vec![
458            Some((1_f32, 0_f64)),
459            Some((1_f32, 0_f64)),
460            Some((1_f32, 0_f64)),
461        ]);
462        convergence.push(vec![Some((1_f32, 0_f64))]);
463
464        assert_eq!(convergence.get_min_iterations(), 1);
465    }
466
467    #[test]
468    fn get_min_iterations_several_02() {
469        let mut convergence: Convergence<f32> = vec![];
470        convergence.push(vec![
471            Some((1_f32, 0_f64)),
472            Some((1_f32, 0_f64)),
473            Some((1_f32, 0_f64)),
474        ]);
475        convergence.push(vec![]);
476
477        assert_eq!(convergence.get_min_iterations(), 0);
478    }
479
480    #[test]
481    fn get_average_convergence_empty() {
482        let convergence: Convergence<f32> = vec![];
483        assert_eq!(convergence.get_average_convergence(), vec![]);
484    }
485
486    #[test]
487    fn get_average_convergence_single_01() {
488        let mut convergence: Convergence<f32> = vec![];
489        convergence.push(vec![
490            Some((3_f32, 30_f64)),
491            Some((2_f32, 20_f64)),
492            Some((1_f32, 10_f64)),
493        ]);
494
495        let result = vec![Some(30_f64), Some(20_f64), Some(10_f64)];
496
497        assert_eq!(convergence.get_average_convergence(), result);
498    }
499
500    #[test]
501    fn get_average_convergence_single_02() {
502        let mut convergence: Convergence<f32> = vec![];
503        convergence.push(vec![Some((3_f32, 30_f64)), None, Some((1_f32, 10_f64))]);
504
505        let result = vec![Some(30_f64), None, Some(10_f64)];
506
507        assert_eq!(convergence.get_average_convergence(), result);
508    }
509
510    #[test]
511    fn get_average_convergence_several_01() {
512        let mut convergence: Convergence<f32> = vec![];
513        convergence.push(vec![
514            Some((3_f32, 30_f64)),
515            Some((2_f32, 20_f64)),
516            Some((1_f32, 10_f64)),
517        ]);
518        convergence.push(vec![
519            Some((3_f32, 50_f64)),
520            Some((2_f32, 40_f64)),
521            Some((1_f32, 30_f64)),
522        ]);
523
524        let result = vec![Some(40_f64), Some(30_f64), Some(20_f64)];
525
526        assert_eq!(convergence.get_average_convergence(), result);
527    }
528
529    #[test]
530    fn get_average_convergence_several_02() {
531        let mut convergence: Convergence<f32> = vec![];
532        convergence.push(vec![Some((3_f32, 30_f64)), None, Some((1_f32, 10_f64))]);
533        convergence.push(vec![
534            Some((3_f32, 50_f64)),
535            Some((2_f32, 40_f64)),
536            Some((1_f32, 30_f64)),
537        ]);
538
539        let result = vec![Some(40_f64), Some(40_f64), Some(20_f64)];
540
541        assert_eq!(convergence.get_average_convergence(), result);
542    }
543
544    #[test]
545    fn get_average_convergence_several_03() {
546        let mut convergence: Convergence<f32> = vec![];
547        convergence.push(vec![Some((3_f32, 30_f64)), None, Some((1_f32, 10_f64))]);
548        convergence.push(vec![Some((3_f32, 50_f64)), None, Some((1_f32, 30_f64))]);
549
550        let result = vec![Some(40_f64), None, Some(20_f64)];
551
552        assert_eq!(convergence.get_average_convergence(), result);
553    }
554
555    #[test]
556    fn get_average_goal_empty() {
557        let results: Vec<Option<Solution<f32>>> = vec![];
558        assert_eq!(results.get_average_goal(), None);
559    }
560
561    #[test]
562    fn get_average_goal_none_only() {
563        let results: Vec<Option<Solution<f32>>> = vec![None];
564        assert_eq!(results.get_average_goal(), None);
565    }
566
567    #[test]
568    fn get_average_goal_single() {
569        let results: Vec<Option<Solution<f32>>> = vec![Some((1.0_f32, 10.0_f64))];
570        assert_eq!(results.get_average_goal(), Some(10.0_f64));
571    }
572
573    #[test]
574    fn get_average_goal_several() {
575        let results: Vec<Option<Solution<f32>>> =
576            vec![Some((1.0_f32, 10.0_f64)), Some((2.0_f32, 30.0_f64))];
577        assert_eq!(results.get_average_goal(), Some(20.0_f64));
578    }
579
580    #[test]
581    fn get_standard_deviation_goal_empty() {
582        let results: Vec<Option<Solution<f32>>> = vec![];
583        assert_eq!(results.get_standard_deviation_goal(), None);
584    }
585
586    #[test]
587    fn get_standard_deviation_goal_single() {
588        let results: Vec<Option<Solution<f32>>> = vec![Some((1.0_f32, 10.0_f64))];
589        assert_eq!(results.get_standard_deviation_goal(), None);
590    }
591
592    #[test]
593    fn get_standard_deviation_goal_none_only() {
594        let results: Vec<Option<Solution<f32>>> = vec![None; 10];
595        assert_eq!(results.get_standard_deviation_goal(), None);
596    }
597
598    #[test]
599    fn get_standard_deviation_goal_equal() {
600        let results: Vec<Option<Solution<f32>>> = vec![Some((1.0_f32, 10.0_f64)); 2];
601        assert!(results.get_standard_deviation_goal().unwrap().abs() < 1e-6);
602    }
603
604    #[test]
605    fn get_standard_deviation_goal_several() {
606        let results: Vec<Option<Solution<f32>>> = vec![
607            Some((1.0_f32, 1.0_f64)),
608            Some((2.0_f32, 2.0_f64)),
609            Some((3.0_f32, 3.0_f64)),
610        ];
611        assert!((results.get_standard_deviation_goal().unwrap() - 1.0_f64).abs() < 1e-6);
612    }
613
614    #[test]
615    fn get_average_vec_float_empty() {
616        let results: Vec<Option<Solution<Vec<f32>>>> = vec![];
617        assert_eq!(results.get_average(), None);
618    }
619
620    #[test]
621    fn get_average_vec_float_none_only() {
622        let results: Vec<Option<Solution<Vec<f32>>>> = vec![None];
623        assert_eq!(results.get_average(), None);
624    }
625
626    #[test]
627    fn get_average_vec_float_single() {
628        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![1.0_f32], 10.0_f64))];
629        assert_eq!(results.get_average(), Some((vec![1.0_f32], 10.0_f64)));
630    }
631
632    #[test]
633    fn get_average_vec_float_several_01() {
634        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
635            Some((vec![1.0_f32], 10.0_f64)),
636            Some((vec![3.0_f32], 30.0_f64)),
637        ];
638        assert_eq!(results.get_average(), Some((vec![2.0_f32], 20.0_f64)));
639    }
640
641    #[test]
642    fn get_average_vec_float_several_02() {
643        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
644            None,
645            Some((vec![1.0_f32], 10.0_f64)),
646            Some((vec![3.0_f32], 30.0_f64)),
647        ];
648        assert_eq!(results.get_average(), Some((vec![2.0_f32], 20.0_f64)));
649    }
650
651    #[test]
652    fn get_average_vec_float_several_03() {
653        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
654            Some((vec![1.0_f32], 10.0_f64)),
655            None,
656            Some((vec![3.0_f32], 30.0_f64)),
657        ];
658        assert_eq!(results.get_average(), Some((vec![2.0_f32], 20.0_f64)));
659    }
660
661    #[test]
662    fn get_average_vec_float_several_04() {
663        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
664            Some((vec![1.0_f32, 2.0_f32], 10.0_f64)),
665            None,
666            Some((vec![3.0_f32, 4.0_f32], 30.0_f64)),
667        ];
668        assert_eq!(
669            results.get_average(),
670            Some((vec![2.0_f32, 3.0_f32], 20.0_f64))
671        );
672    }
673
674    #[test]
675    fn get_standard_deviation_vec_float_empty() {
676        let results: Vec<Option<Solution<Vec<f32>>>> = vec![];
677        assert_eq!(results.get_standard_deviation(), None);
678    }
679
680    #[test]
681    fn get_standard_deviation_vec_float_single() {
682        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![1.0_f32], 10.0_f64))];
683        assert_eq!(results.get_standard_deviation(), None);
684    }
685
686    #[test]
687    fn get_standard_deviation_vec_float_none_only() {
688        let results: Vec<Option<Solution<Vec<f32>>>> = vec![None; 10];
689        assert_eq!(results.get_standard_deviation(), None);
690    }
691
692    #[test]
693    fn get_standard_deviation_vec_float_equal() {
694        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![1.0_f32], 10.0_f64)); 2];
695        let deviation = results.get_standard_deviation().unwrap();
696        assert!(deviation.0[0].abs() < 1e-6);
697        assert!(deviation.1.abs() < 1e-6);
698    }
699
700    #[test]
701    fn get_standard_deviation_goal_several_01() {
702        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
703            Some((vec![10.0_f32], 1.0_f64)),
704            Some((vec![11.0_f32], 2.0_f64)),
705            Some((vec![12.0_f32], 3.0_f64)),
706        ];
707        let deviation = results.get_standard_deviation().unwrap();
708
709        // dbg!(deviation.clone());
710        assert!((deviation.0[0] - 1.0_f32).abs() < 1e-6);
711        assert!((deviation.1 - 1.0 as GoalValue).abs() < 1e-6);
712    }
713
714    #[test]
715    fn get_standard_deviation_goal_several_02() {
716        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
717            Some((vec![10.0_f32, 10.0_f32], 1.0_f64)),
718            Some((vec![11.0_f32, 20.0_f32], 2.0_f64)),
719            Some((vec![12.0_f32, 30.0_f32], 3.0_f64)),
720        ];
721        let deviation = results.get_standard_deviation().unwrap();
722
723        assert!((deviation.0[0] - 1.0_f32).abs() < 1e-6);
724        assert!((deviation.0[1] - 10.0_f32).abs() < 1e-6);
725        assert!((deviation.1 - 1.0 as GoalValue).abs() < 1e-6);
726    }
727
728    #[test]
729    fn get_success_rate_goal_empty() {
730        let results: Vec<Option<Solution<Vec<f32>>>> = vec![];
731        let predicate = get_predicate_success_goal(1.0, 0.01);
732
733        assert_eq!(results.get_success_rate(&predicate), None);
734    }
735
736    #[test]
737    fn get_success_rate_goal_none() {
738        let results: Vec<Option<Solution<Vec<f32>>>> = vec![None];
739        let predicate = get_predicate_success_goal(1.0, 0.01);
740
741        assert!((results.get_success_rate(&predicate).unwrap() - 0.0_f64).abs() < 1e-5);
742    }
743
744    #[test]
745    fn get_success_rate_goal_none_many() {
746        let results: Vec<Option<Solution<Vec<f32>>>> = vec![None; 5];
747        let predicate = get_predicate_success_goal(1.0, 0.01);
748
749        assert!((results.get_success_rate(&predicate).unwrap() - 0.0_f64).abs() < 1e-5);
750    }
751
752    #[test]
753    fn get_success_rate_goal_full_success_fail() {
754        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![10.0_f32], 10.0_f64))];
755        let predicate = get_predicate_success_goal(1.0, 0.01);
756
757        assert!((results.get_success_rate(&predicate).unwrap() - 0.0).abs() < 1e-5);
758    }
759
760    #[test]
761    fn get_success_rate_goal_full_success_01() {
762        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![10.0_f32], 1.0_f64))];
763        let predicate = get_predicate_success_goal(1.0, 0.01);
764
765        assert!((results.get_success_rate(&predicate).unwrap() - 1.0).abs() < 1e-5);
766    }
767
768    #[test]
769    fn get_success_rate_goal_full_success_02() {
770        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![10.0_f32], 1.00999_f64))];
771        let predicate = get_predicate_success_goal(1.0, 0.01);
772
773        assert!((results.get_success_rate(&predicate).unwrap() - 1.0).abs() < 1e-5);
774    }
775
776    #[test]
777    fn get_success_rate_goal_full_success_half() {
778        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
779            Some((vec![10.0_f32], 1.0_f64)),
780            Some((vec![11.0_f32], 10.0_f64)),
781        ];
782        let predicate = get_predicate_success_goal(1.0, 0.01);
783
784        assert!((results.get_success_rate(&predicate).unwrap() - 0.5).abs() < 1e-5);
785    }
786
787    #[test]
788    fn get_success_rate_goal_full_success_two_of_three_01() {
789        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
790            Some((vec![10.0_f32], 10.0_f64)),
791            Some((vec![11.0_f32], 1.0_f64)),
792            Some((vec![12.0_f32], 1.00001_f64)),
793        ];
794        let predicate = get_predicate_success_goal(1.0, 0.01);
795
796        assert!((results.get_success_rate(&predicate).unwrap() - 0.66666).abs() < 1e-5);
797    }
798
799    #[test]
800    fn get_success_rate_goal_full_success_two_of_three_02() {
801        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
802            None,
803            Some((vec![11.0_f32], 1.0_f64)),
804            Some((vec![12.0_f32], 1.00001_f64)),
805        ];
806        let predicate = get_predicate_success_goal(1.0, 0.01);
807
808        assert!((results.get_success_rate(&predicate).unwrap() - 0.66666).abs() < 1e-5);
809    }
810
811    #[test]
812    fn get_success_rate_vec_solution_success_single() {
813        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![1.05_f32], 0.0_f64))];
814        let expected = vec![1.0];
815        let delta = vec![0.1];
816        let predicate = get_predicate_success_vec_solution(expected, delta);
817
818        assert!((results.get_success_rate(&predicate).unwrap() - 1.0).abs() < 1e-5);
819    }
820
821    #[test]
822    fn get_success_rate_vec_solution_fail_single() {
823        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![1.2_f32], 0.0_f64))];
824        let expected = vec![1.0];
825        let delta = vec![0.1];
826        let predicate = get_predicate_success_vec_solution(expected, delta);
827
828        assert!((results.get_success_rate(&predicate).unwrap() - 0.0).abs() < 1e-5);
829    }
830
831    #[test]
832    fn get_success_rate_vec_solution_half_01() {
833        let results: Vec<Option<Solution<Vec<f32>>>> = vec![Some((vec![1.01_f32], 0.0_f64)), None];
834        let expected = vec![1.0];
835        let delta = vec![0.1];
836        let predicate = get_predicate_success_vec_solution(expected, delta);
837
838        assert!((results.get_success_rate(&predicate).unwrap() - 0.5).abs() < 1e-5);
839    }
840
841    #[test]
842    fn get_success_rate_vec_solution_half_02() {
843        let results: Vec<Option<Solution<Vec<f32>>>> = vec![
844            Some((vec![0.01_f32, 1.01_f32], 0.0_f64)),
845            Some((vec![0.01_f32, 1.2_f32], 0.0_f64)),
846        ];
847        let expected = vec![0.0, 1.0];
848        let delta = vec![0.1, 0.1];
849        let predicate = get_predicate_success_vec_solution(expected, delta);
850
851        assert!((results.get_success_rate(&predicate).unwrap() - 0.5).abs() < 1e-5);
852    }
853
854    #[test]
855    fn call_count_data_average_empty() {
856        let data = CallCountData::new();
857        assert_eq!(data.get_call_count(), vec![]);
858        assert_eq!(data.get_average_call_count(), None);
859    }
860
861    #[test]
862    fn call_count_data_average_single_zero() {
863        let mut data = CallCountData::new();
864        data.next_run();
865
866        assert_eq!(data.get_call_count(), vec![0]);
867        assert!((data.get_average_call_count().unwrap() - 0.0) < 1e-5);
868    }
869
870    #[test]
871    fn call_count_data_average_single_one() {
872        let mut data = CallCountData::new();
873        data.next_run();
874        data.increment();
875
876        assert_eq!(data.get_call_count(), vec![1]);
877        assert!((data.get_average_call_count().unwrap() - 1.0) < 1e-5);
878    }
879
880    #[test]
881    fn call_count_data_average_single_two() {
882        let mut data = CallCountData::new();
883        data.next_run();
884        data.add(5);
885
886        assert_eq!(data.get_call_count(), vec![5]);
887        assert!((data.get_average_call_count().unwrap() - 5.0) < 1e-5);
888    }
889
890    #[test]
891    fn call_count_data_average_several() {
892        let mut data = CallCountData::new();
893        data.next_run();
894        data.add(5);
895        data.next_run();
896        data.add(7);
897
898        assert_eq!(data.get_call_count(), vec![5, 7]);
899        assert!((data.get_average_call_count().unwrap() - 6.0) < 1e-5);
900    }
901
902    #[test]
903    fn statistics_convergence_unite_empty() {
904        let mut stat_1: Statistics<f32> = Statistics::new();
905        let stat_2: Statistics<f32> = Statistics::new();
906
907        let valid_results: Vec<Option<Solution<f32>>> = vec![];
908        let valid_convergence: Convergence<f32> = vec![];
909
910        stat_1.unite(stat_2);
911        assert_eq!(stat_1.results, valid_results);
912        assert_eq!(stat_1.convergence, valid_convergence);
913    }
914
915    #[test]
916    fn statistics_unite_results_01() {
917        let mut stat_1: Statistics<f32> = Statistics::new();
918        let stat_2: Statistics<f32> = Statistics::new();
919
920        let valid_results: Vec<Option<Solution<f32>>> = vec![Some((1.0_f32, 0.0))];
921        stat_1.results.push(Some((1.0_f32, 0.0)));
922
923        stat_1.unite(stat_2);
924        assert_eq!(stat_1.results, valid_results);
925    }
926
927    #[test]
928    fn statistics_unite_results_02() {
929        let mut stat_1: Statistics<f32> = Statistics::new();
930        let mut stat_2: Statistics<f32> = Statistics::new();
931
932        let valid_results: Vec<Option<Solution<f32>>> = vec![Some((1.0_f32, 0.0))];
933        stat_2.results.push(Some((1.0_f32, 0.0)));
934
935        stat_1.unite(stat_2);
936        assert_eq!(stat_1.results, valid_results);
937    }
938
939    #[test]
940    fn statistics_unite_results_03() {
941        let mut stat_1: Statistics<f32> = Statistics::new();
942        let mut stat_2: Statistics<f32> = Statistics::new();
943
944        let valid_results: Vec<Option<Solution<f32>>> =
945            vec![Some((1.0_f32, 0.0)), Some((2.0_f32, 1.0))];
946
947        stat_1.results.push(Some((1.0_f32, 0.0)));
948        stat_2.results.push(Some((2.0_f32, 1.0)));
949
950        stat_1.unite(stat_2);
951        assert_eq!(stat_1.results, valid_results);
952    }
953
954    #[test]
955    fn convergence_unite_01() {
956        let mut stat_1: Statistics<f32> = Statistics::new();
957        let stat_2: Statistics<f32> = Statistics::new();
958
959        let valid_convergence: Convergence<f32> =
960            vec![vec![Some((1.0_f32, 0.0)), Some((2.0_f32, 1.0))]];
961
962        stat_1
963            .convergence
964            .push(vec![Some((1.0_f32, 0.0)), Some((2.0_f32, 1.0))]);
965
966        stat_1.unite(stat_2);
967        assert_eq!(stat_1.convergence, valid_convergence);
968    }
969
970    #[test]
971    fn convergence_unite_02() {
972        let mut stat_1: Statistics<f32> = Statistics::new();
973        let mut stat_2: Statistics<f32> = Statistics::new();
974
975        let valid_convergence: Convergence<f32> =
976            vec![vec![Some((1.0_f32, 0.0)), Some((2.0_f32, 1.0))]];
977
978        stat_2
979            .convergence
980            .push(vec![Some((1.0_f32, 0.0)), Some((2.0_f32, 1.0))]);
981
982        stat_1.unite(stat_2);
983        assert_eq!(stat_1.convergence, valid_convergence);
984    }
985
986    #[test]
987    fn convergence_unite_04() {
988        let mut stat_1: Statistics<f32> = Statistics::new();
989        let mut stat_2: Statistics<f32> = Statistics::new();
990
991        let valid_convergence: Convergence<f32> = vec![
992            vec![Some((1.0_f32, 0.0)), Some((2.0_f32, 1.0))],
993            vec![Some((10.0_f32, 10.0)), Some((20.0_f32, 2.0))],
994        ];
995
996        stat_1
997            .convergence
998            .push(vec![Some((1.0_f32, 0.0)), Some((2.0_f32, 1.0))]);
999
1000        stat_2
1001            .convergence
1002            .push(vec![Some((10.0_f32, 10.0)), Some((20.0_f32, 2.0))]);
1003
1004        stat_1.unite(stat_2);
1005        assert_eq!(stat_1.convergence, valid_convergence);
1006    }
1007
1008    #[test]
1009    fn call_count_data_unite_empty() {
1010        let mut call_count_1 = CallCountData::new();
1011        let call_count_2 = CallCountData::new();
1012
1013        let valid_call_count_stat: Vec<usize> = vec![];
1014
1015        call_count_1.unite(call_count_2);
1016
1017        assert_eq!(call_count_1.0, valid_call_count_stat);
1018    }
1019
1020    #[test]
1021    fn call_count_data_unite_01() {
1022        let mut call_count_1 = CallCountData::new();
1023        let call_count_2 = CallCountData::new();
1024
1025        let valid_call_count_stat: Vec<usize> = vec![100];
1026
1027        call_count_1.0.push(100);
1028        call_count_1.unite(call_count_2);
1029
1030        assert_eq!(call_count_1.0, valid_call_count_stat);
1031    }
1032
1033    #[test]
1034    fn call_count_data_unite_02() {
1035        let mut call_count_1 = CallCountData::new();
1036        let mut call_count_2 = CallCountData::new();
1037
1038        let valid_call_count_stat: Vec<usize> = vec![100];
1039
1040        call_count_2.0.push(100);
1041        call_count_1.unite(call_count_2);
1042
1043        assert_eq!(call_count_1.0, valid_call_count_stat);
1044    }
1045
1046    #[test]
1047    fn call_count_data_unite_03() {
1048        let mut call_count_1 = CallCountData::new();
1049        let mut call_count_2 = CallCountData::new();
1050
1051        let valid_call_count_stat: Vec<usize> = vec![100, 200];
1052
1053        call_count_1.0.push(100);
1054        call_count_2.0.push(200);
1055
1056        call_count_1.unite(call_count_2);
1057
1058        assert_eq!(call_count_1.0, valid_call_count_stat);
1059    }
1060}