1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Utility functions for the frostfire library.
//!
//! This module provides various helper functions and utilities
//! that may be useful when working with simulated annealing.
use ;
/// Measures the execution time of a function.
///
/// This is useful for benchmarking different annealing configurations.
///
/// # Parameters
///
/// * `f`: A function to execute and measure
///
/// # Returns
///
/// A tuple containing the function's return value and the execution duration.
///
/// # Examples
///
/// ```
/// use frostfire::utils::time_execution;
/// use std::thread::sleep;
/// use std::time::Duration;
///
/// let (result, duration) = time_execution(|| {
/// sleep(Duration::from_millis(10));
/// 42
/// });
///
/// assert_eq!(result, 42);
/// assert!(duration.as_millis() >= 10);
/// ```
/// Calculates the average of a slice of f64 values.
///
/// # Parameters
///
/// * `values`: A slice of f64 values
///
/// # Returns
///
/// The average of the values, or 0.0 if the slice is empty.
///
/// # Examples
///
/// ```
/// use frostfire::utils::average;
///
/// let values = [1.0, 2.0, 3.0, 4.0, 5.0];
/// assert_eq!(average(&values), 3.0);
/// ```
/// Calculates the standard deviation of a slice of f64 values.
///
/// # Parameters
///
/// * `values`: A slice of f64 values
///
/// # Returns
///
/// The standard deviation of the values, or 0.0 if the slice has fewer than 2 elements.
///
/// # Examples
///
/// ```
/// use frostfire::utils::standard_deviation;
///
/// let values = [1.0, 2.0, 3.0, 4.0, 5.0];
/// assert!((standard_deviation(&values) - 1.581139).abs() < 1e-6);
/// ```
/// Computes the Boltzmann acceptance probability.
///
/// This is the probability used in the Metropolis acceptance criterion.
///
/// # Parameters
///
/// * `delta`: The energy difference (new_energy - current_energy)
/// * `temperature`: The current temperature
///
/// # Returns
///
/// The acceptance probability as a value between 0 and 1.
///
/// # Examples
///
/// ```
/// use frostfire::utils::boltzmann_probability;
///
/// // Improvements always have probability 1
/// assert_eq!(boltzmann_probability(-1.0, 1.0), 1.0);
///
/// // Worse solutions have lower probability
/// let p = boltzmann_probability(2.0, 1.0);
/// assert!(p > 0.0 && p < 1.0);
///
/// // Higher temperature increases acceptance probability
/// assert!(boltzmann_probability(1.0, 2.0) > boltzmann_probability(1.0, 1.0));
/// ```