use crate::error::SampleError;
use rand::Rng;
pub trait ConditionalFactorization {
fn dim(&self) -> usize;
fn sample_i<R: Rng + ?Sized>(&self, rng: &mut R, i: usize, prefix: &[f64]) -> f64;
}
pub struct ConditionalFactorSampler<F> {
inner: F,
}
impl<F> ConditionalFactorSampler<F>
where
F: ConditionalFactorization,
{
pub fn new(inner: F) -> Self {
Self { inner }
}
pub fn sample(&self) -> Result<Vec<f64>, SampleError> {
self.sample_with_rng(&mut rand::rng())
}
pub fn sample_with_rng<R: Rng + ?Sized>(&self, rng: &mut R) -> Result<Vec<f64>, SampleError> {
let dim = self.inner.dim();
if dim == 0 {
return Err(SampleError::McmcFailed);
}
let mut out = Vec::with_capacity(dim);
for i in 0..dim {
let v = self.inner.sample_i(rng, i, &out);
out.push(v);
}
Ok(out)
}
}