packages feed

massiv-test 0.1.1 → 0.1.2

raw patch · 12 files changed

+593/−264 lines, 12 filesdep ~massivPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: massiv

API changes (from Hackage documentation)

+ Test.Massiv.Core.Index: SzTiny :: Sz ix -> SzTiny ix
+ Test.Massiv.Core.Index: [unSzTiny] :: SzTiny ix -> Sz ix
+ Test.Massiv.Core.Index: instance (Test.QuickCheck.Arbitrary.Arbitrary ix, Data.Massiv.Core.Index.Internal.Index ix) => Test.QuickCheck.Arbitrary.Arbitrary (Test.Massiv.Core.Index.SzTiny ix)
+ Test.Massiv.Core.Index: instance Data.Massiv.Core.Index.Internal.Index ix => GHC.Show.Show (Test.Massiv.Core.Index.SzTiny ix)
+ Test.Massiv.Core.Index: instance GHC.Classes.Eq ix => GHC.Classes.Eq (Test.Massiv.Core.Index.SzTiny ix)
+ Test.Massiv.Core.Index: newtype SzTiny ix
+ Test.Massiv.Utils: class NFData a
+ Test.Massiv.Utils: deepseq :: NFData a => a -> b -> b
- Test.Massiv.Core.Index: ixSpec :: forall ix. (Typeable (Lower ix), Arbitrary (Lower ix), Typeable ix, Index ix, Arbitrary ix) => Spec
+ Test.Massiv.Core.Index: ixSpec :: forall ix. (Typeable (Lower ix), Arbitrary (Lower ix), Typeable ix, Index ix, Arbitrary ix, IsIndexDimension ix (Dimensions ix)) => Spec

Files

