module Data.PrimitiveArray where
import Control.Exception (assert)
import Control.Monad
import Control.Monad.Primitive
import Control.Monad.ST
import Data.Array.Repa.Index
import Data.Array.Repa.Shape
import Data.Primitive
import Data.Primitive.Types
import Prelude as P
import System.IO.Unsafe
import Data.Array.Repa.ExtShape
data family MutArr (m :: * -> *) (arr :: *) :: *
class (Shape sh, ExtShape sh) => MPrimArrayOps arr sh elm where
boundsM :: MutArr m (arr sh elm) -> (sh,sh)
fromListM :: PrimMonad m => sh -> sh -> [elm] -> m (MutArr m (arr sh elm))
newM :: PrimMonad m => sh -> sh -> m (MutArr m (arr sh elm))
newWithM :: PrimMonad m => sh -> sh -> elm -> m (MutArr m (arr sh elm))
readM :: PrimMonad m => MutArr m (arr sh elm) -> sh -> m elm
writeM :: PrimMonad m => MutArr m (arr sh elm) -> sh -> elm -> m ()
class (Shape sh, ExtShape sh) => PrimArrayOps arr sh elm where
bounds :: arr sh elm -> (sh,sh)
freeze :: PrimMonad m => MutArr m (arr sh elm) -> m (arr sh elm)
index :: arr sh elm -> sh -> elm
class (Shape sh, ExtShape sh) => PrimArrayMap arr sh e e' where
map :: (e -> e') -> arr sh e -> arr sh e'
(!) :: PrimArrayOps arr sh elm => arr sh elm -> sh -> elm
(!) arr idx = assert (inBounds arr idx) $ index arr idx
inBoundsM :: (Monad m, MPrimArrayOps arr sh elm) => MutArr m (arr sh elm) -> sh -> Bool
inBoundsM marr idx = let (lb,ub) = boundsM marr in inShapeRange lb ub idx
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 = P.map (index arr1) $ rangeList k1 xtnd
ys = P.map (index arr2) $ rangeList k2 xtnd
fromAssocsM
:: (PrimMonad m, MPrimArrayOps arr sh elm)
=> sh -> sh -> elm -> [(sh,elm)] -> m (MutArr m (arr sh elm))
fromAssocsM lb ub def xs = do
ma <- newWithM lb ub def
forM_ xs $ \(k,v) -> writeM ma k v
return ma
assocs :: PrimArrayOps arr sh elm => arr sh elm -> [(sh,elm)]
assocs arr = P.map (\k -> (k,index arr k)) $ rangeList lb (ub `subDim` lb) where
(lb,ub) = bounds arr
fromList :: (PrimArrayOps arr sh elm, MPrimArrayOps arr sh elm) => sh -> sh -> [elm] -> arr sh elm
fromList lb ub xs = runST $ fromListM lb ub xs >>= freeze
fromAssocs :: (PrimArrayOps arr sh elm, MPrimArrayOps arr sh elm) => sh -> sh -> elm -> [(sh,elm)] -> arr sh elm
fromAssocs lb ub def xs = runST $ fromAssocsM lb ub def xs >>= freeze
inBounds :: PrimArrayOps arr sh elm => arr sh elm -> sh -> Bool
inBounds arr idx = let (lb,ub) = bounds arr in inShapeRange lb (ub `addDim` unitDim) idx
toList :: PrimArrayOps arr sh elm => arr sh elm -> [elm]
toList arr = let (lb,ub) = bounds arr in P.map ((!) arr) $ rangeList lb $ ub `subDim` lb