packages feed

massiv 0.1.5.0 → 0.1.6.0

raw patch · 7 files changed

+122/−19 lines, 7 filesdep +semigroupsPVP ok

version bump matches the API change (PVP)

Dependencies added: semigroups

API changes (from Hackage documentation)

+ Data.Massiv.Array: foldSemi :: (Source r ix e, Semigroup m) => (e -> m) -> m -> Array r ix e -> m
+ Data.Massiv.Array.Unsafe: forStencilUnsafe :: (Source r ix e, Manifest r ix e) => Array r ix e -> ix -> ix -> ((ix -> Maybe e) -> a) -> Array DW ix a

Files

massiv.cabal view
@@ -1,5 +1,5 @@ name:                massiv-version:             0.1.5.0+version:             0.1.6.0 synopsis:            Massiv (Массив) is an Array Library. description:         Multi-dimensional Arrays with fusion, stencils and parallel computation. homepage:            https://github.com/lehins/massiv@@ -57,6 +57,10 @@                      , ghc-prim                      , primitive                      , vector++  if impl(ghc < 8.0)+    build-depends: semigroups+   default-language:    Haskell2010   ghc-options:         -Wall 
src/Data/Massiv/Array/Ops/Fold.hs view
@@ -18,6 +18,7 @@      fold   , foldMono+  , foldSemi   , minimum   , maximum   , sum@@ -71,7 +72,7 @@ import           Data.Massiv.Array.Ops.Map           (map) import           Data.Massiv.Core import           Data.Massiv.Core.Common-import           Data.Monoid+import           Data.Semigroup import           Prelude                             hiding (all, and, any,                                                       foldl, foldr, map,                                                       maximum, minimum, or,@@ -85,10 +86,23 @@   => (e -> m) -- ^ Convert each element of an array to an appropriate `Monoid`.   -> Array r ix e -- ^ Source array   -> m-foldMono f = foldl (<>) mempty (<>) mempty . map f+foldMono f = foldl mappend mempty mappend mempty . map f {-# INLINE foldMono #-}  +-- | /O(n)/ - Semigroup fold over an array.+--+-- @since 0.1.6+foldSemi ::+     (Source r ix e, Semigroup m)+  => (e -> m) -- ^ Convert each element of an array to an appropriate `Semigroup`.+  -> m -- ^ Initial element that must be neutral to the (`<>`) function.+  -> Array r ix e -- ^ Source array+  -> m+foldSemi f m = foldl (<>) m (<>) m . map f+{-# INLINE foldSemi #-}++ -- | /O(n)/ - Compute maximum of all elements. maximum :: (Source r ix e, Ord e) =>            Array r ix e -> e@@ -105,7 +119,7 @@ minimum = \arr ->   if isEmpty arr     then error "Data.Massiv.Array.minimum - empty"-    else fold max (evaluateAt arr zeroIndex) arr+    else fold min (evaluateAt arr zeroIndex) arr {-# INLINE minimum #-}  
src/Data/Massiv/Array/Stencil/Internal.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns          #-}+{-# LANGUAGE CPP                   #-} {-# LANGUAGE FlexibleContexts      #-} {-# LANGUAGE FlexibleInstances     #-} {-# LANGUAGE MultiParamTypeClasses #-}@@ -16,9 +17,14 @@  import           Control.Applicative import           Control.DeepSeq-import           Data.Massiv.Core.Common+import           Data.Default.Class                 (Default (def)) import           Data.Massiv.Array.Delayed.Internal-import           Data.Default.Class                (Default (def))+import           Data.Massiv.Array.Delayed.Windowed+import           Data.Massiv.Core.Common+import           GHC.Exts                           (inline)+#if !MIN_VERSION_base(4,11,0)+import           Data.Semigroup+#endif  -- | Stencil is abstract description of how to handle elements in the neighborhood of every array -- cell in order to compute a value for the cells in the new array. Use `Data.Array.makeStencil` and@@ -38,7 +44,6 @@ -- it possible to manipulate the value, without having direct access to it. newtype Value e = Value { unValue :: e } deriving (Show, Eq, Ord, Bounded) - instance Functor Value where   fmap f (Value e) = Value (f e)   {-# INLINE fmap #-}@@ -49,6 +54,18 @@   (<*>) (Value f) (Value e) = Value (f e)   {-# INLINE (<*>) #-} +-- | @since 0.1.5+instance Semigroup a => Semigroup (Value a) where+  Value a <> Value b = Value (a <> b)+  {-# INLINE (<>) #-}++-- | @since 0.1.5+instance Monoid a => Monoid (Value a) where+  mempty = Value mempty+  {-# INLINE mempty #-}+  Value a `mappend` Value b = Value (a `mappend` b)+  {-# INLINE mappend #-}+ instance Num e => Num (Value e) where   (+) = liftA2 (+)   {-# INLINE (+) #-}@@ -222,3 +239,32 @@   in stencil (Value . safeStencilIndex valArr) sCenter `seq` s {-# INLINE validateStencil #-} ++-- | This is an unsafe version of the stencil computation. There are no bounds check further from+-- the border, so if you make sure you don't go outside the size of the stencil, you will be safe,+-- but this is not enforced.+forStencilUnsafe ::+     (Source r ix e, Manifest r ix e)+  => Array r ix e+  -> ix -- ^ Size of the stencil+  -> ix -- ^ Center of the stencil+  -> ((ix -> Maybe e) -> a)+  -- ^ Stencil function that receives a "get" function as it's argument that can+  -- retrieve values of cells in the source array with respect to the center of+  -- the stencil. Stencil function must return a value that will be assigned to+  -- the cell in the result array. Offset supplied to the "get" function+  -- cannot go outside the boundaries of the stencil, otherwise an error will be+  -- raised during stencil creation.+  -> Array DW ix a+forStencilUnsafe !arr !sSz !sCenter relStencil =+  DWArray+    (DArray (getComp arr) sz (stencil (index arr)))+    (Just sSz)+    sCenter+    (liftIndex2 (-) sz (liftIndex2 (-) sSz (pureIndex 1)))+    (stencil (Just . unsafeIndex arr))+  where+    stencil getVal !ix = (inline relStencil $ \ !ixD -> getVal (liftIndex2 (+) ix ixD))+    {-# INLINE stencil #-}+    !sz = size arr+{-# INLINE forStencilUnsafe #-}
src/Data/Massiv/Array/Unsafe.hs view
@@ -39,11 +39,14 @@   , unsafeLinearRead   , unsafeWrite   , unsafeLinearWrite+  -- * Stencil+  , forStencilUnsafe   ) where  import           Control.Monad.Primitive            (PrimMonad (..)) import           Control.Monad.ST                   (runST) import           Data.Massiv.Array.Delayed.Internal (D)+import           Data.Massiv.Array.Stencil.Internal import           Data.Massiv.Core.Common import           Data.Massiv.Core.Scheduler import           System.IO.Unsafe                   (unsafePerformIO)@@ -103,6 +106,8 @@   -- | Create an array in parallel using mutable interface+--+-- @since 0.1.5 unsafeGenerateArrayP :: Mutable r ix e => [Int] -> ix -> (ix -> e) -> Array r ix e unsafeGenerateArrayP wIds !sz f = unsafePerformIO $ do   marr <- unsafeNew sz
src/Data/Massiv/Core/Computation.hs view
@@ -15,16 +15,11 @@   ) where  import           Control.DeepSeq (NFData (..), deepseq)-#if MIN_VERSION_base(4,9,0) #if !MIN_VERSION_base(4,11,0)-import Data.Semigroup-#endif-instance Semigroup Comp where-  (<>) = joinComp+import           Data.Semigroup #endif  - -- | Computation type to use. data Comp   = Seq -- ^ Sequential computation@@ -58,6 +53,10 @@   {-# INLINE mempty #-}   mappend = joinComp   {-# INLINE mappend #-}++instance Semigroup Comp where+  (<>) = joinComp+  {-# INLINE (<>) #-}   joinComp :: Comp -> Comp -> Comp
tests/Data/Massiv/Array/Ops/FoldSpec.hs view
@@ -4,11 +4,14 @@ {-# LANGUAGE MultiParamTypeClasses #-} module Data.Massiv.Array.Ops.FoldSpec (spec) where -import           Data.Massiv.CoreArbitrary+import qualified Data.Foldable             as F+import           Data.Massiv.CoreArbitrary as A+import           Data.Semigroup import           Prelude                   hiding (map, product, sum) import qualified Prelude                   as P (length, sum) import           Test.Hspec import           Test.QuickCheck+import           Test.QuickCheck.Function import           Test.QuickCheck.Monadic  @@ -55,6 +58,20 @@     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 -> ArrTiny1 P ix Int -> Property+foldOpsProp _ f (ArrTiny1 arr) =+  (A.maximum arr === getMax (foldMono Max arr)) .&&.+  (A.minimum arr === getMin (foldSemi Min maxBound arr)) .&&.+  (A.sum arr === F.sum ls) .&&.+  (A.product (A.map ((+ 0.1) . (fromIntegral :: Int -> Double)) arr) ===+   getProduct (foldMono (Product . (+ 0.1) . fromIntegral) arr)) .&&.+  (A.all (apply f) arr === F.all (apply f) ls) .&&.+  (A.any (apply f) arr === F.any (apply f) ls) .&&.+  (A.or (A.map (apply f) arr) === F.or (fmap (apply f) ls)) .&&.+  (A.and (A.map (apply f) arr) === F.and (fmap (apply f) ls))+  where+    ls = toList arr+ spec :: Spec spec = do   specFold (Nothing :: Maybe Ix1) "Ix1"@@ -62,3 +79,7 @@   it "Nested Parallel Fold" $ property prop_NestedFoldP   it "FoldrOnP" $ property $ prop_FoldrOnP   it "FoldlOnP" $ property $ prop_FoldlOnP+  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)
tests/Data/Massiv/CoreArbitrary.hs view
@@ -7,8 +7,10 @@ module Data.Massiv.CoreArbitrary   ( Arr(..)   , ArrTiny(..)+  , ArrTiny1(..)   , ArrIx(..)   , ArrP(..)+  , ArrS(..)   , ArrIxP(..)   , Sz(..)   , SzIx(..)@@ -23,21 +25,23 @@  import           Control.DeepSeq            (NFData, deepseq) import           Control.Exception          (Exception, SomeException, catch)---import           Data.Massiv.Array.Ops.Construct import           Data.Massiv.Array import           Data.Massiv.Core.IndexSpec hiding (spec) import           Data.Typeable import           Test.QuickCheck import           Test.QuickCheck.Monadic -data Arr r ix e = Arr (Array r ix e)+newtype Arr r ix e = Arr {unArr :: Array r ix e} -data ArrTiny r ix e = ArrTiny (Array r ix e)+newtype ArrTiny r ix e = ArrTiny {unArrTiny :: Array r ix e} -data ArrS r ix e = ArrS (Array r ix e)+-- | Tiny but non-empty+newtype ArrTiny1 r ix e = ArrTiny1 {unArrTiny1 :: Array r ix e} -data ArrP r ix e = ArrP (Array r ix e)+newtype ArrS r ix e = ArrS {unArrS :: Array r ix e} +newtype ArrP r ix e = ArrP {unArrP :: Array r ix e}+ data ArrIx r ix e = ArrIx (Array r ix e) ix  data ArrIxS r ix e = ArrIxS (Array r ix e) ix@@ -46,6 +50,7 @@  deriving instance (Show (Array r ix e)) => Show (Arr r ix e) deriving instance (Show (Array r ix e)) => Show (ArrTiny r ix e)+deriving instance (Show (Array r ix e)) => Show (ArrTiny1 r ix e) deriving instance (Show (Array r ix e)) => Show (ArrS r ix e) deriving instance (Show (Array r ix e)) => Show (ArrP r ix e) deriving instance (Show (Array r ix e), Show ix) => Show (ArrIx r ix e)@@ -74,6 +79,15 @@     func <- arbitrary     comp <- oneof [pure Seq, pure Par]     return $ ArrTiny $ makeArray comp (liftIndex (`mod` 10) sz) func++-- | Arbitrary small and possibly empty array. Computation strategy can be either `Seq` or `Par`.+instance (CoArbitrary ix, Arbitrary ix, Typeable e, Construct r ix e, Arbitrary e) =>+         Arbitrary (ArrTiny1 r ix e) where+  arbitrary = do+    SzZ sz <- arbitrary+    func <- arbitrary+    comp <- oneof [pure Seq, pure Par]+    return $ ArrTiny1 $ makeArray comp (liftIndex (succ . (`mod` 10)) sz) func  -- | Arbitrary non-empty array. Computation strategy can be either `Seq` or `Par`. instance (CoArbitrary ix, Arbitrary ix, Typeable e, Construct r ix e, Arbitrary e) =>