1use core::f64::consts::LN_2;
8use core::time::Duration;
9#[allow(unused_imports)]
10use irox_tools::f64::FloatExt;
11
12#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
16pub struct HalfLife(Duration);
17
18#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
21pub struct MeanLifetime(Duration);
22
23#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
26pub struct DecayConstant(Duration);
27
28impl From<Duration> for HalfLife {
29 fn from(value: Duration) -> Self {
30 Self(value)
31 }
32}
33impl From<Duration> for DecayConstant {
34 fn from(value: Duration) -> Self {
35 Self(value)
36 }
37}
38impl From<Duration> for MeanLifetime {
39 fn from(value: Duration) -> Self {
40 Self(value)
41 }
42}
43
44impl From<MeanLifetime> for DecayConstant {
45 fn from(value: MeanLifetime) -> Self {
46 let var = 1.0 / value.0.as_secs_f64();
47 DecayConstant(Duration::from_secs_f64(var))
48 }
49}
50
51impl From<DecayConstant> for MeanLifetime {
52 fn from(value: DecayConstant) -> Self {
53 let var = 1.0 / value.0.as_secs_f64();
54 MeanLifetime(Duration::from_secs_f64(var))
55 }
56}
57
58impl From<DecayConstant> for HalfLife {
59 fn from(value: DecayConstant) -> Self {
60 let var = value.0.as_secs_f64();
61 HalfLife(Duration::from_secs_f64(LN_2 / var))
62 }
63}
64
65impl From<MeanLifetime> for HalfLife {
66 fn from(value: MeanLifetime) -> Self {
67 let var = value.0.as_secs_f64();
68 HalfLife(Duration::from_secs_f64(var * LN_2))
69 }
70}
71
72impl MeanLifetime {
73 pub fn decay_factor_at(&self, time: &Duration) -> f64 {
74 (-time.as_secs_f64() / self.0.as_secs_f64()).exp()
75 }
76}
77
78impl HalfLife {
79 pub fn decay_factor_at(&self, time: &Duration) -> f64 {
80 2.0_f64.powf(-time.as_secs_f64() / self.0.as_secs_f64())
81 }
82}