non_convex_opt/algorithms/parallel_tempering/
replica_exchange.rs

1use rand::prelude::*;
2use rand::rng;
3
4pub enum SwapCheck {
5    Periodic(Periodic),
6    Stochastic(Stochastic),
7    Always(Always),
8}
9
10pub struct Periodic {
11    pub swap_frequency: f64,
12    pub total_steps: usize,
13}
14
15impl Periodic {
16    pub fn new(swap_frequency: f64, total_steps: usize) -> Self {
17        Self {
18            swap_frequency,
19            total_steps,
20        }
21    }
22
23    pub fn should_swap(&self, current_step: usize) -> bool {
24        current_step % (self.swap_frequency * self.total_steps as f64) as usize == 0
25    }
26}
27
28pub struct Stochastic {
29    pub swap_probability: f64,
30}
31
32impl Stochastic {
33    pub fn new(swap_probability: f64) -> Self {
34        Self { swap_probability }
35    }
36
37    pub fn should_swap(&self, _current_step: usize) -> bool {
38        rng().random::<f64>() < self.swap_probability
39    }
40}
41
42#[derive(Default)]
43pub struct Always {}
44
45impl Always {
46    pub fn new() -> Self {
47        Self {}
48    }
49
50    pub fn should_swap(&self, _current_step: usize) -> bool {
51        true
52    }
53}