convex_math/extrapolation/
linear.rs1use super::Extrapolator;
4
5#[derive(Debug, Clone, Copy, Default)]
39pub struct LinearExtrapolator;
40
41impl LinearExtrapolator {
42 #[must_use]
44 pub fn new() -> Self {
45 Self
46 }
47}
48
49impl Extrapolator for LinearExtrapolator {
50 fn extrapolate(&self, t: f64, last_t: f64, last_value: f64, last_derivative: f64) -> f64 {
51 last_value + last_derivative * (t - last_t)
53 }
54
55 fn name(&self) -> &'static str {
56 "Linear"
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use approx::assert_relative_eq;
64
65 #[test]
66 fn test_linear_extrapolation() {
67 let extrap = LinearExtrapolator::new();
68
69 let last_t = 10.0;
70 let last_value = 0.05;
71 let last_deriv = 0.001; let value = extrap.extrapolate(15.0, last_t, last_value, last_deriv);
75 assert_relative_eq!(value, 0.055, epsilon = 1e-10);
76
77 let value = extrap.extrapolate(20.0, last_t, last_value, last_deriv);
79 assert_relative_eq!(value, 0.06, epsilon = 1e-10);
80 }
81
82 #[test]
83 fn test_linear_with_negative_slope() {
84 let extrap = LinearExtrapolator;
85
86 let last_t = 20.0;
87 let last_value = 0.04;
88 let last_deriv = -0.0005; let value = extrap.extrapolate(30.0, last_t, last_value, last_deriv);
92 assert_relative_eq!(value, 0.035, epsilon = 1e-10);
93 }
94
95 #[test]
96 fn test_linear_at_boundary() {
97 let extrap = LinearExtrapolator;
98
99 let last_t = 10.0;
100 let last_value = 0.05;
101 let last_deriv = 0.001;
102
103 let value = extrap.extrapolate(last_t, last_t, last_value, last_deriv);
105 assert_relative_eq!(value, last_value, epsilon = 1e-15);
106 }
107
108 #[test]
109 fn test_linear_with_zero_slope() {
110 let extrap = LinearExtrapolator;
111
112 let last_t = 10.0;
113 let last_value = 0.03;
114 let last_deriv = 0.0;
115
116 for t in [15.0, 20.0, 50.0, 100.0] {
118 let value = extrap.extrapolate(t, last_t, last_value, last_deriv);
119 assert_relative_eq!(value, last_value, epsilon = 1e-15);
120 }
121 }
122
123 #[test]
124 fn test_linear_name() {
125 let extrap = LinearExtrapolator;
126 assert_eq!(extrap.name(), "Linear");
127 }
128}