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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
use super::{Error, Sequence}; use std::fmt; /// Trait for creating methods for timeseries /// /// # Regular methods usage /// /// ### Iterate over vector's values /// /// ``` /// use yata::methods::SMA; /// use yata::prelude::*; /// /// let s: Vec<_> = vec![1.,2.,3.,4.,5.,6.,7.,8.,9.,10.]; /// let mut ma = SMA::new(2, s[0]).unwrap(); /// /// s.iter().enumerate().for_each(|(index, &value)| { /// assert_eq!(ma.next(value), (value + s[index.saturating_sub(1)])/2.); /// }); /// ``` /// /// ### Get a whole new vector over the input vector /// /// ``` /// use yata::methods::SMA; /// use yata::prelude::*; /// /// let s: Vec<_> = vec![1.,2.,3.,4.,5.,6.,7.,8.,9.,10.]; /// let mut ma = SMA::new(2, s[0]).unwrap(); /// /// let result = ma.over(s.iter().copied()); /// assert_eq!(result.as_slice(), &[1., 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]); /// ``` /// /// ### Change vector values using method /// /// ``` /// use yata::core::Sequence; /// use yata::methods::SMA; /// use yata::prelude::*; /// /// let mut s: Sequence<_> = Sequence::from(vec![1.,2.,3.,4.,5.,6.,7.,8.,9.,10.]); /// let mut ma = SMA::new(2, s[0]).unwrap(); /// /// s.apply(&mut ma); /// assert_eq!(s.as_slice(), &[1., 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]); /// ``` /// /// # Be advised /// There is no `reset` method on the trait. If you need reset a state of the `Method` instance, you should just create a new one. pub trait Method: fmt::Debug { /// Method parameters type Params; /// Input value type type Input: Copy; /// Output value type type Output: Copy; // = Self::Input; /// Static method for creating an instance of the method with given `parameters` and initial `value` (simply first input value) fn new(parameters: Self::Params, initial_value: Self::Input) -> Result<Self, Error> where Self: Sized; /// Generates next output value based on the given input `value` fn next(&mut self, value: Self::Input) -> Self::Output; /// Returns a name of the method fn name(&self) -> &str { let parts = std::any::type_name::<Self>().split("::"); parts.last().unwrap_or_default() } /// Returns memory size of the method `(size, align)` fn memsize(&self) -> (usize, usize) where Self: Sized, { (std::mem::size_of::<Self>(), std::mem::align_of::<Self>()) } /// Creates an `iterator` which produces values by the `Method` over given input data `Iterator` fn iter_data<I>(&mut self, input: I) -> MethodOverIterator<Self, I> where I: Iterator<Item = Self::Input>, Self: Sized, { MethodOverIterator::new(self, input) } /// Iterates the `Method` over the given `Iterator` and returns timeserie of output values /// /// # Guarantees /// /// The length of an output `Sequence` is always equal to the length of input one /// ``` /// use yata::methods::SMA; /// use yata::prelude::*; /// /// let s: Vec<_> = vec![1.,2.,3.,4.,5.,6.,7.,8.,9.,10.]; /// let mut ma = SMA::new(5, s[0]).unwrap(); /// /// let result = ma.over(s.iter().copied()); /// assert_eq!(result.len(), s.len()); /// ``` /// /// ``` /// use yata::methods::SMA; /// use yata::prelude::*; /// /// let s: Vec<_> = vec![1.,2.,3.,4.,5.,6.,7.,8.,9.,10.]; /// let mut ma = SMA::new(100, s[0]).unwrap(); /// /// let result = ma.over(s.iter().copied()); /// assert_eq!(result.len(), s.len()); /// ``` #[inline] fn over<I>(&mut self, sequence: I) -> Sequence<Self::Output> where I: Iterator<Item = Self::Input>, Self: Sized, { sequence.map(|x| self.next(x)).collect() } } #[derive(Debug)] pub struct MethodOverIterator<'a, T: Method, I: Iterator<Item = T::Input>> { method: &'a mut T, over: I, } impl<'a, T: Method, I: Iterator<Item = T::Input>> MethodOverIterator<'a, T, I> { pub fn new(method: &'a mut T, over: I) -> Self { Self { method, over } } } impl<'a, T: Method, I: Iterator<Item = T::Input>> Iterator for MethodOverIterator<'a, T, I> { type Item = T::Output; fn next(&mut self) -> Option<Self::Item> { let input = self.over.next()?; let output = self.method.next(input); Some(output) } }