packages feed

massiv 0.2.5.0 → 0.2.6.0

raw patch · 19 files changed

+826/−194 lines, 19 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Massiv.Array: expandInner :: (Index ix, Manifest r (Lower ix) a) => Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b
+ Data.Massiv.Array: expandOuter :: (Index ix, Manifest r (Lower ix) a) => Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b
+ Data.Massiv.Array: expandWithin :: (IsIndexDimension ix n, Manifest r (Lower ix) a) => Dimension n -> Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b
+ Data.Massiv.Array: expandWithin' :: (Index ix, Manifest r (Lower ix) a) => Dim -> Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b
+ Data.Massiv.Array: forIO :: (Source r' ix a, Mutable r ix b) => Array r' ix a -> (a -> IO b) -> IO (Array r ix b)
+ Data.Massiv.Array: forIO_ :: Source r ix e => Array r ix e -> (e -> IO a) -> IO ()
+ Data.Massiv.Array: forM :: (Source r' ix a, Mutable r ix b, Monad m) => Array r' ix a -> (a -> m b) -> m (Array r ix b)
+ Data.Massiv.Array: forMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> Array r' ix a -> (a -> m b) -> m (Array r ix b)
+ Data.Massiv.Array: iforIO :: (Source r' ix a, Mutable r ix b) => Array r' ix a -> (ix -> a -> IO b) -> IO (Array r ix b)
+ Data.Massiv.Array: iforIO_ :: Source r ix a => Array r ix a -> (ix -> a -> IO b) -> IO ()
+ Data.Massiv.Array: iforM :: (Source r' ix a, Mutable r ix b, Monad m) => (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)
+ Data.Massiv.Array: iforMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)
+ Data.Massiv.Array: imapIO :: (Source r' ix a, Mutable r ix b) => (ix -> a -> IO b) -> Array r' ix a -> IO (Array r ix b)
+ Data.Massiv.Array: imapIO_ :: Source r ix e => (ix -> e -> IO a) -> Array r ix e -> IO ()
+ Data.Massiv.Array: imapM :: (Source r' ix a, Mutable r ix b, Monad m) => (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)
+ Data.Massiv.Array: imapMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)
+ Data.Massiv.Array: itraverseA :: (Source r' ix a, Mutable r ix b, Applicative f) => (ix -> a -> f b) -> Array r' ix a -> f (Array r ix b)
+ Data.Massiv.Array: itraverseAR :: (Source r' ix a, Mutable r ix b, Applicative f) => r -> (ix -> a -> f b) -> Array r' ix a -> f (Array r ix b)
+ Data.Massiv.Array: makeArrayA :: (Mutable r a b, Applicative f) => Comp -> a -> (a -> f b) -> f (Array r a b)
+ Data.Massiv.Array: makeArrayAR :: (Mutable r a b, Applicative f) => r -> Comp -> a -> (a -> f b) -> f (Array r a b)
+ Data.Massiv.Array: mapIO :: (Source r' ix a, Mutable r ix b) => (a -> IO b) -> Array r' ix a -> IO (Array r ix b)
+ Data.Massiv.Array: mapIO_ :: Source r b e => (e -> IO a) -> Array r b e -> IO ()
+ Data.Massiv.Array: mapM :: (Source r' ix a, Mutable r ix b, Monad m) => (a -> m b) -> Array r' ix a -> m (Array r ix b)
+ Data.Massiv.Array: mapMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> (a -> m b) -> Array r' ix a -> m (Array r ix b)
+ Data.Massiv.Array: traverseA :: (Source r' ix a, Mutable r ix b, Applicative f) => (a -> f b) -> Array r' ix a -> f (Array r ix b)
+ Data.Massiv.Array: traverseAR :: (Source r' ix a, Mutable r ix b, Applicative f) => r -> (a -> f b) -> Array r' ix a -> f (Array r ix b)
+ Data.Massiv.Array.Mutable: createArray :: (Mutable r ix e, PrimMonad m) => Comp -> ix -> (MArray (PrimState m) r ix e -> m a) -> m (a, Array r ix e)
+ Data.Massiv.Array.Mutable: createArrayST :: Mutable r ix e => Comp -> ix -> (forall s. MArray s r ix e -> ST s a) -> (a, Array r ix e)
+ Data.Massiv.Array.Mutable: createArrayST_ :: Mutable r ix e => Comp -> ix -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e
+ Data.Massiv.Array.Mutable: createArray_ :: (Mutable r ix e, PrimMonad m) => Comp -> ix -> (MArray (PrimState m) r ix e -> m a) -> m (Array r ix e)
+ Data.Massiv.Array.Mutable: generateArray :: (Mutable r ix e, PrimMonad m) => Comp -> ix -> (ix -> m e) -> m (Array r ix e)
+ Data.Massiv.Array.Mutable: generateArrayIO :: Mutable r ix e => Comp -> ix -> (ix -> IO e) -> IO (Array r ix e)
+ Data.Massiv.Array.Mutable: unfoldlPrim :: (Mutable r ix e, PrimMonad m) => Comp -> ix -> (a -> ix -> m (a, e)) -> a -> m (a, Array r ix e)
+ Data.Massiv.Array.Mutable: unfoldlPrim_ :: (Mutable r ix e, PrimMonad m) => Comp -> ix -> (a -> ix -> m (a, e)) -> a -> m (Array r ix e)
+ Data.Massiv.Core.Index: splitLinearlyWithM_ :: Monad m => Int -> (m () -> m a) -> Int -> (Int -> m b) -> (Int -> b -> m c) -> m a

Files

massiv.cabal view
@@ -1,5 +1,5 @@ name:                massiv-version:             0.2.5.0+version:             0.2.6.0 synopsis:            Massiv (Массив) is an Array Library. description:         Multi-dimensional Arrays with fusion, stencils and parallel computation. homepage:            https://github.com/lehins/massiv@@ -89,7 +89,7 @@                     , Data.Massiv.Array.Delayed.WindowedSpec                     , Data.Massiv.Array.ManifestSpec                     , Data.Massiv.Array.Manifest.VectorSpec-                    --, Data.Massiv.Array.MutableSpec+                    , Data.Massiv.Array.MutableSpec                     , Data.Massiv.Array.Ops.ConstructSpec                     , Data.Massiv.Array.Ops.FoldSpec                     , Data.Massiv.Array.Ops.SliceSpec
src/Data/Massiv/Array.hs view
@@ -152,6 +152,7 @@                                      , sum                                      , zip                                      )+ {- $folding  All folding is done in a row-major order.
src/Data/Massiv/Array/Manifest/Internal.hs view
@@ -46,7 +46,7 @@  import           Control.Exception                   (try) import           Control.Monad                       (unless)-import           Control.Monad.ST                    (RealWorld, runST)+import           Control.Monad.ST                    (runST) import           Data.Foldable                       (Foldable (..)) import           Data.Massiv.Array.Delayed.Internal import           Data.Massiv.Array.Ops.Fold.Internal as M@@ -59,7 +59,6 @@ import qualified Data.Vector                         as V import           GHC.Base                            hiding (ord) import           System.IO.Unsafe                    (unsafePerformIO)-  #if MIN_VERSION_primitive(0,6,2) import           Data.Primitive.Array                (sizeofArray,
src/Data/Massiv/Array/Manifest/List.hs view
@@ -82,9 +82,10 @@  -- | Same as `fromLists`, but will throw an error on irregular shaped lists. ----- __Note__: This function is almost the same (modulo customizable computation strategy) if you--- would turn on @{-# LANGUAGE OverloadedLists #-}@. For that reason you can also use--- `GHC.Exts.fromList`.+-- __Note__: This function is the same as if you would turn on @{-\# LANGUAGE OverloadedLists #-}@+-- extension. For that reason you can also use `GHC.Exts.fromList`.+--+-- prop> fromLists' Seq xs == fromList xs -- -- ===__Examples__ --
src/Data/Massiv/Array/Mutable.hs view
@@ -13,15 +13,8 @@ -- Portability : non-portable -- module Data.Massiv.Array.Mutable-  ( Mutable-  , MArray-  , msize-  , new-  , thaw-  , freeze-  , withMArray-  , withMArrayST-  , read+  ( -- * Element-wise mutation+    read   , read'   , write   , write'@@ -29,19 +22,31 @@   , modify'   , swap   , swap'-  -- * Computation+  -- ** Operate over `MArray`+  , Mutable+  , MArray+  , msize+  -- *** Convert+  , new+  , thaw+  , freeze+  -- *** Create+  , createArray_+  , createArray+  , createArrayST_+  , createArrayST+  -- *** Generate+  , generateArray+  , generateArrayIO+  -- *** Unfold+  , unfoldlPrim_+  , unfoldlPrim+  -- *** Modify+  , withMArray+  , withMArrayST+  -- ** Computation   , RealWorld   , computeInto-  -- * Generate (experimental)--  -- $generate-  {-, generateM-  , generateLinearM-  , mapM-  , imapM-  , forM-  , iforM-  , sequenceM -}   ) where  import           Prelude                             hiding (mapM, read)@@ -52,6 +57,7 @@ import           Data.Massiv.Array.Manifest.Internal import           Data.Massiv.Array.Unsafe import           Data.Massiv.Core.Common+import           Data.Massiv.Core.Scheduler  -- | Initialize a new mutable array. Negative size will result in an empty array. new :: (Mutable r ix e, PrimMonad m) => ix -> m (MArray (PrimState m) r ix e)@@ -69,6 +75,184 @@ {-# INLINE freeze #-}  +-- | Create a new array by supplying an action that will fill the new blank mutable array. Use+-- `createArray` if you'd like to keep the result of the filling function.+--+-- ====__Examples__+--+-- >>> createArray_ Seq (Ix1 2) (\ marr -> write marr 0 10 >> write marr 1 11) :: IO (Array P Ix1 Int)+-- (Array P Seq (2)+--   [ 10,11 ])+--+-- @since 0.2.6+--+createArray_ ::+     (Mutable r ix e, PrimMonad m)+  => Comp -- ^ Computation strategy to use after `MArray` gets frozen and onward.+  -> ix -- ^ Size of the newly created array+  -> (MArray (PrimState m) r ix e -> m a)+  -- ^ An action that should fill all elements of the brand new mutable array+  -> m (Array r ix e)+createArray_ comp sz action = fmap snd $ createArray comp sz action+{-# INLINE createArray_ #-}++-- | Just like `createArray_`, but together with `Array` it returns the result of the filling action.+--+-- @since 0.2.6+--+createArray ::+     (Mutable r ix e, PrimMonad m)+  => Comp -- ^ Computation strategy to use after `MArray` gets frozen and onward.+  -> ix -- ^ Size of the newly created array+  -> (MArray (PrimState m) r ix e -> m a)+  -- ^ An action that should fill all elements of the brand new mutable array+  -> m (a, Array r ix e)+createArray comp sz action = do+  marr <- new sz+  a <- action marr+  arr <- unsafeFreeze comp marr+  return (a, arr)+{-# INLINE createArray #-}++-- | Just like `createArray_`, but restricted to `ST`.+--+-- @since 0.2.6+--+createArrayST_ ::+     Mutable r ix e => Comp -> ix -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e+createArrayST_ comp sz action = runST $ createArray_ comp sz action+{-# INLINE createArrayST_ #-}+++-- | Just like `createArray`, but restricted to `ST`.+--+-- @since 0.2.6+--+createArrayST ::+     Mutable r ix e => Comp -> ix -> (forall s. MArray s r ix e -> ST s a) -> (a, Array r ix e)+createArrayST comp sz action = runST $ createArray comp sz action+{-# INLINE createArrayST #-}+++-- | Sequentially generate a pure array. Much like `makeArray` creates a pure array this function+-- will use `Mutable` interface to generate a pure `Array` in the end, except that computation+-- strategy is ignored. Element producing function no longer has to be pure but is a stateful+-- action, since it is restricted to `PrimMonad` and allows for sharing the state between+-- computation of each element, which could be arbitrary effects if that monad is `IO`.+--+-- @since 0.2.6+--+-- ====__Examples__+--+-- >>> import Data.IORef+-- >>> ref <- newIORef (0 :: Int)+-- >>> generateArray Seq (Ix1 6) (\ i -> modifyIORef' ref (+i) >> print i >> pure i) :: IO (Array U Ix1 Int)+-- 0+-- 1+-- 2+-- 3+-- 4+-- 5+-- (Array U Seq (6)+--   [ 0,1,2,3,4,5 ])+-- >>> readIORef ref+-- 15+--+generateArray ::+     (Mutable r ix e, PrimMonad m)+  => Comp -- ^ Computation strategy (ingored during generation)+  -> ix -- ^ Resulting size of the array+  -> (ix -> m e) -- ^ Element producing generator+  -> m (Array r ix e)+generateArray comp sz' gen = do+  let sz = liftIndex (max 0) sz'+  marr <- unsafeNew sz+  iterM_ zeroIndex (msize marr) (pureIndex 1) (<) $ \ix -> gen ix >>= write marr ix+  unsafeFreeze comp marr+{-# INLINE generateArray #-}+++-- | Just like `generateArray`, except this generator __will__ respect the supplied computation+-- strategy, and for that reason it is restricted to `IO`.+--+-- @since 0.2.6+generateArrayIO ::+     (Mutable r ix e)+  => Comp+  -> ix+  -> (ix -> IO e)+  -> IO (Array r ix e)+generateArrayIO comp sz' gen = do+  case comp of+    Seq -> generateArray comp sz' gen+    ParOn wids -> do+      let sz = liftIndex (max 0) sz'+      marr <- unsafeNew sz+      withScheduler_ wids $ \scheduler ->+        splitLinearlyWithM_+          (numWorkers scheduler)+          (scheduleWork scheduler)+          (totalElem sz)+          (gen . fromLinearIndex sz)+          (unsafeLinearWrite marr)+      unsafeFreeze comp marr+{-# INLINE generateArrayIO #-}++-- | Sequentially unfold an array from the left.+--+-- @since 0.2.6+--+-- ====__Examples__+--+-- Create an array with Fibonacci numbers while performing and `IO` action on the accumulator for+-- each element of the array.+--+-- >>> unfoldlPrim_ Seq  (Ix1 10) (\a@(f0, f1) _ -> let fn = f0 + f1 in print a >> return ((f1, fn), f0)) (0, 1) :: IO (Array P Ix1 Int)+-- (0,1)+-- (1,1)+-- (1,2)+-- (2,3)+-- (3,5)+-- (5,8)+-- (8,13)+-- (13,21)+-- (21,34)+-- (34,55)+-- (Array P Seq (10)+--   [ 0,1,1,2,3,5,8,13,21,34 ])+--+unfoldlPrim_ ::+     (Mutable r ix e, PrimMonad m)+  => Comp -- ^ Computation strategy (ignored during initial creation)+  -> ix -- ^ Size of the desired array+  -> (a -> ix -> m (a, e)) -- ^ Unfolding action+  -> a -- ^ Initial accumulator+  -> m (Array r ix e)+unfoldlPrim_ comp sz gen acc0 = fmap snd $ unfoldlPrim comp sz gen acc0+{-# INLINE unfoldlPrim_ #-}+++-- | Just like `unfoldlPrim`, but also returns the final value of the accumulator.+--+-- @since 0.2.6+--+unfoldlPrim ::+     (Mutable r ix e, PrimMonad m)+  => Comp -- ^ Computation strategy (ignored during initial creation)+  -> ix -- ^ Size of the desired array+  -> (a -> ix -> m (a, e)) -- ^ Unfolding action+  -> a -- ^ Initial accumulator+  -> m (a, Array r ix e)+unfoldlPrim comp sz gen acc0 =+  createArray comp sz $ \marr ->+    let sz' = msize marr+     in iterLinearM sz' 0 (totalElem sz') 1 (<) acc0 $ \i ix acc -> do+          (acc', e) <- gen acc ix+          unsafeLinearWrite marr i e+          return acc'+{-# INLINE unfoldlPrim #-}++ -- | Create a copy of a pure array, mutate it in place and return its frozen version. -- -- @since 0.2.2@@ -186,140 +370,3 @@       else ix1 {-# INLINE swap' #-} -{- Disabled until better times. See https://github.com/lehins/massiv/issues/24--unsafeLinearFillM :: (Mutable r ix e, Monad m) =>-                     MArray RealWorld r ix e -> (Int -> m e) -> WorldState -> m WorldState-unsafeLinearFillM ma f (State s_#) = go 0# s_#-  where-    !(I# k#) = totalElem (msize ma)-    go i# s# =-      case i# <# k# of-        0# -> return (State s#)-        _ -> do-          let i = I# i#-          res <- f i-          State s'# <- unsafeLinearWriteA ma i res (State s#)-          go (i# +# 1#) s'#-{-# INLINE unsafeLinearFillM #-}----- | /O(n)/ - Same as `generateM` but using a flat index.------ @since 0.1.1-generateLinearM :: (Monad m, Mutable r ix e) => Comp -> ix -> (Int -> m e) -> m (Array r ix e)-generateLinearM comp sz f = do-  (s, mba) <- unsafeNewA (liftIndex (max 0) sz) (State (noDuplicate# realWorld#))-  s' <- unsafeLinearFillM mba f s-  (_, ba) <- unsafeFreezeA comp mba s'-  return ba-{-# INLINE generateLinearM #-}---- | /O(n)/ - Generate an array monadically using it's mutable interface. Computation will be done-  -- sequentially, regardless of `Comp` argument.------ @since 0.1.1-generateM :: (Monad m, Mutable r ix e) => Comp -> ix -> (ix -> m e) -> m (Array r ix e)-generateM comp sz f = generateLinearM comp sz (f . fromLinearIndex sz)-{-# INLINE generateM #-}----- | /O(n)/ - Map an index aware monadic action over an Array. This operation will force computation--- sequentially and will result in a manifest Array.------ @since 0.1.1-imapM-  :: (Monad m, Source r ix e, Mutable r' ix e') =>-     r' -> (ix -> e -> m e') -> Array r ix e -> m (Array r' ix e')-imapM _ f arr =-  generateLinearM (getComp arr) sz (\ !i -> f (fromLinearIndex sz i) (unsafeLinearIndex arr i))-  where-    !sz = size arr-{-# INLINE imapM #-}---- | /O(n)/ - Map a monadic action over an Array. This operation will force computation sequentially--- and will result in a manifest Array.------ @since 0.1.1------ ====__Examples__------ >>> mapM P (\i -> Just (i*i)) $ range Seq 0 5--- Just (Array P Seq (5)---   [ 0,1,4,9,16 ])----mapM-  :: (Monad m, Source r ix e, Mutable r' ix e') =>-     r' -> (e -> m e') -> Array r ix e -> m (Array r' ix e')-mapM r f = imapM r (const f)-{-# INLINE mapM #-}----- | /O(n)/ - Same as `mapM`, but with its arguments flipped.------ @since 0.1.1-forM ::-     (Monad m, Source r ix e, Mutable r' ix e')-  => r'-  -> Array r ix e-  -> (e -> m e')-  -> m (Array r' ix e')-forM r = flip (mapM r)-{-# INLINE forM #-}----- | /O(n)/ - Same as `imapM`, but with its arguments flipped.------ @since 0.1.1-iforM :: (Monad m, Source r ix e, Mutable r' ix e') =>-         r' -> Array r ix e -> (ix -> e -> m e') -> m (Array r' ix e')-iforM r = flip (imapM r)-{-# INLINE iforM #-}----- | /O(n)/ - Sequence monadic actions in a source Array. This operation will force the computation--- sequentially and will result in a manifest Array.------ @since 0.1.1-sequenceM-  :: (Monad m, Source r ix (m e), Mutable r' ix e) =>-     r' -> Array r ix (m e) -> m (Array r' ix e)-sequenceM r = mapM r id-{-# INLINE sequenceM #-}--}--{- $generate--Functions in this section has been removed until better times due to a known bug https://github.com/lehins/massiv/issues/24---}--{- Disabled until better times--Functions in this section can monadically generate manifest arrays using their associated mutable-interface. Due to the sequential nature of monads generation is done also sequentially regardless of-supplied computation strategy. All of functions here are very much experimental, so please-<https://github.com/lehins/massiv/issues/new report an issue> if you see something not working-properly.--Here is a very imperative like for loop that creates an array while performing a side effect for-each newly created element:--@-printSquare :: Int -> IO (Array P Ix1 Int)-printSquare n = forM P (range Seq 0 n) $ \i -> do-  let e = i*i-  putStrLn $ "Element at index: " ++ show i ++ " = " ++ show e ++ ";"-  return e-@-->>> printSquare 5-Element at index: 0 = 0;-Element at index: 1 = 1;-Element at index: 2 = 4;-Element at index: 3 = 9;-Element at index: 4 = 16;-(Array P Seq (5)-  [ 0,1,4,9,16 ])---}
src/Data/Massiv/Array/Ops/Construct.hs view
@@ -1,7 +1,11 @@ {-# LANGUAGE BangPatterns          #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE ExplicitForAll        #-} {-# LANGUAGE FlexibleContexts      #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-} {-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE TypeOperators         #-} -- | -- Module      : Data.Massiv.Array.Ops.Construct -- Copyright   : (c) Alexey Kuleshevich 2018@@ -11,18 +15,29 @@ -- Portability : non-portable -- module Data.Massiv.Array.Ops.Construct-  ( makeArray+  ( -- ** From a function+    makeArray   , makeArrayR   , makeVectorR   , singleton+    -- *** Applicative+  , makeArrayA+  , makeArrayAR+    -- ** Enumeration   , range   , rangeStep   , enumFromN   , enumFromStepN+    -- ** Expansion+  , expandWithin+  , expandWithin'+  , expandOuter+  , expandInner   ) where  import           Data.Massiv.Array.Delayed.Internal import           Data.Massiv.Core.Common+import           Data.Massiv.Array.Ops.Map          as A import           Prelude                            as P  @@ -51,7 +66,23 @@ makeVectorR _ = makeArray {-# INLINE makeVectorR #-} +-- | Similar to `makeArray`, but construct the array sequentially using an `Applicative` interface+-- disregarding the supplied `Comp`.+--+-- @since 0.2.6+--+makeArrayA :: (Mutable r a b, Applicative f) => Comp -> a -> (a -> f b) -> f (Array r a b)+makeArrayA comp sz f = traverseA f $ makeArrayR D comp sz id+{-# INLINE makeArrayA #-} +-- | Same as `makeArrayA`, but with ability to supply result array representation.+--+-- @since 0.2.6+--+makeArrayAR :: (Mutable r a b, Applicative f) => r -> Comp -> a -> (a -> f b) -> f (Array r a b)+makeArrayAR _ = makeArrayA+{-# INLINE makeArrayAR #-}+ -- | Create a vector with a range of @Int@s incremented by 1. -- @range k0 k1 == rangeStep k0 k1 1@ --@@ -120,3 +151,115 @@ {-# INLINE enumFromStepN #-}  +-- | Function that expands an array to one with a higher dimension.+--+-- This is useful for constructing arrays where there is shared computation+-- between multiple cells.  The makeArray method of constructing arrays:+--+-- > makeArray :: Construct r ix e => Comp -> ix -> (ix -> e) -> Array r ix e+--+-- ...runs a function @ix -> e@ at every array index. This is inefficient if+-- there is a substantial amount of repeated computation that could be shared+-- while constructing elements on the same dimension. The expand functions make+-- this possible. First you construct an @Array r (Lower ix) a@ of one fewer+-- dimensions where @a@ is something like @`Array` r `Ix1` a@ or @`Array` r `Ix2` a@. Then+-- you use 'expandWithin' and a creation function @a -> Int -> b@ to create an+-- @`Array` `D` `Ix2` b@ or @`Array` `D` `Ix3` b@ respectfully.+--+-- @since 0.2.6+--+-- ====__Examples__+--+-- >>> a = makeArrayR U Seq (Ix1 6) (+10) -- Imagine (+10) is some expensive function+-- >>> a+-- (Array U Seq (6)+--   [ 10,11,12,13,14,15 ])+-- >>> expandWithin Dim1 5 (\ e j -> (j + 1) * 100 + e) a :: Array D Ix2 Int+-- (Array D Seq (6 :. 5)+--   [ [ 110,210,310,410,510 ]+--   , [ 111,211,311,411,511 ]+--   , [ 112,212,312,412,512 ]+--   , [ 113,213,313,413,513 ]+--   , [ 114,214,314,414,514 ]+--   , [ 115,215,315,415,515 ]+--   ])+-- >>> expandWithin Dim2 5 (\ e j -> (j + 1) * 100 + e) a :: Array D Ix2 Int+-- (Array D Seq (5 :. 6)+--   [ [ 110,111,112,113,114,115 ]+--   , [ 210,211,212,213,214,215 ]+--   , [ 310,311,312,313,314,315 ]+--   , [ 410,411,412,413,414,415 ]+--   , [ 510,511,512,513,514,515 ]+--   ])+--+expandWithin+  :: (IsIndexDimension ix n, Manifest r (Lower ix) a)+  => Dimension n+  -> Int+  -> (a -> Int -> b)+  -> Array r (Lower ix) a+  -> Array D ix b+expandWithin dim k f arr = do+  makeArray (getComp arr) sz $ \ix ->+    let (i, ixl) = pullOutDimension ix dim+     in f (unsafeIndex arr ixl) i+  where+    szl = size arr+    sz = insertDimension szl dim k+{-# INLINE expandWithin #-}++-- | Similar to `expandWithin`, except that dimension is specified at a value level, which means it+-- will throw an exception on an invalid dimension.+--+-- @since 0.2.6+expandWithin'+  :: (Index ix, Manifest r (Lower ix) a)+  => Dim+  -> Int+  -> (a -> Int -> b)+  -> Array r (Lower ix) a+  -> Array D ix b+expandWithin' dim k f arr =+  makeArray (getComp arr) sz $ \ix ->+    let (i, ixl) = pullOutDim' ix dim+     in f (unsafeIndex arr ixl) i+  where+    szl = size arr+    sz = insertDim' szl dim k+{-# INLINE expandWithin' #-}++-- | Similar to `expandWithin`, except it uses the outermost dimension.+--+-- @since 0.2.6+expandOuter+  :: (Index ix, Manifest r (Lower ix) a)+  => Int+  -> (a -> Int -> b)+  -> Array r (Lower ix) a+  -> Array D ix b+expandOuter k f arr =+  makeArray (getComp arr) sz $ \ix ->+    let (i, ixl) = unconsDim ix+     in f (unsafeIndex arr ixl) i+  where+    szl = size arr+    sz = consDim k szl+{-# INLINE expandOuter #-}++-- | Similar to `expandWithin`, except it uses the innermost dimension.+--+-- @since 0.2.6+expandInner+  :: (Index ix, Manifest r (Lower ix) a)+  => Int+  -> (a -> Int -> b)+  -> Array r (Lower ix) a+  -> Array D ix b+expandInner k f arr =+  makeArray (getComp arr) sz $ \ix ->+    let (ixl, i) = unsnocDim ix+     in f (unsafeIndex arr ixl) i+  where+    szl = size arr+    sz = snocDim szl k+{-# INLINE expandInner #-}
src/Data/Massiv/Array/Ops/Fold.hs view
@@ -347,13 +347,13 @@ {-# INLINE or #-}  --- | Determines whether all element of the array satisfy the predicate.+-- | /O(n)/ - Determines whether all element of the array satisfy the predicate. all :: Source r ix e =>        (e -> Bool) -> Array r ix e -> Bool all f = foldlInternal (\acc el -> acc && f el) True (&&) True {-# INLINE all #-} --- | Determines whether any element of the array satisfies the predicate.+-- | /O(n)/ - Determines whether any element of the array satisfies the predicate. any :: Source r ix e =>        (e -> Bool) -> Array r ix e -> Bool any f = foldlInternal (\acc el -> acc || f el) False (||) False
src/Data/Massiv/Array/Ops/Fold/Internal.hs view
@@ -341,7 +341,7 @@ {-# INLINE ifoldrP #-}  --- | This folding function breaks referencial transparency on some functions+-- | This folding function breaks referential transparency on some functions -- @f@, therefore it is kept here for internal use only. foldlInternal :: Source r ix e =>          (a -> e -> a) -> a -> (b -> a -> b) -> b -> Array r ix e -> b
src/Data/Massiv/Array/Ops/Map.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE BangPatterns          #-} {-# LANGUAGE FlexibleContexts      #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables   #-} -- | -- Module      : Data.Massiv.Array.Ops.Map -- Copyright   : (c) Alexey Kuleshevich 2018@@ -12,11 +13,34 @@ module Data.Massiv.Array.Ops.Map   ( map   , imap+  -- ** Traversing+  , traverseA+  , itraverseA+  , traverseAR+  , itraverseAR   -- ** Monadic+  -- *** Sequential+  , mapM+  , mapMR+  , forM+  , forMR+  , imapM+  , imapMR+  , iforM+  , iforMR   , mapM_   , forM_   , imapM_   , iforM_+  -- *** Parallelizable+  , mapIO+  , mapIO_+  , imapIO+  , imapIO_+  , forIO+  , forIO_+  , iforIO+  , iforIO_   , mapP_   , imapP_   -- ** Zipping@@ -32,15 +56,26 @@   ) where  -import           Control.Monad                      (void, when)+import           Control.Monad                       (void, when)+import           Control.Monad.ST                    (runST)+import           Data.Foldable                       (foldlM) import           Data.Massiv.Array.Delayed.Internal+import           Data.Massiv.Array.Mutable+import           Data.Massiv.Array.Ops.Fold.Internal (foldrFB) import           Data.Massiv.Core.Common import           Data.Massiv.Core.Scheduler-import           Data.Monoid                        ((<>))-import           Prelude                            hiding (map, mapM, mapM_,-                                                     unzip, unzip3, zip, zip3,-                                                     zipWith, zipWith3)+import           Data.Monoid                         ((<>))+import           GHC.Base                            (build)+import           Prelude                             hiding (map, mapM, mapM_,+                                                      traverse, unzip, unzip3,+                                                      zip, zip3, zipWith,+                                                      zipWith3)+import qualified Prelude                             as Prelude (traverse) +--------------------------------------------------------------------------------+-- map -------------------------------------------------------------------------+--------------------------------------------------------------------------------+ -- | Map a function over an array map :: Source r ix e' => (e' -> e) -> Array r ix e' -> Array D ix e map f = imap (const f)@@ -51,6 +86,10 @@ imap f !arr = DArray (getComp arr) (size arr) (\ !ix -> f ix (unsafeIndex arr ix)) {-# INLINE imap #-} +--------------------------------------------------------------------------------+-- zip -------------------------------------------------------------------------+--------------------------------------------------------------------------------+ -- | Zip two arrays zip :: (Source r1 ix e1, Source r2 ix e2)     => Array r1 ix e1 -> Array r2 ix e2 -> Array D ix (e1, e2)@@ -74,7 +113,9 @@ unzip3 arr = (map (\ (e, _, _) -> e) arr, map (\ (_, e, _) -> e) arr, map (\ (_, _, e) -> e) arr) {-# INLINE unzip3 #-} -+--------------------------------------------------------------------------------+-- zipWith ---------------------------------------------------------------------+--------------------------------------------------------------------------------  -- | Zip two arrays with a function. Resulting array will be an intersection of -- source arrays in case their dimensions do not match.@@ -115,8 +156,195 @@     f ix (unsafeIndex arr1 ix) (unsafeIndex arr2 ix) (unsafeIndex arr3 ix) {-# INLINE izipWith3 #-} +--------------------------------------------------------------------------------+-- traverse --------------------------------------------------------------------+-------------------------------------------------------------------------------- +-- | Traverse with an `Applicative` action over an array sequentially.+--+-- @since 0.2.6+--+traverseA ::+     (Source r' ix a, Mutable r ix b, Applicative f)+  => (a -> f b)+  -> Array r' ix a+  -> f (Array r ix b)+traverseA f arr = loadList <$> Prelude.traverse f (build (\c n -> foldrFB c n arr))+  where+    loadList xs =+      runST $ do+        marr <- unsafeNew (size arr)+        _ <- foldlM (\i e -> unsafeLinearWrite marr i e >> return (i + 1)) 0 xs+        unsafeFreeze (getComp arr) marr+    {-# INLINE loadList #-}+{-# INLINE traverseA #-} +-- | Traverse with an `Applicative` index aware action over an array sequentially.+--+-- @since 0.2.6+--+itraverseA ::+     (Source r' ix a, Mutable r ix b, Applicative f)+  => (ix -> a -> f b)+  -> Array r' ix a+  -> f (Array r ix b)+itraverseA f arr =+  fmap loadList $ Prelude.traverse (uncurry f) $ build (\c n -> foldrFB c n (zipWithIndex arr))+  where+    loadList xs =+      runST $ do+        marr <- unsafeNew (size arr)+        _ <- foldlM (\i e -> unsafeLinearWrite marr i e >> return (i + 1)) 0 xs+        unsafeFreeze (getComp arr) marr+    {-# INLINE loadList #-}+{-# INLINE itraverseA #-}++++-- | Same as `traverseA`, except with ability to specify representation.+--+-- @since 0.2.6+--+traverseAR ::+     (Source r' ix a, Mutable r ix b, Applicative f)+  => r+  -> (a -> f b)+  -> Array r' ix a+  -> f (Array r ix b)+traverseAR _ = traverseA+{-# INLINE traverseAR #-}++-- | Same as `itraverseA`, except with ability to specify representation.+--+-- @since 0.2.6+--+itraverseAR ::+     (Source r' ix a, Mutable r ix b, Applicative f)+  => r+  -> (ix -> a -> f b)+  -> Array r' ix a+  -> f (Array r ix b)+itraverseAR _ = itraverseA+{-# INLINE itraverseAR #-}++zipWithIndex :: forall r ix e . Source r ix e => Array r ix e -> Array D ix (ix, e)+zipWithIndex arr = zip (makeArray mempty (size arr) id :: Array D ix ix) arr+{-# INLINE zipWithIndex #-}++--------------------------------------------------------------------------------+-- mapM ------------------------------------------------------------------------+--------------------------------------------------------------------------------++-- | Map a monadic action over an array sequentially.+--+-- @since 0.2.6+--+mapM ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => (a -> m b)+  -> Array r' ix a+  -> m (Array r ix b)+mapM = traverseA+{-# INLINE mapM #-}+++-- | Same as `mapM`, except with ability to specify result representation.+--+-- @since 0.2.6+--+mapMR ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => r+  -> (a -> m b)+  -> Array r' ix a+  -> m (Array r ix b)+mapMR _ = traverseA+{-# INLINE mapMR #-}+++-- | Same as `mapM` except with arguments flipped.+--+-- @since 0.2.6+--+forM ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => Array r' ix a+  -> (a -> m b)+  -> m (Array r ix b)+forM = flip traverseA+{-# INLINE forM #-}+++-- | Same as `forM`, except with ability to specify result representation.+--+-- @since 0.2.6+--+forMR ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => r+  -> Array r' ix a+  -> (a -> m b)+  -> m (Array r ix b)+forMR _ = flip traverseA+{-# INLINE forMR #-}++++-- | Map a monadic action over an array sequentially.+--+-- @since 0.2.6+--+imapM ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => (ix -> a -> m b)+  -> Array r' ix a+  -> m (Array r ix b)+imapM = itraverseA+{-# INLINE imapM #-}+++-- | Same as `imapM`, except with ability to specify result representation.+--+-- @since 0.2.6+--+imapMR ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => r+  -> (ix -> a -> m b)+  -> Array r' ix a+  -> m (Array r ix b)+imapMR _ = itraverseA+{-# INLINE imapMR #-}++++-- | Same as `forM`, except map an index aware action.+--+-- @since 0.2.6+--+iforM ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => (ix -> a -> m b)+  -> Array r' ix a+  -> m (Array r ix b)+iforM = itraverseA+{-# INLINE iforM #-}+++-- | Same as `iforM`, except with ability to specify result representation.+--+-- @since 0.2.6+--+iforMR ::+     (Source r' ix a, Mutable r ix b, Monad m)+  => r+  -> (ix -> a -> m b)+  -> Array r' ix a+  -> m (Array r ix b)+iforMR _ = itraverseA+{-# INLINE iforMR #-}++ -- | Map a monadic function over an array sequentially, while discarding the result. -- -- ==== __Examples__@@ -157,11 +385,87 @@ {-# INLINE iforM_ #-}  +-- | Map an `IO` action over an `Array`. Underlying computation strategy is respected and will be+-- parallelized when requested. Unfortunately no fusion is possible and new array will be create+-- upon each call.+--+-- @since 0.2.6+mapIO ::+     (Source r' ix a, Mutable r ix b) => (a -> IO b) -> Array r' ix a -> IO (Array r ix b)+mapIO action = imapIO (const action)+{-# INLINE mapIO #-} +-- | Similar to `mapIO`, but ignores the result of mapping action and does not create a resulting+-- array, therefore it is faster. Use this instead of `mapIO` when result is irrelevant.+--+-- @since 0.2.6+mapIO_ :: Source r b e => (e -> IO a) -> Array r b e -> IO ()+mapIO_ action = imapIO_ (const action)+{-# INLINE mapIO_ #-}++-- | Same as `mapIO_`, but map an index aware action instead.+--+-- @since 0.2.6+imapIO_ :: Source r ix e => (ix -> e -> IO a) -> Array r ix e -> IO ()+imapIO_ action arr =+  case getComp arr of+    Seq -> imapM_ action arr+    ParOn wids -> do+      let sz = size arr+      withScheduler_ wids $ \scheduler ->+        splitLinearlyWith_+          (numWorkers scheduler)+          (scheduleWork scheduler)+          (totalElem sz)+          (unsafeLinearIndex arr)+          (\i -> void . action (fromLinearIndex sz i))+{-# INLINE imapIO_ #-}+++-- | Same as `mapIO` but map an index aware action instead.+--+-- @since 0.2.6+imapIO ::+     (Source r' ix a, Mutable r ix b) => (ix -> a -> IO b) -> Array r' ix a -> IO (Array r ix b)+imapIO action arr = generateArrayIO (getComp arr) (size arr) $ \ix -> action ix (unsafeIndex arr ix)+{-# INLINE imapIO #-}++-- | Same as `mapIO` but with arguments flipped.+--+-- @since 0.2.6+forIO ::+     (Source r' ix a, Mutable r ix b) => Array r' ix a -> (a -> IO b) -> IO (Array r ix b)+forIO = flip mapIO+{-# INLINE forIO #-}++-- | Same as `mapIO_` but with arguments flipped.+--+-- @since 0.2.6+forIO_ :: Source r ix e => Array r ix e -> (e -> IO a) -> IO ()+forIO_ = flip mapIO_+{-# INLINE forIO_ #-}++-- | Same as `imapIO` but with arguments flipped.+--+-- @since 0.2.6+iforIO ::+     (Source r' ix a, Mutable r ix b) => Array r' ix a -> (ix -> a -> IO b) -> IO (Array r ix b)+iforIO = flip imapIO+{-# INLINE iforIO #-}++-- | Same as `imapIO_` but with arguments flipped.+--+-- @since 0.2.6+iforIO_ :: Source r ix a => Array r ix a -> (ix -> a -> IO b) -> IO ()+iforIO_ = flip imapIO_+{-# INLINE iforIO_ #-}++ -- | Map an IO action, over an array in parallel, while discarding the result. mapP_ :: Source r ix a => (a -> IO b) -> Array r ix a -> IO () mapP_ f = imapP_ (const f) {-# INLINE mapP_ #-}+{-# DEPRECATED mapP_ "In favor of 'mapIO_'" #-}   -- | Map an index aware IO action, over an array in parallel, while@@ -183,3 +487,4 @@       iterLinearM_ sz slackStart totalLength 1 (<) $ \ !i ix -> do         void $ f ix (unsafeLinearIndex arr i) {-# INLINE imapP_ #-}+{-# DEPRECATED imapP_ "In favor of 'imapIO_'" #-}
src/Data/Massiv/Core/Index.hs view
@@ -178,18 +178,20 @@ -- | To be deprecated in favor of `setDim'`. setIndex' :: Index ix => ix -> Dim -> Int -> ix setIndex' ix dim i =-  case setIndex ix dim i of+  case setDim ix dim i of     Just ix' -> ix'     Nothing  -> errorDim "setIndex'" dim {-# INLINE [1] setIndex' #-}+{-# DEPRECATED setIndex' "In favor of `setDim'`" #-}  -- | To be deprecated in favor of `getDim'`. getIndex' :: Index ix => ix -> Dim -> Int getIndex' ix dim =-  case getIndex ix dim of+  case getDim ix dim of     Just ix' -> ix'     Nothing  -> errorDim "getIndex'" dim {-# INLINE [1] getIndex' #-}+{-# DEPRECATED getIndex' "In favor of `getDim'`" #-}  dropDim' :: Index ix => ix -> Dim -> Lower ix dropDim' ix dim =
src/Data/Massiv/Core/Index/Class.hs view
@@ -115,13 +115,11 @@   setDim = setIndex   {-# INLINE [1] setDim #-} -  -- TODO: depricate   -- | Extract the value index has at specified dimension. To be deprecated.   getIndex :: ix -> Dim -> Maybe Int   getIndex = getDim   {-# INLINE [1] getIndex #-} -  -- TODO: depricate   -- | Set the value for an index at specified dimension. To be deprecated.   setIndex :: ix -> Dim -> Int -> Maybe ix   setIndex = setDim@@ -249,6 +247,8 @@       !(inc, incIxL) = unconsDim incIx   {-# INLINE iterM_ #-} +{-# DEPRECATED getIndex "In favor of 'getDim'" #-}+{-# DEPRECATED setIndex "In favor of 'setDim'" #-}  instance Index Ix1T where   type Dimensions Ix1T = 1
src/Data/Massiv/Core/Index/Stride.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE PatternSynonyms            #-}  #if __GLASGOW_HASKELL__ >= 800+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} #else {-# LANGUAGE GADTs                      #-}@@ -56,6 +57,7 @@  #if __GLASGOW_HASKELL__ >= 800 newtype Stride ix = SafeStride ix deriving (Eq, Ord, NFData)+{-# COMPLETE Stride #-} #else -- There is an issue in GHC 7.10 which prevents from placing `Index` constraint on a pattern. data Stride ix where@@ -68,15 +70,16 @@ #endif  -instance Index ix => Show (Stride ix) where-  show (SafeStride ix) = "Stride (" ++ show ix ++ ")"-- -- | A safe bidirectional pattern synonym for `Stride` construction that will make sure stride -- elements are always positive. pattern Stride :: Index ix => ix -> Stride ix pattern Stride ix <- SafeStride ix where         Stride ix = SafeStride (liftIndex (max 1) ix)+++instance Index ix => Show (Stride ix) where+  show (SafeStride ix) = "Stride (" ++ show ix ++ ")"+  -- | Just a helper function for unwrapping `Stride`. unStride :: Stride ix -> ix
src/Data/Massiv/Core/Iterator.hs view
@@ -14,6 +14,7 @@   , loopDeepM   , splitLinearly   , splitLinearlyWith_+  , splitLinearlyWithM_   ) where  @@ -72,9 +73,19 @@   splitLinearlyWith_ :: Monad m => Int -> (m () -> m a) -> Int -> (Int -> b) -> (Int -> b -> m ()) -> m a-splitLinearlyWith_ numChunks with totalLength index write =+splitLinearlyWith_ numChunks with totalLength index =+  splitLinearlyWithM_ numChunks with totalLength (pure . index)+{-# INLINE splitLinearlyWith_ #-}+++-- | Interator tha can be used to split computation jobs+--+-- @since 0.2.6.0+splitLinearlyWithM_ ::+     Monad m => Int -> (m () -> m a) -> Int -> (Int -> m b) -> (Int -> b -> m c) -> m a+splitLinearlyWithM_ numChunks with totalLength make write =   splitLinearly numChunks totalLength  $ \chunkLength slackStart -> do     loopM_ 0 (< slackStart) (+ chunkLength) $ \ !start ->-      with $ loopM_ start (< (start + chunkLength)) (+ 1) $ \ !k -> write k (index k)-    with $ loopM_ slackStart (< totalLength) (+ 1) $ \ !k -> write k (index k)-{-# INLINE splitLinearlyWith_ #-}+      with $ loopM_ start (< (start + chunkLength)) (+ 1) $ \ !k -> make k >>= write k+    with $ loopM_ slackStart (< totalLength) (+ 1) $ \ !k -> make k >>= write k+{-# INLINE splitLinearlyWithM_ #-}
+ tests/Data/Massiv/Array/MutableSpec.hs view
@@ -0,0 +1,83 @@+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MonoLocalBinds        #-}+{-# LANGUAGE MultiParamTypeClasses #-}+module Data.Massiv.Array.MutableSpec (spec) where++import           Control.Monad.ST+import           Data.Functor.Identity+import           Data.Massiv.CoreArbitrary as A+import           Data.Proxy+import           Test.Hspec+import           Test.QuickCheck+import           Test.QuickCheck.Monadic+import           Test.QuickCheck.Function++prop_MapMapM :: (Show (Array r ix Int), Eq (Array r ix Int), Mutable r ix Int) =>+                r -> Proxy ix -> Fun Int Int -> ArrTiny D ix Int -> Property+prop_MapMapM r _ f (ArrTiny arr) =+  computeAs r (A.map (apply f) arr) === runIdentity (A.mapMR r (return . apply f) arr)++prop_iMapiMapM :: (Show (Array r ix Int), Eq (Array r ix Int), Mutable r ix Int) =>+                r -> Proxy ix -> Fun (ix, Int) Int -> ArrTiny D ix Int -> Property+prop_iMapiMapM r _ f (ArrTiny arr) =+  computeAs r (A.imap (curry (apply f)) arr) ===+  runIdentity (A.imapMR r (\ix e -> return $ apply f (ix, e)) arr)+++prop_generateMakeST :: (Show (Array r ix Int), Eq (Array r ix Int), Mutable r ix Int) =>+                             r -> Proxy ix -> Arr r ix Int -> Property+prop_generateMakeST _ _ (Arr arr) =+  arr === runST (generateArray (getComp arr) (size arr) (return . evaluateAt arr))++prop_generateMakeIO :: (Show (Array r ix Int), Eq (Array r ix Int), Mutable r ix Int) =>+                             r -> Proxy ix -> Arr r ix Int -> Property+prop_generateMakeIO _ _ (Arr arr) = monadicIO $ do+  arr' <- run $ generateArray (getComp arr) (size arr) (return . evaluateAt arr)+  return (arr === arr')++mutableSpec ::+     ( Show r+     , Show (Array r Ix3 Int)+     , Show (Array r Ix1 Int)+     , Show (Array r Ix2 Int)+     , Eq (Array r Ix3 Int)+     , Eq (Array r Ix1 Int)+     , Eq (Array r Ix2 Int)+     , Mutable r Ix3 Int+     , Mutable r Ix1 Int+     , Mutable r Ix2 Int+     )+  => r+  -> SpecWith ()+mutableSpec r = do+  describe (show r) $ do+    describe "map == mapM" $ do+      it "Ix1" $ property $ prop_MapMapM r (Proxy :: Proxy Ix1)+      it "Ix2" $ property $ prop_MapMapM r (Proxy :: Proxy Ix2)+      it "Ix3" $ property $ prop_MapMapM r (Proxy :: Proxy Ix3)+    describe "imap == imapM" $ do+      it "Ix1" $ property $ prop_iMapiMapM r (Proxy :: Proxy Ix1)+      it "Ix2T" $ property $ prop_iMapiMapM r (Proxy :: Proxy Ix2)+      it "Ix3T" $ property $ prop_iMapiMapM r (Proxy :: Proxy Ix3)+    describe "makeArray == generateArrayST" $ do+      it "Ix1" $ property $ prop_generateMakeST r (Proxy :: Proxy Ix1)+      it "Ix2" $ property $ prop_generateMakeST r (Proxy :: Proxy Ix2)+      it "Ix3" $ property $ prop_generateMakeST r (Proxy :: Proxy Ix3)+    describe "makeArray == generateArrayIO" $ do+      it "Ix1" $ property $ prop_generateMakeIO r (Proxy :: Proxy Ix1)+      it "Ix2" $ property $ prop_generateMakeIO r (Proxy :: Proxy Ix2)+      it "Ix3" $ property $ prop_generateMakeIO r (Proxy :: Proxy Ix3)+++generateSpec :: Spec+generateSpec = do+  mutableSpec P+  mutableSpec S+  mutableSpec U+  mutableSpec B+  mutableSpec N+++spec :: Spec+spec = describe "GenerateM" generateSpec
tests/Data/Massiv/Array/Ops/ConstructSpec.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE GADTs            #-}-module Data.Massiv.Array.Ops.ConstructSpec (spec) where+module Data.Massiv.Array.Ops.ConstructSpec where -import           Data.Massiv.CoreArbitrary as A+import           Data.Massiv.Array                 as A+import           Data.Massiv.CoreArbitrary         as A import           Data.Proxy import qualified GHC.Exts                   as GHC (IsList (..)) import           Prelude                    as P@@ -91,9 +92,29 @@   it "toFromListIsList" $ property (prop_toFromListIsList (Proxy :: Proxy Ix3))   it "excFromToListIx3" $ property prop_excFromToListIx3 +mkIntermediate :: Int -> Array U Ix1 Int+mkIntermediate t = A.fromList Seq [t + 50, t + 75] +initArr :: Array N Ix1 (Array U Ix1 Int)+initArr = makeArray Seq 3 (\ x -> mkIntermediate x)++initArr2 :: Array N Ix2 (Array U Ix1 Int)+initArr2 = makeArray Seq (2 :. 2) (\ (x :. y) -> mkIntermediate (x+y))++specExpand :: Spec+specExpand = do+  it "expandOuter" $ compute (expandOuter 2 A.index' initArr :: Array D Ix2 Int) `shouldBe`+    resize' (2 :. 3) (fromList Seq [50, 51, 52, 75, 76, 77] :: Array U Ix1 Int)+  it "expandInner" $ compute (expandInner 2 A.index' initArr :: Array D Ix2 Int) `shouldBe`+    resize' (3 :. 2) (fromList Seq [50, 75, 51, 76, 52, 77] :: Array U Ix1 Int)+  it "expandwithin" $ compute (expandWithin Dim1 2 A.index' initArr2 :: Array D Ix3 Int) `shouldBe`+    resize' (2 :> 2 :. 2) (fromList Seq [50, 75, 51, 76, 51, 76, 52, 77] :: Array U Ix1 Int)+  it "expandwithin'" $ compute (expandWithin' 1 2 A.index' initArr2 :: Array D Ix3 Int) `shouldBe`+    resize' (2 :> 2 :. 2) (fromList Seq [50, 75, 51, 76, 51, 76, 52, 77] :: Array U Ix1 Int)+ spec :: Spec spec = do   describe "Ix1" specIx1   describe "Ix2" specIx2   describe "Ix3" specIx3+  describe "Expand" specExpand
tests/Data/Massiv/Array/Ops/TransformSpec.hs view
@@ -4,7 +4,6 @@ module Data.Massiv.Array.Ops.TransformSpec (spec) where  import           Data.Massiv.CoreArbitrary as A-import           Data.Maybe                (fromJust) import           Data.Typeable             (Typeable) import           Test.Hspec import           Test.QuickCheck@@ -15,7 +14,7 @@   => proxy (r, ix, e) -> DimIx ix -> ArrIx r ix e -> Bool prop_ExtractAppend _ (DimIx dim) (ArrIx arr ix) =   maybe False ((delay arr ==) . uncurry (append' dim)) $-  A.splitAt dim (fromJust (getIndex ix dim)) arr+  A.splitAt dim (getDim' ix dim) arr   prop_transposeOuterInner :: Arr D Ix2 Int -> Property
tests/Data/Massiv/Array/StencilSpec.hs view
@@ -47,8 +47,8 @@     ix' =       liftIndex (* signum s) $       fromJust $ do-        i <- getIndex sz r-        setIndex zeroIndex r i+        i <- getDim sz r+        setDim zeroIndex r i   stencilSpec :: Spec
tests/Data/Massiv/Core/IndexSpec.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE GADTs               #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators       #-}+{-# LANGUAGE CPP                 #-} module Data.Massiv.Core.IndexSpec (Sz(..), SzZ(..), SzIx(..), DimIx(..), spec) where  import           Control.Monad@@ -10,6 +11,9 @@ import           Data.Functor.Identity import           Test.Hspec import           Test.QuickCheck+#if !MIN_VERSION_QuickCheck(2,10,0)+import           Test.QuickCheck.Function+#endif  -- | Size that will result in a non-empty array newtype Sz ix = Sz ix deriving Show@@ -98,6 +102,19 @@  instance CoArbitrary Ix5 where   coarbitrary (i :> ix) = coarbitrary i . coarbitrary ix++instance Function Ix2 where+  function = functionMap fromIx2 toIx2++instance Function Ix3 where+  function = functionMap fromIx3 toIx3++instance Function Ix4 where+  function = functionMap fromIx4 toIx4++instance Function Ix5 where+  function = functionMap fromIx5 toIx5+   -- instance Arbitrary Ix2 where
tests/Spec.hs view
@@ -4,7 +4,7 @@ import           Data.Massiv.Array.DelayedSpec          as Delayed import           Data.Massiv.Array.Manifest.VectorSpec  as Vector import           Data.Massiv.Array.ManifestSpec         as Manifest---import           Data.Massiv.Array.MutableSpec         as Mutable+import           Data.Massiv.Array.MutableSpec         as Mutable import           Data.Massiv.Array.Ops.ConstructSpec    as Construct import           Data.Massiv.Array.Ops.FoldSpec         as Fold import           Data.Massiv.Array.Ops.MapSpec          as Map@@ -35,6 +35,6 @@     describe "Delayed" $ Delayed.spec     describe "Windowed" $ Windowed.spec     describe "Manifest" $ Manifest.spec-    --describe "Mutable" $ Mutable.spec+    describe "Mutable" $ Mutable.spec     describe "Stencil" $ Stencil.spec     describe "Vector" $ Vector.spec