use std::io::Write;
pub trait Entropic {
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
}
}
fn step_goal(&self) -> usize;
fn is_finished(&self) -> bool {
self.step_counter() >= self.step_goal()
}
fn log_density(&self) -> Vec<f64>;
fn log_density_base10(&self) -> Vec<f64> {
let mut density = self.log_density();
density
.iter_mut()
.for_each(|val| *val *= std::f64::consts::LOG10_E);
density
}
fn log_density_base(&self, base: f64) -> Vec<f64> {
let factor = std::f64::consts::E.log(base);
let mut density = self.log_density();
density.iter_mut().for_each(|val| *val *= factor);
density
}
fn write_log<W: Write>(&self, writer: W) -> Result<(), std::io::Error>;
}
pub trait EntropicEnsemble<E>: Entropic {
fn ensemble(&self) -> &E;
unsafe fn ensemble_mut(&mut self) -> &mut E;
}
pub trait EntropicHist<Hist>: Entropic {
fn hist(&self) -> &Hist;
}
pub trait EntropicEnergy<Energy>: Entropic {
fn energy(&self) -> &Energy;
}
pub trait EntropicEEH<E, Hist, Energy>:
EntropicEnergy<Energy> + EntropicEnsemble<E> + EntropicHist<Hist>
{
}
impl<A, E, Hist, Energy> EntropicEEH<E, Hist, Energy> for A where
A: EntropicEnergy<Energy> + EntropicEnsemble<E> + EntropicHist<Hist>
{
}