1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use crate::Number; use super::Term; ///A struct assigning to each piece of the function a time after which it is applicable. The term ///will be the evluated one until t passes the next part's after value struct PiecewisePair<T: Number> { term: Box<dyn Term<T>>, after: T //The time after which to apply the term } ///Struct containing a list of terms and times which split the number line into intervals during ///which different terms are applied pub struct PiecewiseTerm<T: Number> { parts: Vec<PiecewisePair<T>> } impl<T: Number> PiecewiseTerm<T> { ///Creates a PiecewiseTerm, which is initialized to contain no terms. Terms and times must be ///added using add_part pub fn new() -> PiecewiseTerm<T> { return PiecewiseTerm { parts: Vec::new() }; } ///Adds on a term to the piecewise function. /// /// # Examples /// /// ``` /// use crate::parametrizer::term::piecewiseterm::PiecewiseTerm; /// use crate::parametrizer::term::constantterm::ConstantTerm; /// use crate::parametrizer::term::Term; /// /// let mut piecewise = PiecewiseTerm::new(); /// /// let const1 = ConstantTerm::new(3); /// let const2 = ConstantTerm::new(5); /// let const3 = ConstantTerm::new(9); /// /// piecewise.add_part(Box::new(const1), 0); /// piecewise.add_part(Box::new(const2), 5); /// piecewise.add_part(Box::new(const3), 10); /// /// assert_eq!(3, piecewise.evaluate(2)); /// assert_eq!(5, piecewise.evaluate(8)); /// assert_eq!(9, piecewise.evaluate(20)); /// ``` pub fn add_part(&mut self, term: Box<dyn Term<T>>, after: T) { self.parts.push(PiecewisePair::<T> { term, after }); } } impl<T: Number> Term<T> for PiecewiseTerm<T> { ///Iterates through all of the piecewise parts, returning the evluation of the term assigned to ///the the interval containing t fn evaluate(&self, t: T) -> T { let mut iter = self.parts.iter(); let mut current = match iter.next() { Some(t) => &t.term, None => return T::zero() }; for part in iter { if t >= part.after { current = &part.term; } else { return current.evaluate(t); } } return current.evaluate(t); } }