packages feed

PrimitiveArray 0.1.1.2 → 0.2.0.0

raw patch · 7 files changed

+503/−136 lines, 7 filesdep −repaPVP ok

version bump matches the API change (PVP)

Dependencies removed: repa

API changes (from Hackage documentation)

- Data.PrimitiveArray: class (PrimMonad m, Shape sh) => PrimArrayOpsM sh elm m where { data family PrimArrayM sh elm m :: *; }
- Data.PrimitiveArray: unsafeFreezeM :: PrimArrayOpsM sh elm m => PrimArrayM sh elm m -> m (PrimArray sh elm)
- Data.PrimitiveArray: unsafeIndex :: PrimArrayOps sh elm => PrimArray sh elm -> sh -> elm
- Data.PrimitiveArray.Unboxed: instance (Read elm, Read sh, Unbox elm) => Read (PrimArray sh elm)
- Data.PrimitiveArray.Unboxed: instance (Show elm, Show sh, Unbox elm) => Show (PrimArray sh elm)
- Data.PrimitiveArray.Unboxed: instance (Unbox elm, Shape sh) => PrimArrayOpsM sh elm (ST s)
- Data.PrimitiveArray.Unboxed: instance (Unbox elm, Shape sh) => PrimArrayOpsM sh elm IO
- Data.PrimitiveArray.Unboxed: instance (Unbox elm, Shape sh, Show elm, Show sh) => PrimArrayOps sh elm
+ Data.Array.Repa.Index: (:.) :: tail -> head -> :. tail head
+ Data.Array.Repa.Index: Z :: Z
+ Data.Array.Repa.Index: data (:.) tail head
+ Data.Array.Repa.Index: data Z
+ Data.Array.Repa.Index: instance (Eq tail, Eq head) => Eq (tail :. head)
+ Data.Array.Repa.Index: instance (Ord tail, Ord head) => Ord (tail :. head)
+ Data.Array.Repa.Index: instance (Show tail, Show head) => Show (tail :. head)
+ Data.Array.Repa.Index: instance Eq Z
+ Data.Array.Repa.Index: instance Ord Z
+ Data.Array.Repa.Index: instance Shape Z
+ Data.Array.Repa.Index: instance Shape sh => Shape (sh :. Int)
+ Data.Array.Repa.Index: instance Show Z
+ Data.Array.Repa.Index: type DIM0 = Z
+ Data.Array.Repa.Index: type DIM1 = DIM0 :. Int
+ Data.Array.Repa.Index: type DIM2 = DIM1 :. Int
+ Data.Array.Repa.Index: type DIM3 = DIM2 :. Int
+ Data.Array.Repa.Index: type DIM4 = DIM3 :. Int
+ Data.Array.Repa.Index: type DIM5 = DIM4 :. Int
+ Data.Array.Repa.Shape: addDim :: Shape sh => sh -> sh -> sh
+ Data.Array.Repa.Shape: class Eq sh => Shape sh
+ Data.Array.Repa.Shape: deepSeq :: Shape sh => sh -> a -> a
+ Data.Array.Repa.Shape: fromIndex :: Shape sh => sh -> Int -> sh
+ Data.Array.Repa.Shape: inShape :: Shape sh => sh -> sh -> Bool
+ Data.Array.Repa.Shape: inShapeRange :: Shape sh => sh -> sh -> sh -> Bool
+ Data.Array.Repa.Shape: intersectDim :: Shape sh => sh -> sh -> sh
+ Data.Array.Repa.Shape: listOfShape :: Shape sh => sh -> [Int]
+ Data.Array.Repa.Shape: rank :: Shape sh => sh -> Int
+ Data.Array.Repa.Shape: shapeOfList :: Shape sh => [Int] -> sh
+ Data.Array.Repa.Shape: showShape :: Shape sh => sh -> String
+ Data.Array.Repa.Shape: size :: Shape sh => sh -> Int
+ Data.Array.Repa.Shape: sizeIsValid :: Shape sh => sh -> Bool
+ Data.Array.Repa.Shape: toIndex :: Shape sh => sh -> sh -> Int
+ Data.Array.Repa.Shape: unitDim :: Shape sh => sh
+ Data.Array.Repa.Shape: zeroDim :: Shape sh => sh
+ Data.ExtShape: class (Eq sh, Shape sh) => ExtShape sh
+ Data.ExtShape: instance ExtShape Z
+ Data.ExtShape: instance ExtShape sh => ExtShape (sh :. Int)
+ Data.ExtShape: rangeList :: ExtShape sh => sh -> sh -> [sh]
+ Data.ExtShape: subDim :: ExtShape sh => sh -> sh -> sh
+ Data.PrimitiveArray: class (Shape sh, ExtShape sh) => MPrimArrayOps marr sh elm
+ Data.PrimitiveArray: freeze :: (PrimArrayOps arr sh elm, PrimMonad m) => MutArray arr (PrimState m) sh elm -> m (arr sh elm)
+ Data.PrimitiveArray: fromList :: PrimArrayOps arr sh elm => sh -> sh -> [elm] -> arr sh elm
+ Data.PrimitiveArray: fromListM :: (MPrimArrayOps marr sh elm, PrimMonad m) => sh -> sh -> [elm] -> m (marr (PrimState m) sh elm)
+ Data.PrimitiveArray: index :: PrimArrayOps arr sh elm => arr sh elm -> sh -> elm
+ Data.PrimitiveArray: newM :: (MPrimArrayOps marr sh elm, PrimMonad m) => sh -> sh -> m (marr (PrimState m) sh elm)
+ Data.PrimitiveArray: newWithM :: (MPrimArrayOps marr sh elm, PrimMonad m) => sh -> sh -> elm -> m (marr (PrimState m) sh elm)
+ Data.PrimitiveArray: sliceEq :: (Eq elm, PrimArrayOps arr sh elm) => arr sh elm -> sh -> arr sh elm -> sh -> sh -> Bool
+ Data.PrimitiveArray: toList :: PrimArrayOps arr sh elm => arr sh elm -> [elm]
+ Data.PrimitiveArray.Unboxed.Zero: Arr0 :: !sh -> {-# UNPACK #-} !ByteArray -> Arr0 sh elm
+ Data.PrimitiveArray.Unboxed.Zero: MArr0 :: !sh -> {-# UNPACK #-} !MutableByteArray s -> MArr0 s sh elm
+ Data.PrimitiveArray.Unboxed.Zero: data Arr0 sh elm
+ Data.PrimitiveArray.Unboxed.Zero: data MArr0 s sh elm
+ Data.PrimitiveArray.Unboxed.Zero: instance (Shape sh, ExtShape sh, Prim elm) => MPrimArrayOps MArr0 sh elm
+ Data.PrimitiveArray.Unboxed.Zero: instance (Shape sh, ExtShape sh, Prim elm) => PrimArrayOps Arr0 sh elm
- Data.PrimitiveArray: (!) :: PrimArrayOps sh elm => PrimArray sh elm -> sh -> elm
+ Data.PrimitiveArray: (!) :: PrimArrayOps arr sh elm => arr sh elm -> sh -> elm
- Data.PrimitiveArray: assocs :: PrimArrayOps sh elm => PrimArray sh elm -> [(sh, elm)]
+ Data.PrimitiveArray: assocs :: PrimArrayOps arr sh elm => arr sh elm -> [(sh, elm)]
- Data.PrimitiveArray: bounds :: PrimArrayOps sh elm => PrimArray sh elm -> (sh, sh)
+ Data.PrimitiveArray: bounds :: PrimArrayOps arr sh elm => arr sh elm -> (sh, sh)
- Data.PrimitiveArray: boundsM :: PrimArrayOpsM sh elm m => PrimArrayM sh elm m -> (sh, sh)
+ Data.PrimitiveArray: boundsM :: MPrimArrayOps marr sh elm => marr s sh elm -> (sh, sh)
- Data.PrimitiveArray: class Shape sh => PrimArrayOps sh elm where { data family PrimArray sh elm :: *; }
+ Data.PrimitiveArray: class (Shape sh, ExtShape sh, MPrimArrayOps (MutArray arr) sh elm) => PrimArrayOps arr sh elm
- Data.PrimitiveArray: fromAssocs :: PrimArrayOps sh elm => sh -> sh -> elm -> [(sh, elm)] -> PrimArray sh elm
+ Data.PrimitiveArray: fromAssocs :: PrimArrayOps arr sh elm => sh -> sh -> elm -> [(sh, elm)] -> arr sh elm
- Data.PrimitiveArray: fromAssocsM :: PrimArrayOpsM sh elm m => sh -> sh -> elm -> [(sh, elm)] -> m (PrimArrayM sh elm m)
+ Data.PrimitiveArray: fromAssocsM :: (PrimMonad m, MPrimArrayOps marr sh elm) => sh -> sh -> elm -> [(sh, elm)] -> m (marr (PrimState m) sh elm)
- Data.PrimitiveArray: inBounds :: PrimArrayOps sh elm => PrimArray sh elm -> sh -> Bool
+ Data.PrimitiveArray: inBounds :: PrimArrayOps arr sh elm => arr sh elm -> sh -> Bool
- Data.PrimitiveArray: inBoundsM :: PrimArrayOpsM sh elm m => PrimArrayM sh elm m -> sh -> Bool
+ Data.PrimitiveArray: inBoundsM :: MPrimArrayOps marr sh elm => marr s sh elm -> sh -> Bool
- Data.PrimitiveArray: readM :: PrimArrayOpsM sh elm m => PrimArrayM sh elm m -> sh -> m elm
+ Data.PrimitiveArray: readM :: (MPrimArrayOps marr sh elm, PrimMonad m) => marr (PrimState m) sh elm -> sh -> m elm
- Data.PrimitiveArray: writeM :: PrimArrayOpsM sh elm m => PrimArrayM sh elm m -> sh -> elm -> m ()
+ Data.PrimitiveArray: writeM :: (MPrimArrayOps marr sh elm, PrimMonad m) => marr (PrimState m) sh elm -> sh -> elm -> m ()

Files

+ Data/Array/Repa/Index.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE TypeOperators, FlexibleInstances, ScopedTypeVariables #-}++-- | Index types.+module Data.Array.Repa.Index+	(+	-- * Index types+	  Z	(..)+	, (:.)	(..)++	-- * Common dimensions.+	, DIM0+	, DIM1+	, DIM2+	, DIM3+	, DIM4+	, DIM5)+where+import Data.Array.Repa.Shape+import GHC.Base 		(quotInt, remInt)++stage	= "Data.Array.Repa.Index"++-- | An index of dimension zero+data Z	= Z+	deriving (Show, Eq, Ord)++-- | Our index type, used for both shapes and indices.+infixl 3 :.+data tail :. head+	= tail :. head+	deriving (Show, Eq, Ord)++-- Common dimensions+type DIM0	= Z+type DIM1	= DIM0 :. Int+type DIM2	= DIM1 :. Int+type DIM3	= DIM2 :. Int+type DIM4	= DIM3 :. Int+type DIM5	= DIM4 :. Int+++-- Shape ------------------------------------------------------------------------------------------+instance Shape Z where+	{-# INLINE rank #-}+	rank _			= 0++	{-# INLINE zeroDim #-}+	zeroDim			= Z++	{-# INLINE unitDim #-}+	unitDim			= Z++	{-# INLINE intersectDim #-}+	intersectDim _ _	= Z++	{-# INLINE addDim #-}+	addDim _ _		= Z++	{-# INLINE size #-}+	size _			= 1++	{-# INLINE sizeIsValid #-}+	sizeIsValid _		= True+++	{-# INLINE toIndex #-}+	toIndex _ _		= 0++	{-# INLINE fromIndex #-}+	fromIndex _ _		= Z+++	{-# INLINE inShapeRange #-}+	inShapeRange Z Z Z	= True++	listOfShape _		= []+	shapeOfList []		= Z+	shapeOfList _		= error $ stage ++ ".fromList: non-empty list when converting to Z."++	{-# INLINE deepSeq #-}+	deepSeq Z x		= x+++instance Shape sh => Shape (sh :. Int) where+	{-# INLINE rank #-}+	rank   (sh  :. _)+		= rank sh + 1++	{-# INLINE zeroDim #-}+	zeroDim = zeroDim :. 0++	{-# INLINE unitDim #-}+	unitDim = unitDim :. 1++	{-# INLINE intersectDim #-}+	intersectDim (sh1 :. n1) (sh2 :. n2)+		= (intersectDim sh1 sh2 :. (min n1 n2))++	{-# INLINE addDim #-}+	addDim (sh1 :. n1) (sh2 :. n2)+		= addDim sh1 sh2 :. (n1 + n2)++	{-# INLINE size #-}+	size  (sh1 :. n)+		= size sh1 * n++	{-# INLINE sizeIsValid #-}+	sizeIsValid (sh1 :. n)+		| size sh1 > 0+		= n <= maxBound `div` size sh1++		| otherwise+		= False++	{-# INLINE toIndex #-}+	toIndex (sh1 :. sh2) (sh1' :. sh2')+		= toIndex sh1 sh1' * sh2 + sh2'++	{-# INLINE fromIndex #-}+	fromIndex (ds :. d) n+	 	= fromIndex ds (n `quotInt` d) :. r+		where+		-- If we assume that the index is in range, there is no point+		-- in computing the remainder for the highest dimension since+		-- n < d must hold. This saves one remInt per element access which+		-- is quite a big deal.+		r 	| rank ds == 0	= n+			| otherwise	= n `remInt` d++	{-# INLINE inShapeRange #-}+	inShapeRange (zs :. z) (sh1 :. n1) (sh2 :. n2)+		= (n2 >= z) && (n2 < n1) && (inShapeRange zs sh1 sh2)+++       	listOfShape (sh :. n)+	 = n : listOfShape sh++	shapeOfList xx+	 = case xx of+		[]	-> error $ stage ++ ".toList: empty list when converting to  (_ :. Int)"+		x:xs	-> shapeOfList xs :. x++	{-# INLINE deepSeq #-}+	deepSeq (sh :. n) x = deepSeq sh (n `seq` x)+
+ Data/Array/Repa/Shape.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE RankNTypes #-}++-- | Class of types that can be used as array shapes and indices.+module Data.Array.Repa.Shape+	( Shape(..)+        , inShape+        , showShape )+where++-- Shape ------------------------------------------------------------------------------------------+-- | Class of types that can be used as array shapes and indices.+class Eq sh => Shape sh where++	-- | Get the number of dimensions in a shape.+	rank	:: sh -> Int++	-- | The shape of an array of size zero, with a particular dimensionality.+	zeroDim	:: sh++	-- | The shape of an array with size one, with a particular dimensionality.+	unitDim :: sh++	-- | Compute the intersection of two shapes.+	intersectDim :: sh -> sh -> sh++	-- | Add the coordinates of two shapes componentwise+	addDim  :: sh -> sh -> sh++	-- | Get the total number of elements in an array with this shape.+	size	:: sh -> Int++	-- | Check whether this shape is small enough so that its flat+	--	indices an be represented as `Int`. If this returns `False` then your+	--	array is too big. Mostly used for writing QuickCheck tests.+	sizeIsValid :: sh -> Bool+++	-- | Convert an index into its equivalent flat, linear, row-major version.+	toIndex :: sh	-- ^ Shape of the array.+		-> sh 	-- ^ Index into the array.+		-> Int++	-- | Inverse of `toIndex`.+	fromIndex+		:: sh 	-- ^ Shape of the array.+		-> Int 	-- ^ Index into linear representation.+		-> sh++	-- | Check whether an index is within a given shape.+	inShapeRange+		:: sh 	-- ^ Start index for range.+		-> sh 	-- ^ Final index for range.+		-> sh 	-- ^ Index to check for.+		-> Bool++	-- | Convert a shape into its list of dimensions.+	listOfShape	:: sh -> [Int]++	-- | Convert a list of dimensions to a shape+	shapeOfList	:: [Int] -> sh++	-- | Ensure that a shape is completely evaluated.+	infixr 0 `deepSeq`+	deepSeq :: sh -> a -> a+++-- | Check whether an index is a part of a given shape.+inShape :: forall sh+	.  Shape sh+	=> sh 		-- ^ Shape of the array.+	-> sh		-- ^ Index.+	-> Bool++{-# INLINE inShape #-}+inShape sh ix+	= inShapeRange zeroDim sh ix+++-- | Nicely format a shape as a string+showShape :: Shape sh => sh -> String+showShape = foldr (\sh str -> str ++ " :. " ++ show sh) "Z" . listOfShape+
+ Data/ExtShape.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeOperators #-}++-- | Additional functions on shapes++module Data.ExtShape where++import Data.Array.Repa.Index+import Data.Array.Repa.Shape++++-- | A number of additional operations that are useful together with+-- 'PrimitiveArray's.++class (Eq sh, Shape sh) => ExtShape sh where++  -- | subtract the right coordinates from the left. Does not check if the+  -- resulting shape make sense.++  subDim :: sh -> sh -> sh++  -- | Given an index and an extend, return a list of all indices. For+  -- @rangeList (Z:.3) (Z:.2)@ this returns @[(Z:.3), (Z:.4), (Z:.5)]@.++  rangeList :: sh -> sh -> [sh]++++instance ExtShape Z where+  subDim _ _ = Z+  {-# INLINE subDim #-}+  rangeList _ _ = [Z]+  {-# INLINE rangeList #-}++instance ExtShape sh => ExtShape (sh:.Int) where+  subDim (sh1:.n1) (sh2:.n2) = subDim sh1 sh2 :. (n1-n2)+  {-# INLINE subDim #-}+  rangeList (sh1:.n1) (sh2:.n2) = [sh:.n | sh <- rangeList sh1 sh2, n <- [n1 .. (n1+n2) ] ]+  {-# INLINE rangeList #-}+
Data/PrimitiveArray.hs view
@@ -1,46 +1,164 @@-{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-} --- | Primitive arrays with a small set of operations. Modelled after repa--- arrays and indexing.------ Array indexing is between [i..j] per dimension.+-- | Vastly extended primitive arrays. Some basic ideas are now modeled after+-- the vector package, especially the monadic mutable / pure immutable array+-- system. There are eight flavors of arrays among three axes: mutable/pure ++-- boxed/unboxed + zero-based/lower-bound. ----- All operations are UNSAFE. In interpreted code, "assert" provides a safety--- net.+-- NOTE all operations in MPrimArrayOps and PrimArrayOps are highly unsafe. No+-- bounds-checking is performed at all.  module Data.PrimitiveArray where -import Control.Monad.Primitive (PrimMonad)-import Data.Array.Repa.Shape (Shape)+import Data.Array.Repa.Index+import Data.Array.Repa.Shape+import Data.Primitive.Types+import Data.Primitive+import Control.Monad.ST+import Control.Monad+import Control.Monad.Primitive+import System.IO.Unsafe import Control.Exception (assert) +import Data.ExtShape  -class Shape sh => PrimArrayOps sh elm where-  data PrimArray sh elm :: *-  unsafeIndex :: PrimArray sh elm -> sh -> elm-  bounds :: PrimArray sh elm -> (sh,sh)-  inBounds :: PrimArray sh elm -> sh -> Bool-  fromAssocs :: sh -> sh -> elm -> [(sh,elm)] -> PrimArray sh elm-  assocs :: PrimArray sh elm -> [(sh,elm)] -class (PrimMonad m, Shape sh) => PrimArrayOpsM sh elm m where-  data PrimArrayM sh elm m :: *-  readM :: PrimArrayM sh elm m -> sh -> m elm-  writeM :: PrimArrayM sh elm m -> sh -> elm -> m ()-  -- | Create a monadic array from a list of associations-  fromAssocsM :: sh -> sh -> elm -> [(sh,elm)] -> m (PrimArrayM sh elm m)-  unsafeFreezeM :: PrimArrayM sh elm m -> m (PrimArray sh elm)-  boundsM :: PrimArrayM sh elm m -> (sh,sh)-  inBoundsM :: PrimArrayM sh elm m -> sh -> Bool+-- | The core set of operations for monadic arrays. +class (Shape sh, ExtShape sh) => MPrimArrayOps marr sh elm where +  -- | Return the bounds of the array. All bounds are inclusive, as in+  -- @[lb..ub]@ --- * Helper functions+  boundsM :: marr s sh elm -> (sh,sh) -(!) :: PrimArrayOps sh elm => PrimArray sh elm -> sh -> elm-(!) pa idx = assert (inBounds pa idx) $ unsafeIndex pa idx+  -- | Given lower and upper bounds and a list of /all/ elements, produce a+  -- mutable array.++  fromListM :: PrimMonad m => sh -> sh -> [elm] -> m (marr (PrimState m) sh elm)++  -- | Creates a new array with the given bounds with each element within the+  -- array being in a random state.++  newM :: PrimMonad m => sh -> sh -> m (marr (PrimState m) sh elm)++  -- | Creates a new array with all elements being equal to 'elm'.++  newWithM :: PrimMonad m => sh -> sh -> elm -> m (marr (PrimState m) sh elm)++  -- | Reads a single element in the array.++  readM :: PrimMonad m => marr (PrimState m) sh elm -> sh -> m elm++  -- | Writes a single element in the array.++  writeM :: PrimMonad m => marr (PrimState m) sh elm -> sh -> elm -> m ()++++-- | Used to connect each immutable array with one mutable array.++type family MutArray (v :: * -> * -> * ) :: * -> * -> * -> *++++-- | The core set of functions on immutable arrays.++class (Shape sh, ExtShape sh, MPrimArrayOps (MutArray arr) sh elm) => PrimArrayOps arr sh elm where++  -- | Returns the bounds of an immutable array, again inclusive bounds: @ [lb..ub] @.++  bounds :: arr sh elm -> (sh,sh)++  -- | Freezes a mutable array an returns its immutable version. This operation+  -- is /O(1)/ and both arrays share the same memory. Do not use the mutable+  -- array afterwards.++  freeze :: PrimMonad m => MutArray arr (PrimState m) sh elm -> m (arr sh elm)++  -- | Extract a single element from the array. Generally unsafe as not+  -- bounds-checking is performed.++  index :: arr sh elm -> sh -> elm++++-- | Infix index operator. Performs minimal bounds-checking using assert in+-- non-optimized code.++(!) :: PrimArrayOps arr sh elm => arr sh elm -> sh -> elm+(!) arr idx = assert (inBounds arr idx) $ index arr idx {-# INLINE (!) #-}++-- | Returns true if the index is valid for the array.+--+-- TODO can't give a typedef++inBoundsM :: MPrimArrayOps marr sh elm => marr s sh elm -> sh -> Bool+inBoundsM marr idx = let (lb,ub) = boundsM marr in inShapeRange lb ub idx+{-# INLINE inBoundsM #-}++-- | Given two arrays with the same dimensionality, their respective starting+-- index, and how many steps to go in each dimension (in terms of a dimension+-- again), determine if the multidimensional slices have the same value at+-- all positions+--+-- TODO specialize for DIM1 (and maybe higher dim's) to use memcmp++sliceEq :: (Eq elm, PrimArrayOps arr sh elm) => arr sh elm -> sh -> arr sh elm -> sh -> sh -> Bool+sliceEq arr1 k1 arr2 k2 xtnd = assert ((inBounds arr1 k1) && (inBounds arr2 k2) && (inBounds arr1 $ k1 `addDim` xtnd) && (inBounds arr2 $ k2 `addDim` xtnd)) $ and res where+  res = zipWith (==) xs ys+  xs = map (index arr1) $ rangeList k1 xtnd+  ys = map (index arr2) $ rangeList k2 xtnd+{-# INLINE sliceEq #-}++-- | Construct a mutable primitive array from a lower and an upper bound, a+-- default element, and a list of associations.++fromAssocsM+  :: (PrimMonad m, MPrimArrayOps marr sh elm)+  => sh -> sh -> elm -> [(sh,elm)] -> m (marr (PrimState m) sh elm)+fromAssocsM lb ub def xs = do+  ma <- newWithM lb ub def+  forM_ xs $ \(k,v) -> writeM ma k v+  return ma+{-# INLINE fromAssocsM #-}++-- | Return all associations from an array.++assocs :: PrimArrayOps arr sh elm => arr sh elm -> [(sh,elm)]+assocs arr = map (\k -> (k,index arr k)) $ rangeList lb (ub `subDim` lb) where+  (lb,ub) = bounds arr+{-# INLINE assocs #-}++-- | Creates an immutable array from lower and upper bounds and a complete list+-- of elements.++fromList :: PrimArrayOps arr sh elm => sh -> sh -> [elm] -> arr sh elm+fromList lb ub xs = runST $ fromListM lb ub xs >>= freeze+{-# INLINE fromList #-}++-- | Creates an immutable array from lower and upper bounds, a default element,+-- and a list of associations.++fromAssocs :: PrimArrayOps arr sh elm => sh -> sh -> elm -> [(sh,elm)] -> arr sh elm+fromAssocs lb ub def xs = runST $ fromAssocsM lb ub def xs >>= freeze+{-# INLINE fromAssocs #-}++-- | Determines if an index is valid for a given immutable array.++inBounds :: PrimArrayOps arr sh elm => arr sh elm -> sh -> Bool+inBounds arr idx = let (lb,ub) = bounds arr in inShapeRange lb ub idx+{-# INLINE inBounds #-}++-- | Returns all elements of an immutable array as a list.++toList :: PrimArrayOps arr sh elm =>  arr sh elm -> [elm]+toList arr = let (lb,ub) = bounds arr in map ((!) arr) $ rangeList lb $ ub `subDim` lb+{-# INLINE toList #-} 
− Data/PrimitiveArray/Unboxed.hs
@@ -1,97 +0,0 @@-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleInstances #-}--module Data.PrimitiveArray.Unboxed where--import qualified Data.Vector.Unboxed.Mutable as VUM-import qualified Data.Vector.Unboxed as VU-import Control.Monad.ST-import Control.Monad-import Data.Array.Repa.Shape-import Control.Exception (assert)--import Data.PrimitiveArray--import Data.Array.Repa.Index----instance (VU.Unbox elm, Shape sh, Show elm, Show sh) => PrimArrayOps sh elm where-  -- | An immutable PrimArray has a lower bound (lsh), and upper bound (ush)-  -- and an upper bound minus unitDim (ush'), returned by bounds-  data PrimArray sh elm = PrimArray sh sh sh (VU.Vector elm)-  unsafeIndex (PrimArray lsh ush ush' v) idx = assert (inShapeRange lsh ush idx)-                                             $ v `VU.unsafeIndex` (toIndex ush idx - toIndex ush lsh)-  bounds (PrimArray lsh ush ush' _) = (lsh,ush')-  inBounds (PrimArray lsh ush ush' _) idx = inShapeRange lsh ush idx-  fromAssocs lsh ush' def xs =-    let ush = ush' `addDim` unitDim-    in  PrimArray lsh ush ush'-        $ VU.replicate (size ush - size lsh) def-        VU.// map (\(k,v) -> if (inShapeRange lsh ush k)-                             then (toIndex ush k - toIndex ush lsh,v)-                             else error $ show (lsh,ush,k,v)-                  ) xs-  assocs (PrimArray lsh ush ush' v) = map (\(k,v) -> (fromIndex ush $ k + toIndex ush lsh, v))-                                    . VU.toList-                                    . VU.indexed-                                    $ v-  {-# INLINE unsafeIndex #-}-  {-# INLINE bounds #-}-  {-# INLINE inBounds #-}-  {-# INLINE fromAssocs #-}--deriving instance (Show elm, Show sh, VU.Unbox elm) => Show (PrimArray sh elm)--deriving instance (Read elm, Read sh, VU.Unbox elm) => Read (PrimArray sh elm)----instance (VUM.Unbox elm, Shape sh) => PrimArrayOpsM sh elm (ST s) where-  data PrimArrayM sh elm (ST s) = PrimArrayST sh sh sh (VUM.STVector s elm)-  readM (PrimArrayST lsh ush ush' v) sh = VUM.unsafeRead v (toIndex ush sh - toIndex ush lsh)-  writeM (PrimArrayST lsh ush suh' v) sh e = VUM.unsafeWrite v (toIndex ush sh - toIndex ush lsh) e-  fromAssocsM lsh ush' def xs = do-    let ush = ush' `addDim` unitDim-    v <- VUM.new (size ush - size lsh)-    VUM.set v def-    forM_ xs $ \(k,e) -> assert (inShapeRange lsh ush k)-                      $ VUM.unsafeWrite v (toIndex ush k - toIndex ush lsh) e-    return $ PrimArrayST lsh ush ush' v-  unsafeFreezeM (PrimArrayST lsh ush ush' v) = do-    v' <- VU.unsafeFreeze v-    return $ PrimArray lsh ush ush' v'-  boundsM (PrimArrayST lsh ush ush' _) = (lsh,ush')-  inBoundsM (PrimArrayST lsh ush ush' _) idx = inShapeRange lsh ush idx-  {-# INLINE readM #-}-  {-# INLINE writeM #-}-  {-# INLINE fromAssocsM #-}-  {-# INLINE unsafeFreezeM #-}-  {-# INLINE boundsM #-}-  {-# INLINE inBoundsM #-}--instance (VUM.Unbox elm, Shape sh) => PrimArrayOpsM sh elm IO where-  data PrimArrayM sh elm IO = PrimArrayIO sh sh sh (VUM.IOVector elm)-  readM (PrimArrayIO lsh ush ush' v) sh = VUM.unsafeRead v (toIndex ush sh - toIndex ush lsh)-  writeM (PrimArrayIO lsh ush suh' v) sh e = VUM.unsafeWrite v (toIndex ush sh - toIndex ush lsh) e-  fromAssocsM lsh ush' def xs = do-    let ush = ush' `addDim` unitDim-    v <- VUM.new (size ush - size lsh)-    VUM.set v def-    forM_ xs $ \(k,e) -> assert (inShapeRange lsh ush k)-                      $ VUM.unsafeWrite v (toIndex ush k - toIndex ush lsh) e-    return $ PrimArrayIO lsh ush ush' v-  unsafeFreezeM (PrimArrayIO lsh ush ush' v) = do-    v' <- VU.unsafeFreeze v-    return $ PrimArray lsh ush ush' v'-  boundsM (PrimArrayIO lsh ush ush' _) = (lsh,ush')-  inBoundsM (PrimArrayIO lsh ush ush' _) idx = inShapeRange lsh ush idx-  {-# INLINE readM #-}-  {-# INLINE writeM #-}-  {-# INLINE fromAssocsM #-}-  {-# INLINE unsafeFreezeM #-}-  {-# INLINE boundsM #-}-  {-# INLINE inBoundsM #-}-
+ Data/PrimitiveArray/Unboxed/Zero.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}++-- | Strict, unboxed arrays of primitive type.++module Data.PrimitiveArray.Unboxed.Zero where++import Control.Monad+import Data.Array.Repa.Index+import Data.Array.Repa.Shape+import Data.Primitive+import Data.Primitive.Types+import Control.Exception (assert)++import Data.ExtShape+import Data.PrimitiveArray++++-- | Monadic arrays of primitive type.++data MArr0 s sh elm = MArr0 !sh {-# UNPACK #-} !(MutableByteArray s)++-- | Immutable arrays of primitive type.++data Arr0 sh elm = Arr0 !sh {-# UNPACK #-} !ByteArray++++type instance MutArray Arr0 = MArr0++-- NOTE inLb, inUb is including bound, while exUb is excluding upper bound.+-- Differentiates between largest included index, first excluded index.++instance (Shape sh, ExtShape sh, Prim elm) => MPrimArrayOps MArr0 sh elm where+  boundsM (MArr0 exUb _) = (zeroDim,exUb `subDim` unitDim)+  fromListM inLb inUb xs = do+    ma <- newM inLb inUb+    let exUb = inUb `addDim` unitDim+    let (MArr0 _ mba) = ma+    zipWithM_ (\k x -> assert (length xs == size exUb) $ writeByteArray mba k x) [0.. toIndex exUb inUb] xs+    return ma+  newM inLb inUb = let exUb = inUb `addDim` unitDim in+    unless (inLb == zeroDim) (error "MArr0 lb/=zeroDim") >>+    MArr0 exUb `liftM` newByteArray (size exUb * sizeOf (undefined :: elm))+  newWithM inLb inUb def = do+    let exUb = inUb `addDim` unitDim+    ma <- newM inLb inUb+    let (MArr0 _ mba) = ma+    forM_ [0 .. toIndex exUb inUb] $ \k -> writeByteArray mba k def+    return ma+  readM (MArr0 exUb mba) idx = assert (inShape exUb idx) $ readByteArray mba (toIndex exUb idx)+  writeM (MArr0 exUb mba) idx elm = assert (inShape exUb idx) $ writeByteArray mba (toIndex exUb idx) elm+  {-# INLINE boundsM #-}+  {-# INLINE fromListM #-}+  {-# INLINE newM #-}+  {-# INLINE newWithM #-}+  {-# INLINE readM #-}+  {-# INLINE writeM #-}++instance (Shape sh, ExtShape sh, Prim elm) => PrimArrayOps Arr0 sh elm where+  bounds (Arr0 exUb _) = (zeroDim,exUb `subDim` unitDim)+  freeze (MArr0 exUb mba) = Arr0 exUb `liftM` unsafeFreezeByteArray mba+  index (Arr0 exUb ba) idx = assert (inShape exUb idx) $ indexByteArray ba (toIndex exUb idx)+  {-# INLINE bounds #-}+  {-# INLINE freeze #-}+  {-# INLINE index #-}+
PrimitiveArray.cabal view
@@ -1,5 +1,5 @@ Name:           PrimitiveArray-Version:        0.1.1.2+Version:        0.2.0.0 License:        BSD3 License-file:   LICENSE Author:         Christian Hoener zu Siederdissen@@ -13,26 +13,34 @@ Synopsis:                 Efficient multidimensional arrays Description:-                This library provides efficient multidimensional arrays. All-                arrays are 0-based and indexed using repa-shapes.+                This library provides efficient multidimensional arrays.                 .-                Please note that this version only has the name (and author) in-                common with the previous 0.0.4.0 version. The basic idea of the-                library remains the same: provide efficient access to immutable-                arrays.+                In general all operations are (highly) unsafe, no+                bounds-checking or other sanity-checking is performed.+                Operations are aimed toward efficiency as much as possible.+                Goals of the library are to have arrays according to three+                ideas: immutable/mutable arrays, strict/lazy arrays,+                zero-based/lower-bound arrays. Zero-based arrays save one+                addition on each access if the lower bound or the array is+                always zero.+                .+                We have forked two repa modules: Shape and Index.  Library   Exposed-modules:+    Data.Array.Repa.Index+    Data.Array.Repa.Shape+    Data.ExtShape     Data.PrimitiveArray-    Data.PrimitiveArray.Unboxed+    Data.PrimitiveArray.Unboxed.Zero   Build-depends:     base >= 4 && <5,     primitive >= 0.4,-    vector >= 0.9,-    repa >= 2.0+    vector >= 0.9   ghc-options:     -Odph     -funbox-strict-fields+  source-repository head   type: git