use derive_getters::Getters;
use optimal_core::prelude::*;
use crate::{types::*, Pbil};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub trait Probabilities {
fn probabilities(&self) -> &[Probability];
}
impl<B, F> Probabilities for Pbil<B, F> {
fn probabilities(&self) -> &[Probability] {
self.state().probabilities()
}
}
#[derive(Clone, Debug, Getters)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct UntilProbabilitiesConverged<I> {
config: UntilProbabilitiesConvergedConfig,
it: I,
}
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct UntilProbabilitiesConvergedConfig {
pub threshold: ProbabilityThreshold,
}
impl UntilProbabilitiesConvergedConfig {
pub fn start<I>(self, it: I) -> UntilProbabilitiesConverged<I> {
UntilProbabilitiesConverged { config: self, it }
}
}
impl<I> UntilProbabilitiesConverged<I> {
pub fn into_inner(self) -> (UntilProbabilitiesConvergedConfig, I) {
(self.config, self.it)
}
}
impl<I> StreamingIterator for UntilProbabilitiesConverged<I>
where
I: StreamingIterator + Probabilities,
{
type Item = I::Item;
fn advance(&mut self) {
self.it.advance()
}
fn get(&self) -> Option<&Self::Item> {
self.it.get()
}
fn is_done(&self) -> bool {
self.it.is_done()
|| self.it.probabilities().iter().all(|p| {
p > &self.config.threshold.upper_bound() || p < &self.config.threshold.lower_bound()
})
}
}