use brk_traversable::Traversable;
use brk_types::{PartsPerMillion64, PartsPerMillionSigned32, Version};
use vecdb::UnaryTransform;
use crate::internal::{LazyPerBlock, LazyRatioPerBlock};
use crate::distribution::metrics::ImportConfig;
const VERSION: Version = Version::new(5);
#[derive(Clone, Traversable)]
pub struct UnrealizedMinimal {
pub nupl: LazyRatioPerBlock<PartsPerMillionSigned32, PartsPerMillion64>,
}
impl UnrealizedMinimal {
pub(crate) fn new(cfg: &ImportConfig, mvrv: &LazyPerBlock<PartsPerMillion64>) -> Self {
Self {
nupl: LazyRatioPerBlock::from_lazy_source::<MvrvToNupl, PartsPerMillion64>(
&cfg.name("nupl"),
cfg.version + VERSION,
mvrv,
),
}
}
}
struct MvrvToNupl;
impl UnaryTransform<PartsPerMillion64, PartsPerMillionSigned32> for MvrvToNupl {
#[inline(always)]
fn apply(mvrv: PartsPerMillion64) -> PartsPerMillionSigned32 {
PartsPerMillionSigned32::from(1.0 - 1.0 / f64::from(mvrv))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nupl_is_derived_from_mvrv() {
assert_eq!(
MvrvToNupl::apply(PartsPerMillion64::from(2.0)),
PartsPerMillionSigned32::from(0.5),
);
assert_eq!(
MvrvToNupl::apply(PartsPerMillion64::from(1.0)),
PartsPerMillionSigned32::ZERO,
);
assert!(MvrvToNupl::apply(PartsPerMillion64::NAN).is_nan());
assert!(MvrvToNupl::apply(PartsPerMillion64::ZERO).is_nan());
}
}