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
use num::Float;
use numeric_literals::replace_float_literals;
use rand::prelude::*;
use rand_distr::{uniform::SampleUniform, Uniform};
use std::fmt::Debug;
pub enum APF<F, R>
where
F: Float + SampleUniform,
R: Rng,
{
Metropolis,
Custom {
f: fn(diff: F, t: F, uni: &Uniform<F>, rng: &mut R) -> bool,
},
}
impl<F, R> APF<F, R>
where
F: Float + SampleUniform + Debug,
R: Rng,
{
#[replace_float_literals(F::from(literal).unwrap())]
pub fn accept(&self, diff: F, t: F, uni: &Uniform<F>, rng: &mut R) -> bool {
match self {
APF::Metropolis => diff <= 0. || uni.sample(rng) < F::min(F::exp(-diff / t), 1.),
APF::Custom { f } => f(diff, t, uni, rng),
}
}
}