{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} module Test.Massiv.Array.Ops.SliceSpec (spec) where import Control.Applicative ((<|>)) import Data.Massiv.Array as A import Test.Massiv.Core ----------- -- Size -- ----------- prop_ExtractEqualsExtractFromTo :: (Source r e, Eq e, Show e, Ragged L ix e) => proxy (r, ix, e) -> SzIx ix -> Array r ix e -> Property prop_ExtractEqualsExtractFromTo _ (SzIx (Sz eIx) sIx) arr = (extractFromToM sIx eIx arr <|> Nothing) === extractM sIx (Sz (liftIndex2 (-) eIx sIx)) arr specSizeN :: ( HasCallStack , Eq e , Show e , Ragged L ix e , Arbitrary (Array r ix e) , Show (Array r ix e) , Source r e , Arbitrary ix ) => proxy (r, ix, e) -> Spec specSizeN proxy = describe "extract" $ it "ExtractEqualsExtractFromTo" $ property $ prop_ExtractEqualsExtractFromTo proxy ----------- -- Slice -- ----------- prop_SliceOuter :: ( HasCallStack , Source r e , Index ix , Ragged L (Lower ix) e , Show e , Eq e , Show (Array r (Lower ix) e) ) => proxy (r, ix, e) -> Ix1 -> Array r ix e -> Property prop_SliceOuter _ i arr = expectProp $ if isSafeIndex (fst (unconsSz (size arr))) i then do e1 <- arr !?> i e2 <- arr (dimensions (size arr), i) delay e1 `shouldBe` e2 else do arr !?> i `shouldSatisfy` isNothing arr (dimensions (size arr), i) `shouldSatisfy` isNothing prop_SliceInner :: (HasCallStack, Source r e, Index ix, Ragged L (Lower ix) e, Show e, Eq e) => proxy (r, ix, e) -> Int -> Array r ix e -> Property prop_SliceInner _ i arr = expectProp $ do if isSafeIndex (snd (unsnocSz (size arr))) i then do e1 <- arr (1, i) e1 `shouldBe` e2 else do arr (1, i) `shouldSatisfy` isNothing prop_SliceIndexDim2 :: (HasCallStack, Source r Int) => ArrIx r Ix2 Int -> Property prop_SliceIndexDim2 (ArrIx arr ix@(i :. j)) = expectProp $ do val <- evaluateM arr ix evaluateM (arr !> i) j `shouldReturn` val evaluateM (arr (2, i)) j `shouldReturn` val evaluateM (arr (1, j)) i `shouldReturn` val prop_SliceIndexDim3 :: (HasCallStack, Source r Int) => ArrIx r Ix3 Int -> Property prop_SliceIndexDim3 (ArrIx arr ix@(i :> j :. k)) = expectProp $ do val <- evaluateM arr ix evaluateM (arr i !> j) k `shouldReturn` val evaluateM (arr i) j `shouldReturn` val evaluateM (arr !> i (3, i) (2, j)) k `shouldReturn` val evaluateM (arr (3, i) (1, k)) j `shouldReturn` val evaluateM (arr (2, j) (2, i)) k `shouldReturn` val evaluateM (arr (2, j) (1, k)) i `shouldReturn` val evaluateM (arr (1, k) (2, i)) j `shouldReturn` val evaluateM (arr (1, k) (1, j)) i `shouldReturn` val prop_SliceIndexDim4 :: (HasCallStack, Source r Int) => ArrIx r Ix4 Int -> Property prop_SliceIndexDim4 (ArrIx arr ix@(i1 :> i2 :> i3 :. i4)) = expectProp $ do val <- evaluateM arr ix evaluateM (arr (4, i1) (3, i2) (2, i3)) i4 `shouldReturn` val evaluateM (arr (4, i1) (2, i3) (3, i2) (3, i1)) (i3 :. i4) `shouldReturn` val evaluateM (arr (2, i3) (2, i2)) (i1 :. i4) `shouldReturn` val evaluateM (arr (2, i3) (1, i4) !> i1) i2 `shouldReturn` val evaluateM (arr (1, i4) !> i1 !> i2) i3 `shouldReturn` val evaluateM (arr !> i1 !> i2 !> i3) i4 `shouldReturn` val evaluateM (arr !> i1 !> i2 i1 i1 i2) i3 `shouldReturn` val evaluateM (arr i1 !> i2) i3 `shouldReturn` val evaluateM (arr i1 i1) i2 `shouldReturn` val specSliceN :: ( HasCallStack , Source r e , Load r ix e , Arbitrary ix , Arbitrary e , Show (Array r ix e) , Ragged L (Lower ix) e , Show e , Eq e , Show (Array r (Lower ix) e) ) => proxy (r, ix, e) -> Spec specSliceN proxy = describe "Slice" $ do prop "SliceOuter" $ prop_SliceOuter proxy prop "SliceInner" $ prop_SliceInner proxy spec :: Spec spec = do describe "Ix1" $ specSizeN (Nothing :: Maybe (D, Ix1, Int)) describe "Ix2" $ do specSizeN (Nothing :: Maybe (D, Ix2, Int)) specSliceN (Nothing :: Maybe (D, Ix2, Int)) describe "SliceIndex" $ do prop "Delayed" $ prop_SliceIndexDim2 @D prop "Manifest" $ prop_SliceIndexDim2 @P describe "Ix3" $ do specSizeN (Nothing :: Maybe (D, Ix3, Int)) specSliceN (Nothing :: Maybe (D, Ix3, Int)) describe "SliceIndex" $ do prop "Delayed" $ prop_SliceIndexDim3 @D prop "Manifest" $ prop_SliceIndexDim3 @P describe "Ix4" $ do specSizeN (Nothing :: Maybe (D, Ix4, Int)) specSliceN (Nothing :: Maybe (D, Ix4, Int)) describe "SliceIndex" $ do prop "Delayed" $ prop_SliceIndexDim4 @D prop "Manifest" $ prop_SliceIndexDim4 @P