use {
crate::{wang_landau::*, Histogram},
std::io::Write,
};
pub trait WangLandau {
fn log_f(&self) -> f64;
fn log_f_threshold(&self) -> f64;
fn set_log_f_threshold(&mut self, log_f_threshold: f64) -> Result<f64, WangLandauErrors>;
#[inline(always)]
fn is_finished(&self) -> bool {
self.log_f() <= self.log_f_threshold()
}
fn log_density(&self) -> &Vec<f64>;
fn log_density_base10(&self) -> Vec<f64> {
self.log_density()
.iter()
.map(|val| val * std::f64::consts::LOG10_E)
.collect()
}
fn log_density_base(&self, base: f64) -> Vec<f64> {
let factor = std::f64::consts::E.log(base);
self.log_density().iter().map(|val| val * factor).collect()
}
fn write_log<W: Write>(&self, writer: W) -> Result<(), std::io::Error>;
fn mode(&self) -> WangLandauMode;
fn step_counter(&self) -> usize;
fn steps_total(&self) -> usize {
self.total_steps_accepted() + self.total_steps_rejected()
}
fn total_steps_accepted(&self) -> usize;
fn total_steps_rejected(&self) -> usize;
fn fraction_accepted_total(&self) -> f64 {
let total_acc = self.total_steps_accepted();
let total_steps = total_acc + self.total_steps_rejected();
if total_steps == 0 {
f64::NAN
} else {
total_acc as f64 / total_steps as f64
}
}
fn fraction_rejected_total(&self) -> f64 {
let total_rej = self.total_steps_rejected();
let total_steps = total_rej + self.total_steps_accepted();
if total_steps == 0 {
f64::NAN
} else {
total_rej as f64 / total_steps as f64
}
}
}
pub trait WangLandauEnsemble<E>: WangLandau {
fn ensemble(&self) -> &E;
unsafe fn ensemble_mut(&mut self) -> &mut E;
}
pub trait WangLandauHist<Hist>: WangLandau {
fn hist(&self) -> &Hist;
}
pub trait WangLandauEnergy<Energy>: WangLandau {
fn energy(&self) -> Option<&Energy>;
}
pub trait WangLandauEEH<E, Hist, Energy>:
WangLandauEnergy<Energy> + WangLandauEnsemble<E> + WangLandauHist<Hist>
{
}
impl<A, E, Hist, Energy> WangLandauEEH<E, Hist, Energy> for A where
A: WangLandauEnergy<Energy> + WangLandauEnsemble<E> + WangLandauHist<Hist>
{
}
pub(crate) trait WangLandau1TCalc<Hist>: WangLandauHist<Hist>
where
Hist: Histogram,
{
#[inline(always)]
fn log_f_1_t(&self) -> f64 {
self.hist().bin_count() as f64 / self.step_counter() as f64
}
}
impl<A, Hist> WangLandau1TCalc<Hist> for A
where
A: WangLandauHist<Hist>,
Hist: Histogram,
{
}