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
//! # Modification factor schedules
//!
//! This module provides implementations of the [`Schedule`] trait for
//! controlling how the modification factor (`ln_f`) changes during
//! Wang-Landau sampling.
//!
//! Two common schedules are provided:
//!
//! - [`Geometric`]: Reduces ln_f by a constant factor (e.g., ln_f *= 0.5)
//! - [`OneOverT`]: Uses the Belardinelli-Pereyra 1/t schedule
//!
//! Custom schedules can be implemented by implementing the [`Schedule`] trait.
use crateSchedule;
/// A geometric schedule that multiplies `ln_f` by a constant factor.
///
/// This is the original schedule proposed in the Wang-Landau algorithm,
/// where the modification factor is reduced by a constant factor (typically 0.5)
/// whenever the histogram becomes flat.
///
/// # Fields
///
/// * `alpha` - The factor by which ln_f is multiplied (0 < alpha < 1)
/// * `tol` - The convergence tolerance for ln_f
///
/// # Example
///
/// ```
/// use wanglandau::prelude::*;
///
/// let mut ln_f = 1.0;
/// let mut schedule = Geometric { alpha: 0.5, tol: 1e-8 };
///
/// // Update ln_f geometrically
/// let converged = schedule.update(&mut ln_f);
/// assert_eq!(ln_f, 0.5); // ln_f *= 0.5
/// assert_eq!(converged, false); // Not yet below tolerance
///
/// // After many updates...
/// // converged will be true when ln_f < 1e-8
/// ```
/// A 1/t schedule for ln_f, following the Belardinelli-Pereyra algorithm.
///
/// This schedule sets ln_f = 1/t, where t is the number of updates performed.
/// This provides provably optimal convergence for Wang-Landau sampling.
///
/// # Fields
///
/// * `t` - The current time step (internal counter)
/// * `tol` - The convergence tolerance for ln_f
///
/// # Example
///
/// ```
/// use wanglandau::prelude::*;
///
/// let mut ln_f = 1.0;
/// let mut schedule = OneOverT::default();
///
/// // Update ln_f using 1/t schedule
/// let converged = schedule.update(&mut ln_f);
/// assert_eq!(ln_f, 0.5); // ln_f = 1/2
/// assert_eq!(converged, false);
///
/// // Update again
/// let converged = schedule.update(&mut ln_f);
/// assert_eq!(ln_f, 1.0/3.0); // ln_f = 1/3
/// assert_eq!(converged, false);
///
/// // After many updates...
/// // converged will be true when ln_f < tol (default 1e-8)
/// ```