massiv 0.6.0.0 → 0.6.1.0
raw patch · 14 files changed
+358/−49 lines, 14 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Data.Massiv.Array: quicksortBy :: Mutable r Ix1 e => (e -> e -> Ordering) -> Vector r e -> Vector r e
+ Data.Massiv.Array: quicksortByM :: (Mutable r Ix1 e, MonadUnliftIO m) => (e -> e -> m Ordering) -> Vector r e -> m (Vector r e)
+ Data.Massiv.Array: replaceOuterSlice :: (MonadThrow m, Extract r ix e, Source (R r) ix e, Load (R r) (Lower ix) e, Resize (R r) (Lower ix)) => Ix1 -> Array (R r) (Lower ix) e -> Array r ix e -> m (Array DL ix e)
+ Data.Massiv.Array: replaceSlice :: (MonadThrow m, Extract r ix e, Source (R r) ix e, Load (R r) (Lower ix) e, Resize (R r) (Lower ix)) => Dim -> Ix1 -> Array (R r) (Lower ix) e -> Array r ix e -> m (Array DL ix e)
+ Data.Massiv.Array.Mutable: withLoadMArrayS :: forall r ix e r' m a. (Load r' ix e, Mutable r ix e, PrimMonad m) => Array r' ix e -> (MArray (PrimState m) r ix e -> m a) -> m (a, Array r ix e)
+ Data.Massiv.Array.Mutable: withLoadMArrayST :: forall r ix e r' a. (Load r' ix e, Mutable r ix e) => Array r' ix e -> (forall s. MArray s r ix e -> ST s a) -> (a, Array r ix e)
+ Data.Massiv.Array.Mutable: withLoadMArrayST_ :: forall r ix e r' a. (Load r' ix e, Mutable r ix e) => Array r' ix e -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e
+ Data.Massiv.Array.Mutable: withLoadMArrayS_ :: forall r ix e r' m a. (Load r' ix e, Mutable r ix e, PrimMonad m) => Array r' ix e -> (MArray (PrimState m) r ix e -> m a) -> m (Array r ix e)
+ Data.Massiv.Array.Mutable: withLoadMArray_ :: forall r ix e r' m b. (Load r' ix e, Mutable r ix e, MonadUnliftIO m) => Array r' ix e -> (Scheduler m () -> MArray RealWorld r ix e -> m b) -> m (Array r ix e)
+ Data.Massiv.Array.Mutable.Algorithms: quicksortByM_ :: (Mutable r Ix1 e, PrimMonad m) => (e -> e -> m Ordering) -> Scheduler m () -> MVector (PrimState m) r e -> m ()
+ Data.Massiv.Core: class Num e => FoldNumeric r e
+ Data.Massiv.Core: class FoldNumeric r e => Numeric r e
+ Data.Massiv.Core: class (Numeric r e, Floating e) => NumericFloat r e
- Data.Massiv.Array: tally :: (Mutable r Ix1 e, Resize r ix, Load r ix e, Ord e) => Array r ix e -> Array DS Ix1 (e, Int)
+ Data.Massiv.Array: tally :: (Mutable r Ix1 e, Resize r ix, Load r ix e, Ord e) => Array r ix e -> Vector DS (e, Int)
- Data.Massiv.Array.Mutable.Algorithms: quicksortM_ :: (Ord e, Mutable r Ix1 e, PrimMonad m) => Scheduler m () -> MArray (PrimState m) r Ix1 e -> m ()
+ Data.Massiv.Array.Mutable.Algorithms: quicksortM_ :: (Ord e, Mutable r Ix1 e, PrimMonad m) => Scheduler m () -> MVector (PrimState m) r e -> m ()
- Data.Massiv.Array.Mutable.Algorithms: unstablePartitionM :: forall r e m. (Mutable r Ix1 e, PrimMonad m) => MArray (PrimState m) r Ix1 e -> (e -> Bool) -> m Ix1
+ Data.Massiv.Array.Mutable.Algorithms: unstablePartitionM :: forall r e m. (Mutable r Ix1 e, PrimMonad m) => MVector (PrimState m) r e -> (e -> Bool) -> m Ix1
- Data.Massiv.Array.Unsafe: unsafeUnstablePartitionRegionM :: forall r e m. (Mutable r Ix1 e, PrimMonad m) => MArray (PrimState m) r Ix1 e -> (e -> Bool) -> Ix1 -> Ix1 -> m Ix1
+ Data.Massiv.Array.Unsafe: unsafeUnstablePartitionRegionM :: forall r e m. (Mutable r Ix1 e, PrimMonad m) => MVector (PrimState m) r e -> (e -> Bool) -> Ix1 -> Ix1 -> m Ix1
Files
- CHANGELOG.md +8/−0
- massiv.cabal +1/−1
- src/Data/Massiv/Array.hs +3/−1
- src/Data/Massiv/Array/Manifest/Primitive.hs +4/−0
- src/Data/Massiv/Array/Manifest/Storable.hs +4/−0
- src/Data/Massiv/Array/Manifest/Unboxed.hs +3/−0
- src/Data/Massiv/Array/Mutable.hs +78/−1
- src/Data/Massiv/Array/Mutable/Algorithms.hs +2/−1
- src/Data/Massiv/Array/Ops/Sort.hs +88/−30
- src/Data/Massiv/Array/Ops/Transform.hs +92/−0
- src/Data/Massiv/Core.hs +5/−0
- src/Data/Massiv/Core/Common.hs +2/−2
- src/Data/Massiv/Vector.hs +57/−13
- tests/doctests.hs +11/−0
CHANGELOG.md view
@@ -1,3 +1,11 @@+# 0.6.1++* Addition of `withLoadMArray_`, `withLoadMArrayS`, `withLoadMArrayS_`,+ `withLoadMArrayST`, `withLoadMArrayST_`+* Addition of `replaceSlice` and `replaceOuterSlice`+* Addition of `quicksortBy`, `quicksortByM` and `quicksortByM_`+* Fix performance regression for `quicksort` and `quicksortM_` introduced in previous release.+ # 0.6.0 * Fix semantics of `Applicative`, `Num` and `Fractional` instance for `D` arrays:
massiv.cabal view
@@ -1,5 +1,5 @@ name: massiv-version: 0.6.0.0+version: 0.6.1.0 synopsis: Massiv (Массив) is an Array Library. description: Multi-dimensional Arrays with fusion, stencils and parallel computation. homepage: https://github.com/lehins/massiv
src/Data/Massiv/Array.hs view
@@ -133,6 +133,8 @@ -- * Algorithms -- ** Sorting , quicksort+ , quicksortBy+ , quicksortByM , tally -- ** Iterations , iterateUntil@@ -162,7 +164,7 @@ import Data.Massiv.Array.Ops.Fold import Data.Massiv.Array.Ops.Map import Data.Massiv.Array.Ops.Slice-import Data.Massiv.Array.Ops.Sort (quicksort, tally)+import Data.Massiv.Array.Ops.Sort import Data.Massiv.Array.Ops.Transform import Data.Massiv.Array.Stencil import Data.Massiv.Core
src/Data/Massiv/Array/Manifest/Primitive.hs view
@@ -91,6 +91,10 @@ rnf (PArray c sz o a) = c `deepseq` sz `deepseq` o `seq` a `seq` () {-# INLINE rnf #-} +instance NFData ix => NFData (MArray s P ix e) where+ rnf (MPArray sz _o _mb) = sz `deepseq` ()+ {-# INLINE rnf #-}+ instance (Prim e, Eq e, Index ix) => Eq (Array P ix e) where (==) = eqArrays (==) {-# INLINE (==) #-}
src/Data/Massiv/Array/Manifest/Storable.hs view
@@ -79,6 +79,10 @@ rnf (SArray c sz v) = c `deepseq` sz `deepseq` v `deepseq` () {-# INLINE rnf #-} +instance NFData ix => NFData (MArray s S ix e) where+ rnf (MSArray sz mv) = sz `deepseq` mv `deepseq` ()+ {-# INLINE rnf #-}+ instance (Storable e, Eq e, Index ix) => Eq (Array S ix e) where (==) = eqArrays (==) {-# INLINE (==) #-}
src/Data/Massiv/Array/Manifest/Unboxed.hs view
@@ -58,6 +58,9 @@ rnf (UArray c sz v) = c `deepseq` sz `deepseq` v `deepseq` () {-# INLINE rnf #-} +instance NFData ix => NFData (MArray s U ix e) where+ rnf (MUArray sz mv) = sz `deepseq` mv `deepseq` ()+ {-# INLINE rnf #-} instance (VU.Unbox e, Index ix) => Construct U ix e where setComp c arr = arr { uComp = c }
src/Data/Massiv/Array/Mutable.hs view
@@ -81,10 +81,15 @@ -- *** Modify , withMArray , withMArray_+ , withLoadMArray_ , withMArrayS+ , withLoadMArrayS , withMArrayS_+ , withLoadMArrayS_ , withMArrayST+ , withLoadMArrayST , withMArrayST_+ , withLoadMArrayST_ -- *** Initialize , initialize , initializeNew@@ -851,6 +856,28 @@ {-# INLINE withMArray_ #-} +-- | Same as `withMArray_`, but the array supplied to this function can be any loadable+-- array. For that reason it will be faster if supplied array is delayed.+--+-- @since 0.6.1+withLoadMArray_ ::+ forall r ix e r' m b. (Load r' ix e, Mutable r ix e, MonadUnliftIO m)+ => Array r' ix e+ -> (Scheduler m () -> MArray RealWorld r ix e -> m b)+ -> m (Array r ix e)+withLoadMArray_ arr action = do+ marr <- liftIO $ unsafeNew (size arr)+ withScheduler_ (getComp arr) $ \scheduler -> do+ runBatch_ scheduler $ \_ -> loadArrayM scheduler arr (\i -> liftIO . unsafeLinearWrite marr i)+ action scheduler marr+ liftIO $ unsafeFreeze (getComp arr) marr+{-# INLINE[2] withLoadMArray_ #-}+{-# RULES+"withLoadMArray_/withMArray_" [~2] withLoadMArray_ = withMArray_+"withLoadMArrayS/withMArrayS" [~2] withLoadMArrayS = withMArrayS+"withLoadMArrayS_/withMArrayS_" [~2] withLoadMArrayS_ = withMArrayS_+#-}+ -- | Create a copy of a pure array, mutate it in place and return its frozen version. The important -- benefit over doing a manual `thawS` followed by a `freezeS` is that an array will only be copied -- once.@@ -868,7 +895,7 @@ {-# INLINE withMArrayS #-} --- | Same as `withMArrayS`, but discards rhe element produced by the supplied action+-- | Same as `withMArrayS`, except it discards the value produced by the supplied action -- -- @since 0.5.0 withMArrayS_ ::@@ -880,6 +907,33 @@ {-# INLINE withMArrayS_ #-} +-- | Same as `withMArrayS`, but will work with any loadable array.+--+-- @since 0.6.1+withLoadMArrayS ::+ forall r ix e r' m a. (Load r' ix e, Mutable r ix e, PrimMonad m)+ => Array r' ix e+ -> (MArray (PrimState m) r ix e -> m a)+ -> m (a, Array r ix e)+withLoadMArrayS arr action = do+ marr <- unsafeNew (size arr)+ loadArrayM trivialScheduler_ arr (unsafeLinearWrite marr)+ a <- action marr+ (,) a <$> unsafeFreeze (getComp arr) marr+{-# INLINE[2] withLoadMArrayS #-}++-- | Same as `withMArrayS_`, but will work with any loadable array.+--+-- @since 0.6.1+withLoadMArrayS_ ::+ forall r ix e r' m a. (Load r' ix e, Mutable r ix e, PrimMonad m)+ => Array r' ix e+ -> (MArray (PrimState m) r ix e -> m a)+ -> m (Array r ix e)+withLoadMArrayS_ arr action = snd <$> withLoadMArrayS arr action+{-# INLINE[2] withLoadMArrayS_ #-}++ -- | Same as `withMArrayS` but in `ST`. This is not only pure, but also the safest way to do -- mutation to the array. --@@ -900,6 +954,29 @@ Mutable r ix e => Array r ix e -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e withMArrayST_ arr f = runST $ withMArrayS_ arr f {-# INLINE withMArrayST_ #-}+++-- | Same as `withMArrayST`, but works with any loadable array.+--+-- @since 0.6.1+withLoadMArrayST ::+ forall r ix e r' a. (Load r' ix e, Mutable r ix e)+ => Array r' ix e+ -> (forall s. MArray s r ix e -> ST s a)+ -> (a, Array r ix e)+withLoadMArrayST arr f = runST $ withLoadMArrayS arr f+{-# INLINE[2] withLoadMArrayST #-}++-- | Same as `withMArrayST_`, but works with any loadable array.+--+-- @since 0.6.1+withLoadMArrayST_ ::+ forall r ix e r' a. (Load r' ix e, Mutable r ix e)+ => Array r' ix e+ -> (forall s. MArray s r ix e -> ST s a)+ -> Array r ix e+withLoadMArrayST_ arr f = runST $ withLoadMArrayS_ arr f+{-# INLINE[2] withLoadMArrayST_ #-} -- | /O(1)/ - Lookup an element in the mutable array. Returns `Nothing` when index is out of bounds.
src/Data/Massiv/Array/Mutable/Algorithms.hs view
@@ -10,6 +10,7 @@ -- module Data.Massiv.Array.Mutable.Algorithms ( quicksortM_+ , quicksortByM_ , unstablePartitionM , iterateUntilM ) where@@ -36,7 +37,7 @@ -- @since 0.3.2 unstablePartitionM :: forall r e m. (Mutable r Ix1 e, PrimMonad m)- => MArray (PrimState m) r Ix1 e+ => MVector (PrimState m) r e -> (e -> Bool) -- ^ Predicate -> m Ix1 unstablePartitionM marr f = unsafeUnstablePartitionRegionM marr f 0 (unSz (msize marr) - 1)
src/Data/Massiv/Array/Ops/Sort.hs view
@@ -12,10 +12,14 @@ module Data.Massiv.Array.Ops.Sort ( tally , quicksort+ , quicksortBy+ , quicksortByM , quicksortM_+ , quicksortByM_ , unsafeUnstablePartitionRegionM ) where +import Control.Monad.IO.Unlift import Control.Monad (when) import Control.Scheduler import Data.Massiv.Array.Delayed.Stream@@ -25,7 +29,7 @@ import Data.Massiv.Vector (scatMaybes, sunfoldrN) import System.IO.Unsafe --- | Count how many occurance of each element there is in the array. Results will be+-- | Count number of occurrences of each element in the array. Results will be -- sorted in ascending order of the element. -- -- ==== __Example__@@ -40,7 +44,7 @@ -- [ (1,1), (2,3), (3,1), (4,2), (5,1) ] -- -- @since 0.4.4-tally :: (Mutable r Ix1 e, Resize r ix, Load r ix e, Ord e) => Array r ix e -> Array DS Ix1 (e, Int)+tally :: (Mutable r Ix1 e, Resize r ix, Load r ix e, Ord e) => Array r ix e -> Vector DS (e, Int) tally arr | isEmpty arr = setComp (getComp arr) empty | otherwise = scatMaybes $ sunfoldrN (sz + 1) count (0, 0, sorted ! 0)@@ -58,36 +62,48 @@ {-# INLINE tally #-} ---- | Partition a segment of a vector. Starting and ending indices are unchecked.------ @since 0.3.2-unsafeUnstablePartitionRegionM ::+unsafeUnstablePartitionRegionM' :: forall r e m. (Mutable r Ix1 e, PrimMonad m) => MArray (PrimState m) r Ix1 e- -> (e -> Bool)+ -> (e -> m Bool) -> Ix1 -- ^ Start index of the region -> Ix1 -- ^ End index of the region -> m Ix1-unsafeUnstablePartitionRegionM marr f start end = fromLeft start (end + 1)+unsafeUnstablePartitionRegionM' marr f start end = fromLeft start (end + 1) where fromLeft i j | i == j = pure i | otherwise = do- x <- unsafeRead marr i- if f x+ e <- f =<< unsafeLinearRead marr i+ if e then fromLeft (i + 1) j else fromRight i (j - 1) fromRight i j | i == j = pure i | otherwise = do- x <- unsafeRead marr j- if f x+ x <- unsafeLinearRead marr j+ e <- f x+ if e then do- unsafeWrite marr j =<< unsafeRead marr i- unsafeWrite marr i x+ unsafeLinearWrite marr j =<< unsafeLinearRead marr i+ unsafeLinearWrite marr i x fromLeft (i + 1) j else fromRight i (j - 1)+{-# INLINE unsafeUnstablePartitionRegionM' #-}+++-- TODO: Replace `unsafeUnstablePartitionRegionM` with `unsafeUnstablePartitionRegionM'`+-- | Partition a segment of a vector. Starting and ending indices are unchecked.+--+-- @since 0.3.2+unsafeUnstablePartitionRegionM ::+ forall r e m. (Mutable r Ix1 e, PrimMonad m)+ => MVector (PrimState m) r e+ -> (e -> Bool)+ -> Ix1 -- ^ Start index of the region+ -> Ix1 -- ^ End index of the region+ -> m Ix1+unsafeUnstablePartitionRegionM marr f = unsafeUnstablePartitionRegionM' marr (pure . f) {-# INLINE unsafeUnstablePartitionRegionM #-} @@ -104,39 +120,81 @@ {-# INLINE quicksort #-} +-- | Same as `quicksortBy`, but instead of `Ord` constraint expects a custom `Ordering`.+--+-- @since 0.6.1+quicksortByM ::+ (Mutable r Ix1 e, MonadUnliftIO m) => (e -> e -> m Ordering) -> Vector r e -> m (Vector r e)+quicksortByM f arr = withRunInIO $ \run -> withMArray_ arr (quicksortByM_ (\x y -> run (f x y)))+{-# INLINE quicksortByM #-} +-- | Same as `quicksortBy`, but instead of `Ord` constraint expects a custom `Ordering`.+--+-- @since 0.6.1+quicksortBy ::+ (Mutable r Ix1 e) => (e -> e -> Ordering) -> Vector r e -> Vector r e+quicksortBy f arr =+ unsafePerformIO $ withMArray_ arr (quicksortByM_ (\x y -> pure $ f x y))+{-# INLINE quicksortBy #-}+ -- | Mutable version of `quicksort` -- -- @since 0.3.2 quicksortM_ :: (Ord e, Mutable r Ix1 e, PrimMonad m) => Scheduler m ()- -> MArray (PrimState m) r Ix1 e+ -> MVector (PrimState m) r e -> m ()-quicksortM_ scheduler marr =+quicksortM_ = quicksortInternalM_ (\e1 e2 -> pure $ e1 < e2) (\e1 e2 -> pure $ e1 == e2)+{-# INLINE quicksortM_ #-}+++-- | Same as `quicksortM_`, but instead of `Ord` constraint expects a custom `Ordering`.+--+-- @since 0.6.1+quicksortByM_ ::+ (Mutable r Ix1 e, PrimMonad m)+ => (e -> e -> m Ordering)+ -> Scheduler m ()+ -> MVector (PrimState m) r e+ -> m ()+quicksortByM_ compareM =+ quicksortInternalM_ (\x y -> (LT ==) <$> compareM x y) (\x y -> (EQ ==) <$> compareM x y)+{-# INLINE quicksortByM_ #-}+++quicksortInternalM_ ::+ (Mutable r Ix1 e, PrimMonad m)+ => (e -> e -> m Bool)+ -> (e -> e -> m Bool)+ -> Scheduler m ()+ -> MVector (PrimState m) r e+ -> m ()+quicksortInternalM_ fLT fEQ scheduler marr = scheduleWork scheduler $ qsort (numWorkers scheduler) 0 (unSz (msize marr) - 1) where- leSwap i j = do- ei <- unsafeRead marr i- ej <- unsafeRead marr j- if ei < ej+ ltSwap i j = do+ ei <- unsafeLinearRead marr i+ ej <- unsafeLinearRead marr j+ lt <- fLT ei ej+ if lt then do- unsafeWrite marr i ej- unsafeWrite marr j ei+ unsafeLinearWrite marr i ej+ unsafeLinearWrite marr j ei pure ei else pure ej- {-# INLINE leSwap #-}+ {-# INLINE ltSwap #-} getPivot lo hi = do let !mid = (hi + lo) `div` 2- _ <- leSwap mid lo- _ <- leSwap hi lo- leSwap mid hi+ _ <- ltSwap mid lo+ _ <- ltSwap hi lo+ ltSwap mid hi {-# INLINE getPivot #-} qsort !n !lo !hi = when (lo < hi) $ do p <- getPivot lo hi- l <- unsafeUnstablePartitionRegionM marr (< p) lo (hi - 1)- h <- unsafeUnstablePartitionRegionM marr (== p) l hi+ l <- unsafeUnstablePartitionRegionM' marr (`fLT` p) lo (hi - 1)+ h <- unsafeUnstablePartitionRegionM' marr (`fEQ` p) l hi if n > 0 then do let !n' = n - 1@@ -145,4 +203,4 @@ else do qsort n lo (l - 1) qsort n h hi-{-# INLINE quicksortM_ #-}+{-# INLINE quicksortInternalM_ #-}
src/Data/Massiv/Array/Ops/Transform.hs view
@@ -49,6 +49,8 @@ , splitAtM , splitAt' , splitExtractM+ , replaceSlice+ , replaceOuterSlice -- ** Upsample/Downsample , upsample , downsample@@ -748,6 +750,96 @@ rightArr <- extractFromToM rightArrStartIx szIx arr pure (leftArr, midArr, rightArr) {-# INLINE splitExtractM #-}++++-- | Replace a slice of an array with another one+--+-- ==== __Example__+--+-- >>> import Data.Massiv.Array+-- >>> arr = makeArrayR U Seq (Sz3 3 4 5) fromIx3+-- >>> arr' = makeArrayR U Seq (Sz3 3 4 5) (fromIx3 . liftIndex (* 100))+-- >>> replaceSlice 2 1 (arr' <!> (2, 3)) arr+-- Array DL Seq (Sz (3 :> 4 :. 5))+-- [ [ [ (0,0,0), (0,0,1), (0,0,2), (0,0,3), (0,0,4) ]+-- , [ (0,300,0), (0,300,100), (0,300,200), (0,300,300), (0,300,400) ]+-- , [ (0,2,0), (0,2,1), (0,2,2), (0,2,3), (0,2,4) ]+-- , [ (0,3,0), (0,3,1), (0,3,2), (0,3,3), (0,3,4) ]+-- ]+-- , [ [ (1,0,0), (1,0,1), (1,0,2), (1,0,3), (1,0,4) ]+-- , [ (100,300,0), (100,300,100), (100,300,200), (100,300,300), (100,300,400) ]+-- , [ (1,2,0), (1,2,1), (1,2,2), (1,2,3), (1,2,4) ]+-- , [ (1,3,0), (1,3,1), (1,3,2), (1,3,3), (1,3,4) ]+-- ]+-- , [ [ (2,0,0), (2,0,1), (2,0,2), (2,0,3), (2,0,4) ]+-- , [ (200,300,0), (200,300,100), (200,300,200), (200,300,300), (200,300,400) ]+-- , [ (2,2,0), (2,2,1), (2,2,2), (2,2,3), (2,2,4) ]+-- , [ (2,3,0), (2,3,1), (2,3,2), (2,3,3), (2,3,4) ]+-- ]+-- ]+--+-- @since 0.6.1+replaceSlice ::+ ( MonadThrow m+ , Extract r ix e+ , Source (R r) ix e+ , Load (R r) (Lower ix) e+ , Resize (R r) (Lower ix)+ )+ => Dim+ -> Ix1+ -> Array (R r) (Lower ix) e+ -> Array r ix e+ -> m (Array DL ix e)+replaceSlice dim i sl arr = do+ (l, m, r) <- splitExtractM dim i (SafeSz 1) arr+ m' <- resizeM (size m) sl+ concatM dim [l, m', r]+{-# INLINE replaceSlice #-}+++-- | Replace an outer slice of an array with another one+--+-- ==== __Example__+--+-- >>> import Data.Massiv.Array+-- >>> arr = makeArrayR U Seq (Sz3 3 4 5) fromIx3+-- >>> arr' = makeArrayR U Seq (Sz3 3 4 5) (fromIx3 . liftIndex (* 100))+-- >>> replaceOuterSlice 1 (arr' !> 2) arr+-- Array DL Seq (Sz (3 :> 4 :. 5))+-- [ [ [ (0,0,0), (0,0,1), (0,0,2), (0,0,3), (0,0,4) ]+-- , [ (0,1,0), (0,1,1), (0,1,2), (0,1,3), (0,1,4) ]+-- , [ (0,2,0), (0,2,1), (0,2,2), (0,2,3), (0,2,4) ]+-- , [ (0,3,0), (0,3,1), (0,3,2), (0,3,3), (0,3,4) ]+-- ]+-- , [ [ (200,0,0), (200,0,100), (200,0,200), (200,0,300), (200,0,400) ]+-- , [ (200,100,0), (200,100,100), (200,100,200), (200,100,300), (200,100,400) ]+-- , [ (200,200,0), (200,200,100), (200,200,200), (200,200,300), (200,200,400) ]+-- , [ (200,300,0), (200,300,100), (200,300,200), (200,300,300), (200,300,400) ]+-- ]+-- , [ [ (2,0,0), (2,0,1), (2,0,2), (2,0,3), (2,0,4) ]+-- , [ (2,1,0), (2,1,1), (2,1,2), (2,1,3), (2,1,4) ]+-- , [ (2,2,0), (2,2,1), (2,2,2), (2,2,3), (2,2,4) ]+-- , [ (2,3,0), (2,3,1), (2,3,2), (2,3,3), (2,3,4) ]+-- ]+-- ]+--+-- @since 0.6.1+replaceOuterSlice ::+ ( MonadThrow m+ , Extract r ix e+ , Source (R r) ix e+ , Load (R r) (Lower ix) e+ , Resize (R r) (Lower ix)+ )+ => Ix1+ -> Array (R r) (Lower ix) e+ -> Array r ix e+ -> m (Array DL ix e)+replaceOuterSlice i sl arr = replaceSlice (dimensions (size arr)) i sl arr+{-# INLINE replaceOuterSlice #-}+ -- | Delete a region from an array along the specified dimension. --
src/Data/Massiv/Core.hs view
@@ -38,6 +38,10 @@ , WorkerStates , initWorkerStates , module Data.Massiv.Core.Index+ -- * Numeric+ , FoldNumeric+ , Numeric+ , NumericFloat -- * Exceptions , MonadThrow(..) , throw@@ -56,6 +60,7 @@ import Data.Massiv.Core.Index import Data.Massiv.Core.List import Data.Massiv.Core.Exception+import Data.Massiv.Core.Operations (FoldNumeric, Numeric, NumericFloat) -- | Append computation strategy using `Comp`'s `Monoid` instance.
src/Data/Massiv/Core/Common.hs view
@@ -565,7 +565,7 @@ -- @since 0.1.0 unsafeRead :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> m e-unsafeRead !marr !ix = unsafeLinearRead marr (toLinearIndex (msize marr) ix)+unsafeRead marr = unsafeLinearRead marr . toLinearIndex (msize marr) {-# INLINE unsafeRead #-} -- | Write an element into array@@ -573,7 +573,7 @@ -- @since 0.1.0 unsafeWrite :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> e -> m ()-unsafeWrite !marr !ix = unsafeLinearWrite marr (toLinearIndex (msize marr) ix)+unsafeWrite marr = unsafeLinearWrite marr . toLinearIndex (msize marr) {-# INLINE unsafeWrite #-}
src/Data/Massiv/Vector.hs view
@@ -429,7 +429,7 @@ -- -- /Related/: `head'`, `shead'`, `sheadM`, `unconsM`. ----- /__Throws Exceptions__/: `SizeEmptyException`+-- /__Throws Exceptions__/: `SizeEmptyException` when array is empty -- -- ==== __Examples__ --@@ -1410,7 +1410,7 @@ {-# INLINE sfilter #-} --- | Similar to `sfilter`, but map with an index aware function.+-- | Similar to `sfilter`, but filter with an index aware function. -- -- ==== __Examples__ --@@ -1462,12 +1462,10 @@ {-# INLINE sfilterM #-} --- | Similar to `filterM`, but map with an index aware function.+-- | Similar to `filterM`, but filter with an index aware function. -- -- Corresponds to: @`filterM` (uncurry f) . `simap` (,)@ ----- ==== __Examples__--- -- @since 0.5.0 sifilterM :: (Stream r ix a, Applicative f) => (ix -> a -> f Bool) -> Array r ix a -> f (Vector DS a)@@ -2458,63 +2456,109 @@ --- |+-- | Add all elements of the array together --+-- /Related/: `sum`.+-- -- ==== __Examples__ --+-- >>> import Data.Massiv.Vector as V+-- >>> V.ssum $ V.sfromList [10, 3, 70, 5 :: Int]+-- 88+-- -- @since 0.5.0 ssum :: (Num e, Stream r ix e) => Array r ix e -> e ssum = sfoldl (+) 0 {-# INLINE ssum #-} --- |+-- | Multiply all elements of the array together --+-- /Related/: `product`.+-- -- ==== __Examples__ --+-- >>> import Data.Massiv.Vector as V+-- >>> V.sproduct $ V.sfromList [10, 3, 70, 5 :: Int]+-- 10500+-- -- @since 0.5.0 sproduct :: (Num e, Stream r ix e) => Array r ix e -> e sproduct = sfoldl (*) 1 {-# INLINE sproduct #-} --- |+-- | /O(n)/ - Find the largest value in the array. Throws an error on empty. --+-- /Related/: `smaximumM`, `maximum`, `maximumM`.+-- -- ==== __Examples__ --+-- >>> import Data.Massiv.Vector as V+-- >>> V.smaximum' $ V.sfromList [10, 3, 70, 5 :: Int]+-- 70+-- >>> V.smaximum' (V.empty :: Vector D Int)+-- *** Exception: SizeEmptyException: (Sz1 0) corresponds to an empty array+-- -- @since 0.5.0 smaximum' :: (Ord e, Stream r ix e) => Array r ix e -> e smaximum' = sfoldl1' max {-# INLINE smaximum' #-} --- |+-- | /O(n)/ - Find the largest value in the array. --+-- /Related/: `smaximum`, `maximum`, `maximumM`.+--+-- /__Throws Exceptions__/: `SizeEmptyException` when array is empty+-- -- ==== __Examples__ --+-- >>> import Data.Massiv.Vector as V+-- >>> V.smaximumM $ V.sfromList [10, 3, 70, 5 :: Int]+-- 70+-- >>> V.smaximumM (V.empty :: Vector D Int) :: Maybe Int+-- Nothing+-- -- @since 0.5.0 smaximumM :: (Ord e, Stream r ix e, MonadThrow m) => Array r ix e -> m e smaximumM = sfoldl1M (\e acc -> pure (max e acc)) {-# INLINE smaximumM #-} ---- |+-- | /O(n)/ - Find the smallest value in the array. Throws an error on empty. --+-- /Related/: `sminimumM`, `minimum`, `minimumM`.+-- -- ==== __Examples__ --+-- >>> import Data.Massiv.Vector as V+-- >>> V.sminimum' $ V.sfromList [10, 3, 70, 5 :: Int]+-- 3+-- >>> V.sminimum' (V.empty :: Array D Ix2 Int)+-- *** Exception: SizeEmptyException: (Sz (0 :. 0)) corresponds to an empty array+-- -- @since 0.5.0 sminimum' :: (Ord e, Stream r ix e) => Array r ix e -> e sminimum' = sfoldl1' min {-# INLINE sminimum' #-} --- |+-- | /O(n)/ - Find the smallest value in the array. --+-- /Related/: `sminimum'`, `minimum`, `minimumM`.+--+-- /__Throws Exceptions__/: `SizeEmptyException` when array is empty+-- -- ==== __Examples__ --+-- >>> import Data.Massiv.Vector as V+-- >>> V.sminimumM $ V.sfromList [10, 3, 70, 5 :: Int]+-- 3+-- >>> V.sminimumM (V.empty :: Array D Ix2 Int) :: Maybe Int+-- Nothing+-- -- @since 0.5.0 sminimumM :: (Ord e, Stream r ix e, MonadThrow m) => Array r ix e -> m e sminimumM = sfoldl1M (\e acc -> pure (min e acc)) {-# INLINE sminimumM #-}- -- | See `stake`.
tests/doctests.hs view
@@ -1,6 +1,17 @@+{-# LANGUAGE CPP #-} module Main where +#if __GLASGOW_HASKELL__ >= 802 && __GLASGOW_HASKELL__ < 810+ import Test.DocTest (doctest) main :: IO () main = doctest ["-Iinclude","src"]++#else++-- TODO: fix doctest support+main :: IO ()+main = putStrLn "\nDoctests are not supported for older ghc version\n"++#endif