use bustools_core::utils::{self, get_progressbar};
use itertools::izip;
use statrs::distribution::Binomial;
use statrs::distribution::Discrete;
use crate::utils::logspace;
pub fn phantom_binomial_regression(z: &[usize], mr: &[usize], r:&[usize], s: usize) -> (f64, Vec<f64>, Vec<f64>){
assert_eq!(z.len() , r.len());
let s_f64 = s as f64;
let n = 10000;
let mut prange: Vec<f64> = logspace(-7.0, 0.0, n);
prange.pop();
let mut loglike_range: Vec<f64> = Vec::with_capacity(n);
let bar = get_progressbar(n as u64);
for _p in prange.iter(){
let mut loglike = 0.0;
for (zi, mri, ri) in izip!(z, mr, r){
loglike += loglike_fn(*_p, *zi, *mri, *ri, s_f64);
}
bar.inc(1);
loglike_range.push(loglike);
}
let (ix_max, _loglike_max) = utils::argsort::argmax_float(&loglike_range);
let pmax = prange[ix_max];
(pmax, prange, loglike_range)
}
fn loglike_fn(p: f64, zi: usize, mri: usize, ri: usize, s_f64: f64) -> f64{
let ri_f64 = ri as f64;
let correction_factor = (s_f64-1.0)* (p/(s_f64-1.0)).powf(ri_f64);
let mut p_binomial = (1.0-p).powf(ri_f64) + correction_factor;
if p_binomial > 1.0{
p_binomial= 1.0;
}
let b_rv = Binomial::new(p_binomial, mri as u64).unwrap_or_else(|_| panic!("p {}", p_binomial));
let loglike_inc = b_rv.ln_pmf(zi as u64);
loglike_inc
}
#[cfg(test)]
mod test{
}