massiv-test.cabal view
@@ -1,5 +1,5 @@ name:                massiv-test-version:             0.1.1+version:             0.1.2 synopsis:            Library that contains generators, properties and tests for Massiv Array Library. description:         This library is designed for users of massiv library that need random generators for writing custom property tests and reusing some of the predefined ones. homepage:            https://github.com/lehins/massiv@@ -32,7 +32,7 @@                      , exceptions                      , QuickCheck                      , hspec-                     , massiv >= 0.4.2+                     , massiv >= 0.4.5                      , scheduler                      , primitive                      , unliftio@@ -55,6 +55,8 @@                     , Test.Massiv.Core.SchedulerSpec                     , Test.Massiv.Array.Delayed.StreamSpec                     , Test.Massiv.Array.MutableSpec+                    , Test.Massiv.Array.Ops.TransformSpec+                    , Test.Massiv.Array.Ops.SortSpec                       -- TODO: Below should be moved to Test.Massiv.Array                     , Data.Massiv.Array.Delayed.InterleavedSpec                     , Data.Massiv.Array.Delayed.PushSpec@@ -67,8 +69,6 @@                     , Data.Massiv.Array.Ops.FoldSpec                     , Data.Massiv.Array.Ops.MapSpec                     , Data.Massiv.Array.Ops.SliceSpec-                    , Data.Massiv.Array.Ops.SortSpec-                    , Data.Massiv.Array.Ops.TransformSpec                     , Data.Massiv.Array.StencilSpec                     , Data.Massiv.ArraySpec   build-depends:      base
src/Test/Massiv/Core.hs view
@@ -2,8 +2,10 @@   ( module Index   , module Commmon   , module Utils+  , module Test.Hspec.QuickCheck   ) where  import Test.Massiv.Core.Index as Index (DimIx(..), SzIx(..), SzNE(..)) import Test.Massiv.Core.Common as Commmon import Test.Massiv.Utils as Utils+import Test.Hspec.QuickCheck
src/Test/Massiv/Core/Index.hs view
@@ -16,6 +16,7 @@   ( DimIx(..)   , SzNE(..)   , SzIx(..)+  , SzTiny(..)   , ixToList   , arbitraryIx1   , toIx@@ -87,6 +88,15 @@     SzIx sz . flip (liftIndex2 mod) (unSz sz) <$> arbitrary  +++newtype SzTiny ix = SzTiny { unSzTiny :: Sz ix }+  deriving (Show, Eq)++instance (Arbitrary ix, Index ix) => Arbitrary (SzTiny ix) where+  arbitrary = SzTiny . liftSz (`mod` 10) <$> arbitrary++ instance Arbitrary e => Arbitrary (Border e) where   arbitrary =     oneof@@ -405,7 +415,8 @@   ixSpec ::-     forall ix. (Typeable (Lower ix), Arbitrary (Lower ix), Typeable ix, Index ix, Arbitrary ix)+     forall ix. (Typeable (Lower ix), Arbitrary (Lower ix), Typeable ix, Index ix, Arbitrary ix+                , IsIndexDimension ix (Dimensions ix))   => Spec ixSpec = do   let threshold = 50000
src/Test/Massiv/Utils.hs view
@@ -23,7 +23,7 @@ import Test.QuickCheck.Monadic as X import Test.Hspec as X import Test.QuickCheck.Function as X-import Control.DeepSeq (NFData, deepseq)+import Control.DeepSeq as X (NFData, deepseq) import UnliftIO.Exception (Exception(..), SomeException, catch, catchAny) #if !MIN_VERSION_base(4,11,0) import Data.Semigroup as X ((<>))
tests/Data/Massiv/Array/Ops/FoldSpec.hs view
@@ -1,40 +1,35 @@+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-} module Data.Massiv.Array.Ops.FoldSpec (spec) where  import qualified Data.Foldable as F import Data.Massiv.Array as A-import Test.Massiv.Core import Data.Semigroup import Prelude hiding (map, product, sum)+import Test.Massiv.Core   -prop_SumSEqSumP :: Index ix => proxy ix -> Array D ix Int -> Bool-prop_SumSEqSumP _ arr = sum arr == sum (setComp Par arr)+prop_SumSEqSumP :: Index 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_ProdSEqProdP :: Index ix => Array D ix Int -> Bool+prop_ProdSEqProdP arr = product arr == product (setComp Par arr)  -specFold ::-     (Arbitrary ix, Index ix, Show (Array D ix Int))-  => proxy ix-  -> String-  -> Spec-specFold proxy dimStr =-  describe dimStr $ do-    it "sumS Eq sumP" $ property $ prop_SumSEqSumP proxy-    it "prodS Eq prodP" $ property $ prop_ProdSEqProdP proxy--foldOpsProp :: (Source P ix Int) => proxy ix -> Fun Int Bool -> ArrTinyNE P ix Int -> Property-foldOpsProp _ f (ArrTinyNE arr) =+foldOpsProp ::+     (Source P ix Int)+  => Fun Int Bool+  -> ArrTinyNE P ix Int+  -> Property+foldOpsProp f (ArrTinyNE arr) =   (A.maximum' arr === getMax (foldMono Max arr)) .&&.   (A.minimum' arr === getMin (foldSemi Min maxBound arr)) .&&.   (A.sum arr === F.sum ls) .&&.@@ -47,12 +42,44 @@   where     ls = toList 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)+++specFold ::+     forall ix. (Arbitrary ix, Index ix, Show (Array D ix Int), Show (Array P ix Int))+  => String+  -> Spec+specFold dimStr =+  describe dimStr $ do+    it "sumS Eq sumP" $ property $ prop_SumSEqSumP @ix+    it "prodS Eq prodP" $ property $ prop_ProdSEqProdP @ix+    it "foldOps" $ property $ foldOpsProp @ix+++prop_foldOuterSliceToList ::+     (Elt P ix Int ~ Array M (Lower ix) Int, OuterSlice P ix Int, Index (Lower ix))+  => ArrTiny P ix Int+  -> Property+prop_foldOuterSliceToList (ArrTiny arr) =+  foldOuterSlice A.toList arr === A.fold (A.map pure arr)++ spec :: Spec spec = do-  specFold (Nothing :: Maybe Ix1) "Ix1"-  specFold (Nothing :: Maybe Ix2) "Ix2"+  specFold @Ix1 "Ix1"+  specFold @Ix2 "Ix2"+  specFold @Ix3 "Ix3"   it "Nested Parallel Fold" $ property prop_NestedFoldP   describe "Foldable Props" $ do-    it "Ix1" $ property $ foldOpsProp (Nothing :: Maybe Ix1)-    it "Ix2" $ property $ foldOpsProp (Nothing :: Maybe Ix2)-    it "Ix3" $ property $ foldOpsProp (Nothing :: Maybe Ix3)+    prop "Ix2" $ prop_foldOuterSliceToList @Ix2+    prop "Ix3" $ prop_foldOuterSliceToList @Ix3+    prop "Ix4" $ prop_foldOuterSliceToList @Ix4+  describe "Exceptions" $ do+    let emptySelector :: forall ix . Index ix => SizeException -> Bool+        emptySelector = (== SizeEmptyException (Sz (zeroIndex :: ix)))+    it "maximumM" $ maximumM (A.empty :: Array D Ix1 Int) `shouldThrow` emptySelector @Ix1+    it "minimumM" $ minimumM (A.empty :: Array D Ix2 Int) `shouldThrow` emptySelector @Ix2+    it "maximum'" $ (pure $! maximum' (A.empty :: Array D Ix3 Int)) `shouldThrow` emptySelector @Ix3+    it "minimum'" $ (pure $! minimum' (A.empty :: Array D Ix4 Int)) `shouldThrow` emptySelector @Ix4
− tests/Data/Massiv/Array/Ops/SortSpec.hs
@@ -1,18 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeApplications #-}-module Data.Massiv.Array.Ops.SortSpec (spec) where--import Data.List as L-import Data.Massiv.Array as A-import Test.Massiv.Core---prop_IsSorted :: (b -> b) -> ([Int] -> b) -> (b -> [Int]) -> [Int] -> Property-prop_IsSorted sortWith from to xs =-  to (sortWith (from xs)) === sort xs--spec :: Spec-spec =-  describe "QuickSort" $ do-    it "Seq" $ property $ prop_IsSorted (quicksort @P) (A.fromList Seq) A.toList-    it "Par" $ property $ prop_IsSorted (quicksort @P) (A.fromList (ParN 4)) A.toList
− tests/Data/Massiv/Array/Ops/TransformSpec.hs
@@ -1,158 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE MonoLocalBinds #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeApplications #-}-module Data.Massiv.Array.Ops.TransformSpec (spec) where--import Data.Massiv.Array as A-import Test.Massiv.Core-import Data.Sequence as S-import Prelude as P-import Data.Foldable as F (foldl', toList)-import Data.Maybe--prop_transposeOuterInner :: Array D Ix2 Int -> Property-prop_transposeOuterInner arr = transposeOuter arr === transpose arr--prop_upsampleDownsample ::-     (Show (Array P ix Int), Index ix) => ArrTiny P ix Int -> Stride ix -> Int -> Property-prop_upsampleDownsample (ArrTiny arr) stride fill =-  arr === compute (downsample stride (computeAs P (upsample fill stride arr)))--prop_ExtractAppend-  :: (Show (Array P ix Int), Index ix)-  => DimIx ix -> ArrIx P ix Int -> Property-prop_ExtractAppend (DimIx dim) (ArrIx arr ix) =-  arr === compute (uncurry (append' dim) $ A.splitAt' dim (getDim' ix dim) arr)--prop_SplitExtract-  :: (Show (Array P ix Int), Show (Array M ix Int), Index ix)-  => DimIx ix -> ArrIx P ix Int -> Positive Int -> Property-prop_SplitExtract (DimIx dim) (ArrIx arr ix) (Positive n) =-  (computeAs P <$> splitAt' dim i arr) === (left, computeAs P (append' dim center right)) .&&.-  (computeAs P splitLeft, splitRight) === (computeAs P (append' dim left center), right)-  where i = getDim' ix dim-        k = getDim' (unSz (size arr)) dim-        n' = n `mod` (k - i)-        (left, center, right) = either throw id (splitExtractM dim i (Sz n') arr)-        (splitLeft, splitRight) = splitAt' dim (i + n') arr--prop_ConcatAppend-  :: (Show (Array P ix Int), Index ix)-  => DimIx ix -> Comp -> Sz ix -> NonEmptyList (Fun ix Int) -> Property-prop_ConcatAppend (DimIx dim) comp sz (NonEmpty fns) =-  foldl1 (\arr -> computeAs P . append' dim arr) arrs ===-  computeAs P (concat' dim arrs)-  where-    arrs = P.map (makeArrayR P comp sz . apply) fns--prop_AppendMappend-  :: Array D Ix1 Int -> Array D Ix1 Int -> Property-prop_AppendMappend arr1 arr2 =-  computeAs P (append' 1 arr1 arr2) === computeAs P (toLoadArray arr1 <> toLoadArray arr2)--prop_ConcatMconcat-  :: [Array D Ix1 Int] -> Property-prop_ConcatMconcat arrs =-  computeAs P (concat' 1 (A.empty : arrs)) === computeAs P (mconcat (fmap toLoadArray arrs))--prop_ExtractSizeMismatch ::-     Index ix => ArrTiny P ix Int -> Positive Int -> Property-prop_ExtractSizeMismatch (ArrTiny arr) (Positive n) =-  assertExceptionIO (SizeElementsMismatchException sz sz' ==) $ resizeM sz' arr-  where-    sz = size arr-    sz' = Sz (totalElem sz + n)--spec :: Spec-spec = do-  it "transposeOuterInner" $ property prop_transposeOuterInner-  describe "upsampleDownsample" $ do-    it "Ix1" $ property (prop_upsampleDownsample @Ix1)-    it "Ix2" $ property (prop_upsampleDownsample @Ix2)-    it "Ix3" $ property (prop_upsampleDownsample @Ix3)-    it "Ix4" $ property (prop_upsampleDownsample @Ix4)-  describe "extractSizeMismatch" $ do-    it "Ix1" $ property (prop_ExtractSizeMismatch @Ix1)-    it "Ix2" $ property (prop_ExtractSizeMismatch @Ix2)-    it "Ix3" $ property (prop_ExtractSizeMismatch @Ix3)-    it "Ix4" $ property (prop_ExtractSizeMismatch @Ix4)-  describe "ExtractAppend" $ do-    it "Ix1" $ property (prop_ExtractAppend @Ix1)-    it "Ix2" $ property (prop_ExtractAppend @Ix2)-    it "Ix3" $ property (prop_ExtractAppend @Ix3)-    it "Ix4" $ property (prop_ExtractAppend @Ix4)-  describe "ExtractAppend" $ do-    it "Ix1" $ property (prop_SplitExtract @Ix1)-    it "Ix2" $ property (prop_SplitExtract @Ix2)-    it "Ix3" $ property (prop_SplitExtract @Ix3)-    it "Ix4" $ property (prop_SplitExtract @Ix4)-  describe "ConcatAppend" $ do-    it "Ix1" $ property (prop_ConcatAppend @Ix1)-    it "Ix2" $ property (prop_ConcatAppend @Ix2)-    it "Ix3" $ property (prop_ConcatAppend @Ix3)-    it "Ix4" $ property (prop_ConcatAppend @Ix4)-  describe "Monoid" $ do-    it "Ix1" $ property prop_AppendMappend-    it "Ix1" $ property prop_ConcatMconcat-  describe "Sequence" $ do-    it "ConsSnoc" $ property prop_ConsSnoc-    it "UnconsUnsnoc" $ property prop_UnconsUnsnoc-  describe "zoomWithGrid" $ do-    it "Ix1" $ property (prop_zoomWithGridStrideCompute @Ix1)-    it "Ix2" $ property (prop_zoomWithGridStrideCompute @Ix2)-    it "Ix3" $ property (prop_zoomWithGridStrideCompute @Ix3)-    it "Ix4" $ property (prop_zoomWithGridStrideCompute @Ix4)--prop_zoomWithGridStrideCompute :: (Show (Array P ix Int), Index ix) => Array D ix Int -> Stride ix -> Int -> Property-prop_zoomWithGridStrideCompute arr stride defVal =-  (computeWithStrideAs P stride' arr' ===-   A.replicate Seq (Sz (liftIndex (+ 1) $ unSz (size arr))) defVal) .&&.-  (computeWithStrideAs P stride' (extract' (pureIndex 1) sz' arr') === compute arr)-  where-    arr' = computeAs P (zoomWithGrid defVal stride arr)-    sz' = Sz (liftIndex (subtract 1) $ unSz (size arr'))-    stride' = Stride (liftIndex (+ 1) $ unStride stride)---prop_UnconsUnsnoc :: Array D Ix1 Int -> Bool -> Property-prop_UnconsUnsnoc arr unconsFirst =-  preJust $ do-    (arr', u, s) <--      if unconsFirst-        then do-          (u, au) <- unconsM arr-          (as, s) <- unsnocM au-          pure (as, u, s)-        else do-          (as, s) <- unsnocM arr-          (u, au) <- unconsM as-          pure (au, u, s)-    pure (computeAs U (A.snoc (A.cons u (toLoadArray (computeAs U arr'))) s) === compute arr)--preJust :: Testable prop => Maybe prop -> Property-preJust m = isJust m ==> fromJust m--prop_ConsSnoc :: Array D Ix1 Int -> [SeqOp Int] -> Property-prop_ConsSnoc arr ops =-  A.toList (computeAs U (foldl' applyArraySeqOp (toLoadArray arr) ops)) ===-  F.toList (foldl' applySequenceSeqOp (S.fromList (A.toList arr)) ops)--data SeqOp e = Cons e | Snoc e deriving (Eq, Show)--instance Arbitrary e => Arbitrary (SeqOp e) where-  arbitrary = do-    e <- arbitrary-    elements [Cons e, Snoc e]--applyArraySeqOp :: Array DL Ix1 e -> SeqOp e -> Array DL Ix1 e-applyArraySeqOp arr = \case-  Cons x -> A.cons x arr-  Snoc x -> A.snoc arr x---applySequenceSeqOp :: Seq a -> SeqOp a -> Seq a-applySequenceSeqOp arr = \case-  Cons x -> x <| arr-  Snoc x -> arr |> x
tests/Data/Massiv/Array/StencilSpec.hs view
@@ -4,36 +4,50 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedLists #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-} module Data.Massiv.Array.StencilSpec (spec) where +import Prelude as P import Control.DeepSeq (deepseq) import Data.Default (Default(def)) import Data.Massiv.Array as A+import Data.Massiv.Array.Stencil.Unsafe as A import Test.Massiv.Core --- sum3x3Stencil :: Fractional a => Stencil Ix2 a a--- sum3x3Stencil = makeConvolutionStencil (3 :. 3) (1 :. 1) $ \ get ->---   get (-1 :. -1) 1 . get (-1 :. 0) 1 . get (-1 :. 1) 1 .---   get ( 0 :. -1) 1 . get ( 0 :. 0) 1 . get ( 0 :. 1) 1 .---   get ( 1 :. -1) 1 . get ( 1 :. 0) 1 . get ( 1 :. 1) 1--- {-# INLINE sum3x3Stencil #-}+avg3x3Stencil :: Fractional a => Stencil Ix2 a a+avg3x3Stencil = (/9) <$> makeConvolutionStencil (Sz 3) (1 :. 1) $ \ get ->+  get (-1 :. -1) 1 . get (-1 :. 0) 1 . get (-1 :. 1) 1 .+  get ( 0 :. -1) 1 . get ( 0 :. 0) 1 . get ( 0 :. 1) 1 .+  get ( 1 :. -1) 1 . get ( 1 :. 0) 1 . get ( 1 :. 1) 1   singletonStencil :: (Index ix) => (Int -> Int) -> Stencil ix Int Int singletonStencil f =   makeStencil oneSz zeroIndex $ \ get -> fmap f (get zeroIndex)-{-# INLINE singletonStencil #-}  -prop_MapSingletonStencil :: (Load DW ix Int, Manifest U ix Int) =>-                            Proxy ix -> Fun Int Int -> Border Int -> ArrNE U ix Int -> Bool+prop_MapSingletonStencil :: (Load DW ix Int, Manifest U ix Int, Show (Array U ix Int)) =>+                            Proxy ix -> Fun Int Int -> Border Int -> ArrNE U ix Int -> Property prop_MapSingletonStencil _ f b (ArrNE arr) =-  computeAs U (mapStencil b (singletonStencil (apply f)) arr) == computeAs U (A.map (apply f) arr)+  computeAs U (mapStencil b (singletonStencil (apply f)) arr) === computeAs U (A.map (apply f) arr) -prop_MapSingletonStencilWithStride :: (StrideLoad DW ix Int, Manifest U ix Int) =>-                                      Proxy ix -> Fun Int Int -> Border Int -> ArrNE U ix Int -> Bool+prop_ApplyZeroStencil ::+     (Load DW ix Int, Manifest U ix Int) => Proxy ix -> Int -> Array U ix Int -> Property+prop_ApplyZeroStencil _ e arr =+  assertSomeException $ computeAs U (applyStencil noPadding zeroStencil arr)+  where+    zeroStencil = makeStencil zeroSz zeroIndex $ \_get -> pure e+++prop_MapSingletonStencilWithStride ::+     (StrideLoad DW ix Int, Manifest U ix Int, Show (Array U ix Int))+  => Proxy ix+  -> Fun Int Int+  -> Border Int+  -> ArrNE U ix Int+  -> Property prop_MapSingletonStencilWithStride _ f b (ArrNE arr) =-  computeWithStride oneStride (mapStencil b (singletonStencil (apply f)) arr) ==+  computeWithStride oneStride (mapStencil b (singletonStencil (apply f)) arr) ===   computeAs U (A.map (apply f) arr)  -- Tests out of bounds stencil indexing@@ -45,6 +59,50 @@     ix' = liftIndex (* signum s) (setDim' zeroIndex r (getDim' (unSz sz) r))  +instance Index ix => Show (Stencil ix a b) where+  show stencil =+    "Stencil " ++ show (getStencilSize stencil) ++ " " ++ show (getStencilCenter stencil)+++prop_MapEqApplyStencil ::+     (Show (Array P ix Int), StrideLoad DW ix Int)+  => Stride ix+  -> SzTiny ix+  -> Border Int+  -> Array P ix Int+  -> Property+prop_MapEqApplyStencil stride (SzTiny sz) b arr =+  forAll (elements (P.zip [0 ..] (toList $ A.map (\(n, _, _) -> n) stencils))) $ \(i, _) ->+    let (_, stencil, g) = stencils ! i+     in computeAs P (mapStencilUnsafe b sz zeroIndex g arr) ===+        computeAs P (applyStencil (samePadding stencil b) stencil arr) .&&.+        computeWithStrideAs P stride (mapStencilUnsafe b sz zeroIndex g arr) ===+        computeWithStrideAs P stride (applyStencil (samePadding stencil b) stencil arr)+  where+    stencils = mkCommonStencils sz++mkCommonStencils ::+     (Bounded a, Num a, Ord a, Index ix)+  => Sz ix+  -> Array B Ix1 (String, Stencil ix a a, (ix -> a) -> a)+mkCommonStencils sz =+  fromList+    Seq+    [ (name, stencil sz, \get -> foldlS f acc0 $ fmap get (zeroIndex ..: unSz sz))+    | (name, stencil, f, acc0) <-+        [ ("maxStencil", maxStencil, max, minBound)+        , ("minStencil", minStencil, min, maxBound)+        , ("sumStencil", sumStencil, (+), 0)+        , ("productStencil", productStencil, (*), 1)+        ]+    ]++prop_FoldrStencil :: Load DW ix (Array DL Ix1 Int) => ArrNE P ix Int -> Property+prop_FoldrStencil (ArrNE arr) =+  computeAs P (computeAs B folded ! zeroIndex) === A.fromList Seq (foldrS (:) [] arr)+  where+    folded = applyStencil noPadding (foldrStencil cons A.empty (size arr)) arr+ stencilSpec :: Spec stencilSpec = do   describe "MapSingletonStencil" $ do@@ -57,12 +115,34 @@     it "Ix1" $ property $ prop_MapSingletonStencilWithStride (Proxy :: Proxy Ix1)     it "Ix2" $ property $ prop_MapSingletonStencilWithStride (Proxy :: Proxy Ix2)     it "Ix3" $ property $ prop_MapSingletonStencilWithStride (Proxy :: Proxy Ix3)+  describe "ApplyZeroStencil" $ do+    it "Ix1" $ property $ prop_ApplyZeroStencil (Proxy :: Proxy Ix1)+    it "Ix2" $ property $ prop_ApplyZeroStencil (Proxy :: Proxy Ix2)+    it "Ix3" $ property $ prop_ApplyZeroStencil (Proxy :: Proxy Ix3)+    it "Ix4" $ property $ prop_ApplyZeroStencil (Proxy :: Proxy Ix4)+    it "Ix2T" $ property $ prop_ApplyZeroStencil (Proxy :: Proxy Ix2T)   describe "DangerousStencil" $ do     it "Ix1" $ property $ prop_DangerousStencil (Proxy :: Proxy Ix1)     it "Ix2" $ property $ prop_DangerousStencil (Proxy :: Proxy Ix2)     it "Ix3" $ property $ prop_DangerousStencil (Proxy :: Proxy Ix3)     it "Ix4" $ property $ prop_DangerousStencil (Proxy :: Proxy Ix4)-+  describe "MapEqApplyStencil" $ do+    it "Ix1" $ property $ prop_MapEqApplyStencil @Ix1+    it "Ix2" $ property $ prop_MapEqApplyStencil @Ix2+    it "Ix3" $ property $ prop_MapEqApplyStencil @Ix3+    it "Ix4" $ property $ prop_MapEqApplyStencil @Ix4+  describe "FoldrStencil" $ do+    it "Ix1" $ property $ prop_FoldrStencil @Ix1+    it "Ix2" $ property $ prop_FoldrStencil @Ix2+    it "Ix3" $ property $ prop_FoldrStencil @Ix3+    it "Ix4" $ property $ prop_FoldrStencil @Ix4+  describe "Simple" $ do+    it "sumStencil" $ property $ \ (arr :: Array B Ix2 Rational) border ->+      computeAs N (mapStencil border avg3x3Stencil arr) ===+      computeAs N (applyStencil (Padding 1 1 border) (avgStencil (Sz 3)) arr)+    it "sameSizeAndCenter" $ property $ \ (SzIx sz ix) ->+      let stencil = makeStencil sz ix ($ Ix1 0) :: Stencil Ix1 Int Int+      in getStencilSize stencil === sz .&&. getStencilCenter stencil === ix  stencilDirection :: Ix2 -> Array U Ix2 Int -> Array U Ix2 Int stencilDirection ix = computeAs U . mapStencil (Fill def) (makeStencil (Sz 3) (1 :. 1) $ \f -> f ix)@@ -89,63 +169,71 @@       ysConvXs4' = [4, 10, 20, 30, 34]       ysCorrXs4' = [20, 30, 40, 26, 14]       xs4f' f = f (-1) 1 . f 0 2 . f 1 3 . f 2 4+      mapStencil1 :: Stencil Ix1 Int Int -> Array U Ix1 Int -> Array U Ix1 Int+      mapStencil1 s = computeAs U . mapStencil (Fill 0) s+      mapStencil2 :: Stencil Ix2 Int Int -> Array U Ix2 Int -> Array U Ix2 Int+      mapStencil2 s = computeAs U . mapStencil (Fill 0) s       applyStencil1 :: Stencil Ix1 Int Int -> Array U Ix1 Int -> Array U Ix1 Int-      applyStencil1 s = computeAs U . mapStencil (Fill 0) s-      applyStencil2 :: Stencil Ix2 Int Int -> Array U Ix2 Int -> Array U Ix2 Int-      applyStencil2 s = computeAs U . mapStencil (Fill 0) s+      applyStencil1 s = computeAs U . applyStencil noPadding s   describe "makeConvolutionStencilFromKernel" $ do-    it "1x3" $ applyStencil1 (makeConvolutionStencilFromKernel xs3) ys `shouldBe` ysConvXs3-    it "1x4" $ applyStencil1 (makeConvolutionStencilFromKernel xs4) ys `shouldBe` ysConvXs4+    it "1x3 map" $ mapStencil1 (makeConvolutionStencilFromKernel xs3) ys `shouldBe` ysConvXs3+    it "1x4 map" $ mapStencil1 (makeConvolutionStencilFromKernel xs4) ys `shouldBe` ysConvXs4+    it "1x3 apply" $+      applyStencil1 (makeConvolutionStencilFromKernel xs3) ys `shouldBe`+      compute (extract' 1 3 ysConvXs3)+    it "1x4 apply" $+      applyStencil1 (makeConvolutionStencilFromKernel xs4) ys `shouldBe`+      compute (extract' 1 2 ysConvXs4)   describe "makeCorrelationStencilFromKernel" $ do-    it "1x3" $ applyStencil1 (makeCorrelationStencilFromKernel xs3) ys `shouldBe` ysCorrXs3-    it "1x4" $ applyStencil1 (makeCorrelationStencilFromKernel xs4) ys `shouldBe` ysCorrXs4+    it "1x3 map" $ mapStencil1 (makeCorrelationStencilFromKernel xs3) ys `shouldBe` ysCorrXs3+    it "1x4 map" $ mapStencil1 (makeCorrelationStencilFromKernel xs4) ys `shouldBe` ysCorrXs4   describe "makeConvolutionStencil" $ do-    it "1x3" $ applyStencil1 (makeConvolutionStencil (Sz1 3) 1 xs3f) ys `shouldBe` ysConvXs3-    it "1x4" $ applyStencil1 (makeConvolutionStencil (Sz1 4) 2 xs4f) ys `shouldBe` ysConvXs4-    it "1x4" $ applyStencil1 (makeConvolutionStencil (Sz1 4) 1 xs4f') ys `shouldBe` ysConvXs4'+    it "1x3" $ mapStencil1 (makeConvolutionStencil (Sz1 3) 1 xs3f) ys `shouldBe` ysConvXs3+    it "1x4" $ mapStencil1 (makeConvolutionStencil (Sz1 4) 2 xs4f) ys `shouldBe` ysConvXs4+    it "1x4" $ mapStencil1 (makeConvolutionStencil (Sz1 4) 1 xs4f') ys `shouldBe` ysConvXs4'   describe "makeCorrelationStencil" $ do-    it "1x3" $ applyStencil1 (makeCorrelationStencil (Sz1 3) 1 xs3f) ys `shouldBe` ysCorrXs3-    it "1x4" $ applyStencil1 (makeCorrelationStencil (Sz1 4) 2 xs4f) ys `shouldBe` ysCorrXs4-    it "1x4" $ applyStencil1 (makeCorrelationStencil (Sz1 4) 1 xs4f') ys `shouldBe` ysCorrXs4'+    it "1x3" $ mapStencil1 (makeCorrelationStencil (Sz1 3) 1 xs3f) ys `shouldBe` ysCorrXs3+    it "1x4" $ mapStencil1 (makeCorrelationStencil (Sz1 4) 2 xs4f) ys `shouldBe` ysCorrXs4+    it "1x4" $ mapStencil1 (makeCorrelationStencil (Sz1 4) 1 xs4f') ys `shouldBe` ysCorrXs4'   describe "makeConvolutionStencil == makeConvolutionStencilFromKernel" $ do     it "Sobel Horizontal" $       property $ \(arr :: Array U Ix2 Int) ->-        applyStencil2 (makeConvolutionStencil (Sz 3) 1 sobelX) arr ===-        applyStencil2 (makeConvolutionStencilFromKernel sobelKernelX) arr+        mapStencil2 (makeConvolutionStencil (Sz 3) 1 sobelX) arr ===+        mapStencil2 (makeConvolutionStencilFromKernel sobelKernelX) arr     it "1x3" $       property $ \(arr :: Array U Ix1 Int) ->-        applyStencil1 (makeConvolutionStencil (Sz1 3) 1 xs3f) arr ===-        applyStencil1 (makeConvolutionStencilFromKernel xs3) arr+        mapStencil1 (makeConvolutionStencil (Sz1 3) 1 xs3f) arr ===+        mapStencil1 (makeConvolutionStencilFromKernel xs3) arr     it "1x4" $       property $ \(arr :: Array U Ix1 Int) ->-        applyStencil1 (makeConvolutionStencil (Sz1 4) 2 xs4f) arr ===-        applyStencil1 (makeConvolutionStencilFromKernel xs4) arr+        mapStencil1 (makeConvolutionStencil (Sz1 4) 2 xs4f) arr ===+        mapStencil1 (makeConvolutionStencilFromKernel xs4) arr   describe "makeCorrelationStencil == makeCorrelationStencilFromKernel" $ do     it "Sobel Horizontal" $       property $ \(arr :: Array U Ix2 Int) ->-        applyStencil2 (makeCorrelationStencil (Sz 3) 1 sobelX) arr ===-        applyStencil2 (makeCorrelationStencilFromKernel sobelKernelX) arr+        mapStencil2 (makeCorrelationStencil (Sz 3) 1 sobelX) arr ===+        mapStencil2 (makeCorrelationStencilFromKernel sobelKernelX) arr     it "1x3" $       property $ \(arr :: Array U Ix1 Int) ->-        applyStencil1 (makeCorrelationStencil (Sz1 3) 1 xs3f) arr ===-        applyStencil1 (makeCorrelationStencilFromKernel xs3) arr+        mapStencil1 (makeCorrelationStencil (Sz1 3) 1 xs3f) arr ===+        mapStencil1 (makeCorrelationStencilFromKernel xs3) arr     it "1x4" $       property $ \(arr :: Array U Ix1 Int) ->-        applyStencil1 (makeCorrelationStencil (Sz1 4) 2 xs4f) arr ===-        applyStencil1 (makeCorrelationStencilFromKernel xs4) arr+        mapStencil1 (makeCorrelationStencil (Sz1 4) 2 xs4f) arr ===+        mapStencil1 (makeCorrelationStencilFromKernel xs4) arr   describe "makeConvolutionStencil == makeCorrelationStencil . rotate180" $ do     it "Sobel Horizontal" $       property $ \(arr :: Array U Ix2 Int) ->-        applyStencil2 (makeConvolutionStencilFromKernel sobelKernelX) arr ===-        applyStencil2 (makeCorrelationStencilFromKernel (rotate180 sobelKernelX)) arr+        mapStencil2 (makeConvolutionStencilFromKernel sobelKernelX) arr ===+        mapStencil2 (makeCorrelationStencilFromKernel (rotate180 sobelKernelX)) arr     it "1x3" $       property $ \(arr :: Array U Ix1 Int) ->-        applyStencil1 (makeConvolutionStencilFromKernel xs3) arr ===-        applyStencil1 (makeCorrelationStencilFromKernel (rotate180 xs3)) arr+        mapStencil1 (makeConvolutionStencilFromKernel xs3) arr ===+        mapStencil1 (makeCorrelationStencilFromKernel (rotate180 xs3)) arr     it "1x5" $       property $ \(arr :: Array U Ix1 Int) ->-        applyStencil1 (makeConvolutionStencilFromKernel ys) arr ===-        applyStencil1 (makeCorrelationStencilFromKernel (rotate180 ys)) arr+        mapStencil1 (makeConvolutionStencilFromKernel ys) arr ===+        mapStencil1 (makeCorrelationStencilFromKernel (rotate180 ys)) arr  spec :: Spec spec = do
tests/Test/Massiv/Array/MutableSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-}@@ -8,7 +9,7 @@ {-# LANGUAGE TypeOperators #-} module Test.Massiv.Array.MutableSpec (spec) where -import Data.Massiv.Array+import Data.Massiv.Array as A import Test.Massiv.Core import Test.Massiv.Core.Mutable import Test.Massiv.Array.Delayed@@ -18,6 +19,10 @@ type MutableArraySpec r ix e    = ( Show e      , Eq e+     , Arbitrary e+     , Arbitrary ix+     , CoArbitrary e+     , Function e      , Eq (Array r ix e)      , Show (Array r ix e)      , Eq (Array (R r) Ix1 e)@@ -32,9 +37,6 @@  type MutableSpec r e    = ( Typeable e-     , Arbitrary e-     , CoArbitrary e-     , Function e      , IsList (Array r Ix1 e)      , Item (Array r Ix1 e) ~ e      , MutableArraySpec r Ix1 e@@ -43,10 +45,14 @@      , MutableArraySpec r Ix4 e      , MutableArraySpec r Ix5 e) -streamSpecR :: forall r ix e. (MutableArraySpec r ix e) => Spec-streamSpecR =+localMutableSpec :: forall r ix e. (MutableArraySpec r ix e) => Spec+localMutableSpec = do   describe "toStream/toList" $     it "toStream" $ property (prop_toStream @r @ix @e)+  describe "Mutable operations" $ do+    it "write" $ property (prop_Write @r @ix @e)+    it "modify" $ property (prop_Modify @r @ix @e)+    it "swap" $ property (prop_Swap @r @ix @e)  specMutableR :: forall r e. MutableSpec r e => Spec specMutableR = do@@ -59,10 +65,11 @@   mutableSpec @r @Ix2 @e   mutableSpec @r @Ix3 @e   mutableSpec @r @Ix4 @e-  streamSpecR @r @Ix1 @e-  streamSpecR @r @Ix2 @e-  streamSpecR @r @Ix3 @e-  streamSpecR @r @Ix4 @e+  localMutableSpec @r @Ix1 @e+  localMutableSpec @r @Ix2 @e+  localMutableSpec @r @Ix3 @e+  localMutableSpec @r @Ix4 @e+  localMutableSpec @r @Ix5 @e   describe "toStream/toList" $     it "toStreamIsList" $ property (prop_toStreamIsList @r @e)   --mutableSpec @r @Ix5 @e -- slows down the test suite@@ -76,6 +83,104 @@   unsafeMutableUnboxedSpec @r @Ix3 @e   unsafeMutableUnboxedSpec @r @Ix4 @e   unsafeMutableUnboxedSpec @r @Ix5 @e++prop_Write :: (Mutable r ix e, Eq e, Show e) => Array r ix e -> ix -> e -> Property+prop_Write arr ix e =+  monadicIO $+  run $ do+    marr <- thaw arr+    A.read marr ix >>= \case+      Nothing ->+        let withExcept = assertExceptionIO (== IndexOutOfBoundsException (size arr) ix)+         in pure+              (withExcept (writeM marr ix e) .&&.+               (write marr ix e `shouldReturn` False) .&&.+               (write_ marr ix e `shouldReturn` ()))+      Just olde ->+        pure $+        property $ do+          indexM arr ix `shouldReturn` olde+          A.write marr ix e `shouldReturn` True+          A.read marr ix `shouldReturn` Just e++          marr' <- thaw arr+          writeM marr' ix e `shouldReturn` ()+          arr' <- freeze (getComp arr) marr'+          indexM arr' ix `shouldReturn` e++          arr'' <- withMArray arr (\_ ma -> write_ ma ix e)+          index' arr'' ix `shouldBe` e+++prop_Modify :: (Mutable r ix e, Eq e, Show e) => Array r ix e -> Fun e e -> ix -> Property+prop_Modify arr f ix =+  monadicIO $+  run $ do+    marr <- thaw arr+    modify marr (pure . apply f) ix >>= \case+      Nothing ->+        let withExcept = assertExceptionIO (== IndexOutOfBoundsException (size arr) ix)+         in pure+              (withExcept (void $ indexM arr ix) .&&.+               withExcept (void $ readM marr ix) .&&.+               withExcept (void $ modifyM marr (pure . apply f) ix) .&&.+               withExcept (modifyM_ marr (pure . apply f) ix) .&&.+               (modify_ marr (pure . apply f) ix `shouldReturn` ()))+      Just e ->+        pure $+        property $ do+          let fM = pure . apply f+              fe = apply f e+          indexM arr ix `shouldReturn` e+          A.read marr ix `shouldReturn` Just fe++          marr' <- thawS arr+          readM marr' ix `shouldReturn` e+          modifyM marr' fM ix `shouldReturn` e+          arr' <- freezeS marr'+          indexM arr' ix `shouldReturn` fe++          arr'' <- withMArrayS arr (\ma -> modify_ ma fM ix)+          index' arr'' ix `shouldBe` fe++prop_Swap :: (Mutable r ix e, Eq e, Show e) => Array r ix e -> ix -> ix -> Property+prop_Swap arr ix1 ix2 =+  monadicIO $+  run $ do+    marr <- thaw arr+    swap marr ix1 ix2 >>= \case+      Nothing ->+        let withExcept =+              assertExceptionIO+                (\case+                   IndexOutOfBoundsException _ _ -> True+                   _ -> False)+         in pure+              (withExcept (void $ indexM arr ix1 >> indexM arr ix2) .&&.+               withExcept (void $ readM marr ix1 >> readM marr ix2) .&&.+               withExcept (void $ swapM marr ix1 ix2) .&&.+               withExcept (void $ swapM marr ix2 ix1) .&&.+               withExcept (swapM_ marr ix1 ix2) .&&.+               withExcept (swapM_ marr ix2 ix1) .&&.+               (swap_ marr ix1 ix2 `shouldReturn` ()) .&&.+               (swap_ marr ix2 ix1 `shouldReturn` ()))+      Just (e1, e2) ->+        pure $+        property $ do+          indexM arr ix1 `shouldReturn` e1+          indexM arr ix2 `shouldReturn` e2+          readM marr ix1 `shouldReturn` e2+          readM marr ix2 `shouldReturn` e1++          marr' <- thawS arr+          swapM marr' ix1 ix2 `shouldReturn` (e1, e2)+          arr' <- freezeS marr'+          indexM arr' ix1 `shouldReturn` e2+          indexM arr' ix2 `shouldReturn` e1++          let arr'' = withMArrayST arr (\ma -> swap_ ma ix1 ix2)+          index' arr'' ix1 `shouldBe` e2+          index' arr'' ix2 `shouldBe` e1   
+ tests/Test/Massiv/Array/Ops/SortSpec.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeApplications #-}+module Test.Massiv.Array.Ops.SortSpec (spec) where++import Data.List as L+import Data.Massiv.Array as A+import Test.Massiv.Core as A+import Data.Foldable as F+import Data.Map.Strict as M++prop_IsSorted :: (b -> b) -> ([Int] -> b) -> (b -> [Int]) -> [Int] -> Property+prop_IsSorted sortWith from to xs =+  to (sortWith (from xs)) === sort xs++tallyMap :: Array P Ix1 Word -> Map Word Int+tallyMap arr = F.foldr' addCount M.empty $ toManifest arr+  where+    addCount :: Word -> Map Word Int -> Map Word Int+    addCount !el !counter = M.insertWith (+) el 1 counter+++spec :: Spec+spec = do+  describe "QuickSort" $ do+    it "Seq" $ property $ prop_IsSorted (quicksort @P) (A.fromList Seq) A.toList+    it "Par" $ property $ prop_IsSorted (quicksort @P) (A.fromList (ParN 4)) A.toList+  describe "Tally" $+    prop "Same as Map" $ \ arr ->+       M.toList (tallyMap arr) === F.toList (tally arr)
+ tests/Test/Massiv/Array/Ops/TransformSpec.hs view
@@ -0,0 +1,239 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MonoLocalBinds #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+module Test.Massiv.Array.Ops.TransformSpec (spec) where++import Data.Foldable as F (foldl', toList)+import Data.Massiv.Array as A+import Data.Maybe+import Data.Sequence as S+import Prelude as P+import Test.Massiv.Core++prop_TransposeOuterInner :: Array D Ix2 Int -> Property+prop_TransposeOuterInner arr = transposeOuter arr === transpose arr++prop_UpsampleDownsample ::+     forall r ix e . (Eq (Array r ix e), Show (Array r ix e), Mutable r ix e)+  => ArrTiny r ix e+  -> Stride ix+  -> e+  -> Property+prop_UpsampleDownsample (ArrTiny arr) stride fill =+  arr === compute (downsample stride (compute @r (upsample fill stride arr)))++prop_ExtractAppend ::+     forall r ix e.+     ( Eq (Array r ix e)+     , Show (Array r ix e)+     , Source (R r) ix e+     , Extract r ix e+     , Mutable r ix e+     )+  => DimIx ix+  -> ArrIx r ix e+  -> Property+prop_ExtractAppend (DimIx dim) (ArrIx arr ix) =+  arr === compute (uncurry (append' dim) $ A.splitAt' dim (getDim' ix dim) arr)++prop_SplitExtract ::+     forall r ix e.+     ( Eq (Array r ix e)+     , Eq (Array (R r) ix e)+     , Show (Array r ix e)+     , Show (Array (R r) ix e)+     , Source (R r) ix e+     , Mutable r ix e+     , Extract r ix e+     )+  => DimIx ix+  -> ArrIx r ix e+  -> Positive Int+  -> Property+prop_SplitExtract (DimIx dim) (ArrIx arr ix) (Positive n) =+  (compute @r <$> splitAt' dim i arr) === (left, compute @r (append' dim center right)) .&&.+  (compute @r splitLeft, splitRight) === (compute @r (append' dim left center), right)+  where i = getDim' ix dim+        k = getDim' (unSz (size arr)) dim+        n' = n `mod` (k - i)+        (left, center, right) = either throw id (splitExtractM dim i (Sz n') arr)+        (splitLeft, splitRight) = splitAt' dim (i + n') arr++prop_ConcatAppend ::+     forall r ix. (Eq (Array r ix Int), Show (Array r ix Int), Mutable r ix Int)+  => DimIx ix+  -> Comp+  -> Sz ix+  -> NonEmptyList (Fun ix Int)+  -> Property+prop_ConcatAppend (DimIx dim) comp sz (NonEmpty fns) =+  foldl1 (\arr -> compute @r . append' dim arr) arrs ===+  compute @r (concat' dim arrs)+  where+    arrs = P.zipWith (\ f i -> makeArray @r comp sz ((+i) . apply f)) fns [0 .. ]++prop_ConcatMConcatOuterM ::+     forall r ix. (Eq (Array r ix Int), Show (Array r ix Int), Mutable r ix Int)+  => Comp+  -> Sz ix+  -> NonEmptyList (Fun ix Int)+  -> Property+prop_ConcatMConcatOuterM comp sz (NonEmpty fns) =+  property $ do+    as <- compute @r <$> concatM (dimensions sz) arrs+    as' <- compute @r <$> concatOuterM (P.map toLoadArray arrs)+    as `shouldBe` as'+  where+    arrs = P.zipWith (\ f i -> makeArray @r comp sz ((+i) . apply f)) fns [0 .. ]++prop_AppendMappend+  :: Array D Ix1 Int -> Array D Ix1 Int -> Property+prop_AppendMappend arr1 arr2 =+  computeAs P (append' 1 arr1 arr2) === computeAs P (toLoadArray arr1 <> toLoadArray arr2)++prop_ConcatMconcat+  :: [Array D Ix1 Int] -> Property+prop_ConcatMconcat arrs =+  computeAs P (concat' 1 (A.empty : arrs)) === computeAs P (mconcat (fmap toLoadArray arrs))++prop_ExtractSizeMismatch ::+     (Resize r ix, Load r ix e, NFData (Array r Int e)) => ArrTiny r ix e -> Positive Int -> Property+prop_ExtractSizeMismatch (ArrTiny arr) (Positive n) =+  assertExceptionIO (SizeElementsMismatchException sz sz' ==) $ resizeM sz' arr+  where+    sz = size arr+    sz' = Sz (totalElem sz + n)++prop_ZoomWithGridStrideCompute ::+     forall r ix e.+     ( Eq (Array r ix e)+     , Show (Array r ix e)+     , StrideLoad (R r) ix e+     , StrideLoad r ix e+     , Mutable r ix e+     , Extract r ix e+     )+  => Array r ix e+  -> Stride ix+  -> e+  -> Property+prop_ZoomWithGridStrideCompute arr stride defVal =+  (computeWithStride @r stride' arr' ===+   A.replicate Seq (Sz (liftIndex (+ 1) $ unSz (size arr))) defVal) .&&.+  (computeWithStride @r stride' (extract' (pureIndex 1) sz' arr') === compute arr)+  where+    arr' = compute @r (zoomWithGrid defVal stride arr)+    sz' = Sz (liftIndex (subtract 1) $ unSz (size arr'))+    stride' = Stride (liftIndex (+ 1) $ unStride stride)++prop_ZoomStrideCompute ::+     forall r ix e. (Eq (Array r ix e), Show (Array r ix e), StrideLoad r ix e, Mutable r ix e)+  => Array r ix e+  -> Stride ix+  -> Property+prop_ZoomStrideCompute arr stride = computeWithStride @r stride arr' === compute arr+  where+    arr' = compute @r (zoom stride arr)+++type Transform r ix e+   = ( Show e+     , Eq e+     , Arbitrary e+     , Arbitrary ix+     , Typeable e+     , Typeable ix+     , CoArbitrary e+     , CoArbitrary ix+     , Function e+     , Function ix+     , Eq (Array r ix e)+     , Eq (Array (R r) ix e)+     , Eq (Array r ix Int)+     , Show (Array r ix e)+     , Show (Array (R r) ix e)+     , Show (Array r ix Int)+     , NFData (Array r ix e)+     , NFData (Array r Int e)+     , Resize r ix+     , Extract r ix e+     , Source (R r) ix e+     , StrideLoad r ix e+     , StrideLoad (R r) ix e+     , Mutable r ix Int+     , Mutable r ix e)++specTransformR ::+     forall r ix e. Transform r ix e+  => Spec+specTransformR =+  describe ("Transform (" ++ showsArrayType @r @ix @e ")") $ do+    prop "UpsampleDownsample" (prop_UpsampleDownsample @r @ix @e)+    prop "ExtractSizeMismatch" (prop_ExtractSizeMismatch @r @ix @e)+    prop "ExtractAppend" (prop_ExtractAppend @r @ix @e)+    prop "SplitExtract" (prop_SplitExtract @r @ix @e)+    prop "ConcatAppend" (prop_ConcatAppend @r @ix)+    prop "ConcatMConcatOuterM" (prop_ConcatMConcatOuterM @r @ix)+    prop "ZoomStrideCompute" (prop_ZoomStrideCompute @r @ix @e)+    prop "ZoomWithGridStrideCompute" (prop_ZoomWithGridStrideCompute @r @ix @e)++spec :: Spec+spec = do+  it "transposeOuterInner" $ property prop_TransposeOuterInner+  specTransformR @P @Ix1 @Int+  specTransformR @P @Ix2 @Int+  specTransformR @P @Ix3 @Int+  specTransformR @P @Ix4 @Int+  describe "Monoid" $ do+    it "Ix1" $ property prop_AppendMappend+    it "Ix1" $ property prop_ConcatMconcat+  describe "Sequence" $ do+    it "ConsSnoc" $ property prop_ConsSnoc+    it "UnconsUnsnoc" $ property prop_UnconsUnsnoc+++prop_UnconsUnsnoc :: Array D Ix1 Int -> Bool -> Property+prop_UnconsUnsnoc arr unconsFirst =+  preJust $ do+    (arr', u, s) <-+      if unconsFirst+        then do+          (u, au) <- unconsM arr+          (as, s) <- unsnocM au+          pure (as, u, s)+        else do+          (as, s) <- unsnocM arr+          (u, au) <- unconsM as+          pure (au, u, s)+    pure (computeAs U (A.snoc (A.cons u (toLoadArray (computeAs U arr'))) s) === compute arr)++preJust :: Testable prop => Maybe prop -> Property+preJust m = isJust m ==> fromJust m++prop_ConsSnoc :: Array D Ix1 Int -> [SeqOp Int] -> Property+prop_ConsSnoc arr ops =+  A.toList (computeAs U (foldl' applyArraySeqOp (toLoadArray arr) ops)) ===+  F.toList (foldl' applySequenceSeqOp (S.fromList (A.toList arr)) ops)++data SeqOp e = Cons e | Snoc e deriving (Eq, Show)++instance Arbitrary e => Arbitrary (SeqOp e) where+  arbitrary = do+    e <- arbitrary+    elements [Cons e, Snoc e]++applyArraySeqOp :: Array DL Ix1 e -> SeqOp e -> Array DL Ix1 e+applyArraySeqOp arr = \case+  Cons x -> A.cons x arr+  Snoc x -> A.snoc arr x+++applySequenceSeqOp :: Seq a -> SeqOp a -> Seq a+applySequenceSeqOp arr = \case+  Cons x -> x <| arr+  Snoc x -> arr |> x
tests/Test/Massiv/Core/IndexSpec.hs view
@@ -1,7 +1,9 @@-{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module Test.Massiv.Core.IndexSpec (spec) where @@ -14,7 +16,6 @@ import Test.Validity.Ord (ordSpecOnArbitrary)  - specIxN ::      forall ix.      ( Num ix@@ -26,6 +27,7 @@      , Typeable (Lower ix)      , Arbitrary ix      , Arbitrary (Lower ix)+     , IsIndexDimension ix (Dimensions ix)      )   => Spec specIxN = do@@ -70,6 +72,7 @@      , Index (Lower ix)      , Arbitrary ix      , Arbitrary (Lower ix)+     , IsIndexDimension ix (Dimensions ix)      )   => (ix -> ix')   -> (ix' -> ix)