use fix::prelude::*;
use fix::typed_floats::StrictlyPositiveFinite;
use fix::typenum::Integer;
use crate::error::CoreError;
pub fn positive<Exp: Integer>(
value: UFix64<Exp>,
) -> Result<StrictlyPositiveFinite, CoreError> {
value
.to_positive_f64()
.ok_or(CoreError::MarginalRateInvalid)
}
pub fn positive_rate(rate: f64) -> Result<f64, CoreError> {
StrictlyPositiveFinite::try_from(rate)
.map(|checked| checked.get())
.map_err(|_| CoreError::MarginalRateInvalid)
}
#[must_use]
pub fn quotient_rule(
numerator: StrictlyPositiveFinite,
d_numerator: f64,
denominator: StrictlyPositiveFinite,
d_denominator: f64,
scale: StrictlyPositiveFinite,
) -> f64 {
let denominator = denominator.get();
(d_numerator * denominator - numerator.get() * d_denominator) * scale.get()
/ (denominator * denominator)
}
#[must_use]
pub fn chain_rule(curve_slope: f64, d_inner: f64) -> f64 {
if curve_slope == 0.0 {
0.0
} else {
curve_slope * d_inner
}
}