module Streamly.Test.Data.Fold.Window (main) where import Test.Hspec (hspec, describe, it, runIO) import Streamly.Internal.Data.Scanl (Incr(..)) import qualified Streamly.Internal.Data.Fold as Fold import qualified Streamly.Internal.Data.RingArray as RingArray import qualified Streamly.Internal.Data.Scanl as Scanl import qualified Streamly.Internal.Data.Stream as S import Prelude hiding (sum, maximum, minimum) moduleName :: String moduleName = "Window" main :: IO () main = hspec $ do describe moduleName $ do let numElem = 80000 winSize = 800 testCaseChunk = [9007199254740992, 1, 1.0 :: Double, 9007199254740992, 1, 1, 1, 9007199254740992] testCase = take numElem $ cycle testCaseChunk deviationLimit = 1 testFunc f = do let c = S.fromList testCase f1 = Fold.fromScanl $ Scanl.incrScan winSize f f2 = Fold.fromScanl f a <- runIO $ S.fold f1 c b <- runIO $ S.fold f2 $ S.drop (numElem - winSize) $ fmap Insert c let c1 = a - b it ("should not deviate more than " ++ show deviationLimit) $ c1 >= -1 * deviationLimit && c1 <= deviationLimit describe "Sum" $ testFunc Scanl.incrSum describe "mean" $ testFunc Scanl.incrMean describe "Correctness" $ do let winSize = 3 testCase1 = [1.0, 4.0, 3.0, 2.1, -5.1, -2.0, 7.0, 3.0, -2.5] :: [Double] testCase2 = replicate 5 1.0 ++ [7.0] testFunc tc f sI sW = do let c = S.fromList tc a <- runIO $ S.fold Fold.toList $ S.postscanl f $ fmap Insert c b <- runIO $ S.fold Fold.toList $ S.postscanl (Scanl.incrScan winSize f) c it "Infinite" $ a == sI it ("Finite " ++ show winSize) $ b == sW testFunc2 tc expec f = do let c = S.fromList tc a <- runIO $ S.toList $ S.postscanl (f winSize) c runIO $ print a it (show tc) $ a == expec describe "toList" $ do testFunc2 testCase1 [[1.0],[1.0,4.0],[1.0,4.0,3.0],[4.0,3.0,2.1],[3.0,2.1,-5.1] ,[2.1,-5.1,-2.0],[-5.1,-2.0,7.0],[-2.0,7.0,3.0],[7.0,3.0,-2.5] ] (RingArray.scanFoldRingsBy Fold.toList) describe "minimum" $ do testFunc2 testCase1 [Just 1.0,Just 1.0,Just 1.0,Just 2.1,Just (-5.1),Just (-5.1) ,Just (-5.1),Just (-2.0),Just (-2.5)] (RingArray.scanFoldRingsBy Fold.minimum) describe "maximum" $ do testFunc2 testCase1 [Just 1.0,Just 4.0,Just 4.0,Just 4.0,Just 3.0,Just 2.1 ,Just 7.0,Just 7.0,Just 7.0] (RingArray.scanFoldRingsBy Fold.maximum) describe "range" $ do testFunc2 testCase1 [Just (1.0,1.0),Just (1.0,4.0),Just (1.0,4.0),Just (2.1,4.0) ,Just (-5.1,3.0),Just (-5.1,2.1),Just (-5.1,7.0) ,Just (-2.0,7.0),Just (-2.5,7.0)] (RingArray.scanFoldRingsBy Fold.range) describe "sum" $ do let scanInf = [1, 2, 3, 4, 5, 12] :: [Double] scanWin = [1, 2, 3, 3, 3, 9] :: [Double] testFunc testCase2 Scanl.incrSum scanInf scanWin describe "mean" $ do let scanInf = [1, 1, 1, 1, 1, 2] :: [Double] scanWin = [1, 1, 1, 1, 1, 3] :: [Double] testFunc testCase2 Scanl.incrMean scanInf scanWin