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
use std::cmp::*;
#[cfg(feature = "serde_support")]
use serde::{Serialize, Deserialize};
/// List of possible errors
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub enum WangLandauErrors{
/// `trial_step_min <= trial_step_max` has to be true
InvalidMinMaxTrialSteps,
/// `log_f_threshold`can never be negative or zero!
/// it also cannot be NaN or infinite!
InvalidLogFThreshold,
/// Still in the process of gathering statistics
/// Not enough to make an estimate
NotEnoughStatistics,
/// Still Gathering Statistics, this is only an estimate!
EstimatedStatistic(Vec<f64>),
/// bestof has to be at least 1 and at most the number of distinct steps tried,
/// i.e., max_step - min_step + 1
InvalidBestof,
/// check refine has to be at least 1
CheckRefineEvery0,
/// you have to call one of the
NotInitialized,
/// Step limit exceeded without finding valid starting point
InitFailed
}
/// Look at the paper
/// > R. E. Belardinelli and V. D. Pereyra,
/// > Fast algorithm to calculate density of states,”
/// > Phys. Rev. E **75**: 046701 (2007), DOI [10.1103/PhysRevE.75.046701](https://doi.org/10.1103/PhysRevE.75.046701)
/// * This enum is to see, which mode is currently used
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub enum WangLandauMode {
/// * Using original wang landau, i.e.,
/// refine every time when every bin in the
/// histogram was hit
/// * refine: `log_f *= 0.5;
RefineOriginal,
/// * Use 1/T approach
/// * refine each step by: `log_f = bin_count as f64 / step_count as f64`
Refine1T
}
impl WangLandauMode{
/// * true if self is `RefineOriginal` variant
/// * false otherwise
pub fn is_mode_original(&self) -> bool {
matches!(self, WangLandauMode::RefineOriginal)
}
/// * true if self is `Refine1T` variant
/// * false otherwise
pub fn is_mode_1_t(&self) -> bool {
matches!(self, WangLandauMode::Refine1T)
}
}
pub(crate) struct ProbIndex{
pub(crate) index: usize,
diff: f64
}
impl PartialEq for ProbIndex{
fn eq(&self, other: &Self) -> bool {
self.index == other.index
&&
self.diff == other.diff
}
}
impl Eq for ProbIndex{}
impl PartialOrd for ProbIndex{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ProbIndex{
fn cmp(&self, other: &Self) -> Ordering {
self.diff.total_cmp(&other.diff)
}
}
impl ProbIndex{
pub(crate) fn new(prob: f64, index: usize) -> Self
{
debug_assert!(prob.is_finite());
Self{
index,
diff: (0.5 - prob).copysign(-1.0)
}
}
pub(crate) fn is_best_of(&self, threshold: f64) -> bool
{
self.diff >= -threshold
}
}