module Data.MovingAverage.Simple ( simple ) where import Data.MovingAverage.Types (SmoothedResults, MovingAverageError(..), buildSimpleMovingAverage) simple :: Floating a => Int -> [a] -> Either MovingAverageError (SmoothedResults a) simple _ [] = Left NoValuesProvided simple n xs | n <= 0 = Left $ InvalidWindow "Window must be greater than 0" | otherwise = Right $ buildSimpleMovingAverage n xsAndSmoothedPairs where xsAndSmoothedPairs = zip xs (map fst3 $ scanl1 average sampleTriples) divisors = map fromIntegral $ [1..n] ++ repeat n nAgos = replicate (n - 1) 0 ++ xs sampleTriples = zip3 xs divisors nAgos average :: Fractional a => (a, a, a) -> (a, a, a) -> (a, a, a) average (prevAvg, prevDiv, dropMe) (sample, divisor, nAgo) = (newAvg, divisor, nAgo) where prevSum = prevAvg * prevDiv newAvg = (prevSum + sample - dropMe) / divisor fst3 :: (a, b, c) -> a fst3 (x, _, _) = x