massiv-0.1.0.0: tests/Data/Massiv/Array/Ops/FoldSpec.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Data.Massiv.Array.Ops.FoldSpec (spec) where
import Data.Massiv.CoreArbitrary
import Prelude hiding (map, product, sum)
import qualified Prelude as P (length, sum)
import Test.Hspec
import Test.QuickCheck
import Test.QuickCheck.Monadic
prop_SumSEqSumP :: Index ix => proxy ix -> Array D ix Int -> Bool
prop_SumSEqSumP _ arr = sum arr == sum (setComp Par arr)
prop_ProdSEqProdP :: Index ix => proxy ix -> Array D ix Int -> Bool
prop_ProdSEqProdP _ arr = product arr == product (setComp Par arr)
prop_NestedFoldP :: Array D Ix1 (Array D Ix1 Int) -> Bool
prop_NestedFoldP arr = sum (setComp Par (map sum $ setComp Par arr)) == sum (map sum arr)
prop_FoldrOnP :: Int -> [Int] -> ArrP D Ix1 Int -> Property
prop_FoldrOnP wId wIds (ArrP arr) =
P.length arr > P.length wIds ==> monadicIO $ do
res <- run $ ifoldrOnP wIdsNE (\_ -> (+)) 0 (:) [] arr
if P.length arr `mod` P.length wIdsNE == 0
then assert (P.length res == P.length wIdsNE)
else assert (P.length res == P.length wIdsNE + 1)
assert (P.sum res == sum arr)
where
wIdsNE = wId : wIds
prop_FoldlOnP :: Int -> [Int] -> ArrP D Ix1 Int -> Property
prop_FoldlOnP wId wIds (ArrP arr) =
P.length arr > P.length wIds ==> monadicIO $ do
res <- run $ ifoldlOnP wIdsNE (\a _ x -> a + x) 0 (flip (:)) [] arr
if P.length arr `mod` P.length wIdsNE == 0
then assert (P.length res == P.length wIdsNE)
else assert (P.length res == P.length wIdsNE + 1)
assert (P.sum res == sum arr)
where
wIdsNE = wId : wIds
specFold ::
(Arbitrary ix, CoArbitrary ix, Index ix, Show (Array D ix Int))
=> proxy ix
-> String
-> Spec
specFold proxy dimStr = do
describe dimStr $ do
it "sumS Eq sumP" $ property $ prop_SumSEqSumP proxy
it "prodS Eq prodP" $ property $ prop_ProdSEqProdP proxy
spec :: Spec
spec = do
specFold (Nothing :: Maybe Ix1) "Ix1"
specFold (Nothing :: Maybe Ix2) "Ix2"
it "Nested Parallel Fold" $ property prop_NestedFoldP
it "FoldrOnP" $ property $ prop_FoldrOnP
it "FoldlOnP" $ property $ prop_FoldlOnP