Skip to content

Instantly share code, notes, and snippets.

@hcarvalhoalves
Last active August 27, 2015 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hcarvalhoalves/9174d71e6729dc68f6a4 to your computer and use it in GitHub Desktop.
Save hcarvalhoalves/9174d71e6729dc68f6a4 to your computer and use it in GitHub Desktop.
import System.Random
import Data.List
mu :: Fractional a => [a] -> a
mu [] = 0
mu ps = sum ps / (fromIntegral . length) ps
sigma :: Floating a => [a] -> a
sigma [] = 0
sigma ps = sqrt (mu $ map xm ps)
where m = mu ps
xm x = (x - m) ** 2
data Direction a = Up a | Down a deriving (Eq, Ord, Show)
getDirection :: (Ord a, Num a) => a -> a -> Direction a
getDirection m p | p > m = Up m
| p <= m = Down m
| otherwise = Up 0
data StdDev a = Normal a | AboveSigma a deriving (Eq, Ord, Show)
getStdDev :: (Ord a, Num a) => a -> a -> StdDev a
getStdDev s p | p > (2 * s) = AboveSigma s
| otherwise = Normal s
data Analysis a = Analysis a (Direction a) (StdDev a) deriving (Eq, Ord, Show)
analyze :: (Ord a, Num a) => a -> a -> a -> Analysis a
analyze m s p = Analysis p (getDirection m p) (getStdDev (abs s) (abs p))
analyzeSeries :: (Ord a, Num a) => a -> a -> [a] -> [Analysis a]
analyzeSeries _ _ [] = []
analyzeSeries m s (p:ps) = [(analyze m s p)] ++ (analyzeSeries m s ps)
analyzeStream :: (Ord a, Floating a) => Int -> [a] -> [Analysis a]
analyzeStream _ [] = []
analyzeStream samples ps = (analyzeSeries (mu window) (sigma window) window) ++ analyzeStream samples rest
where window = take samples ps
rest = drop samples ps
onlyAlert :: Analysis t -> Bool
onlyAlert (Analysis _ _ s) = case s of Normal _ -> False
_ -> True
filterAlert :: [Analysis t] -> [Analysis t]
filterAlert = filter onlyAlert
randomSeries :: StdGen -> [Float]
randomSeries g = map (subtract 0.5) $ unfoldr (Just . random) g
main :: IO ()
main = do
seed <- newStdGen
let rs = randomSeries seed
putStr $ unlines $ map show $ filterAlert $ analyzeStream 100 rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment