module Data.Array.Repa.Internals.Base
( Array (..)
, Region(..)
, Range (..)
, Rect (..)
, Generator(..)
, deepSeqArray, deepSeqArrays
, singleton, toScalar
, extent, delay
, inRange
, (!), index
, (!?), safeIndex
, unsafeIndex
, fromFunction
, fromVector
, fromList)
where
import Data.Array.Repa.Index
import Data.Array.Repa.Internals.Elt
import Data.Array.Repa.Shape as S
import qualified Data.Vector.Unboxed as V
import Data.Vector.Unboxed (Vector)
stage = "Data.Array.Repa.Array"
data Array sh a
= Array
{
arrayExtent :: sh
, arrayRegions :: [Region sh a] }
data Region sh a
= Region
{
regionRange :: Range sh
, regionGenerator :: Generator sh a }
data Range sh
= RangeAll
| RangeRects
{ rangeMatch :: sh -> Bool
, rangeRects :: [Rect sh] }
data Rect sh
= Rect sh sh
data Generator sh a
= GenManifest (Vector a)
| forall cursor
. GenCursor
{
genMakeCursor :: sh -> cursor
, genShiftCursor :: sh -> cursor -> cursor
, genLoadElem :: cursor -> a }
infixr 0 `deepSeqArray`
deepSeqArray :: Shape sh => Array sh a -> b -> b
deepSeqArray (Array ex rgns) x
= ex `S.deepSeq` rgns `deepSeqRegions` x
infixr 0 `deepSeqArrays`
deepSeqArrays :: Shape sh => [Array sh a] -> b -> b
deepSeqArrays as y
= case as of
[] -> y
[a] -> a `deepSeqArray` y
[a1, a2] -> a1 `deepSeqArray` a2 `deepSeqArray` y
[a1, a2, a3] -> a1 `deepSeqArray` a2 `deepSeqArray` a3 `deepSeqArray` y
[a1, a2, a3, a4]-> a1 `deepSeqArray` a2 `deepSeqArray` a3 `deepSeqArray` a4 `deepSeqArray` y
_ -> deepSeqArrays' as y
deepSeqArrays' as' y
= case as' of
[] -> y
x : xs -> x `deepSeqArray` xs `deepSeqArrays` y
infixr 0 `deepSeqRegion`
deepSeqRegion :: Shape sh => Region sh a -> b -> b
deepSeqRegion (Region range gen) x
= range `deepSeqRange` gen `deepSeqGen` x
infixr 0 `deepSeqRegions`
deepSeqRegions :: Shape sh => [Region sh a] -> b -> b
deepSeqRegions rs y
= case rs of
[] -> y
[r] -> r `deepSeqRegion` y
[r1, r2] -> r1 `deepSeqRegion` r2 `deepSeqRegion` y
rs' -> deepSeqRegions' rs' y
deepSeqRegions' rs' y
= case rs' of
[] -> y
x : xs -> x `deepSeqRegion` xs `deepSeqRegions'` y
infixr 0 `deepSeqRange`
deepSeqRange :: Shape sh => Range sh -> b -> b
deepSeqRange range x
= case range of
RangeAll -> x
RangeRects f rects -> f `seq` rects `seq` x
infixr 0 `deepSeqGen`
deepSeqGen :: Shape sh => Generator sh a -> b -> b
deepSeqGen gen x
= case gen of
GenManifest vec -> vec `seq` x
GenCursor{} -> x
inRange :: Shape sh => Range sh -> sh -> Bool
inRange RangeAll _ = True
inRange (RangeRects fn _) ix = fn ix
singleton :: Elt a => a -> Array Z a
singleton = fromFunction Z . const
toScalar :: Elt a => Array Z a -> a
toScalar arr = arr ! Z
extent :: Array sh a -> sh
extent arr = arrayExtent arr
delay :: (Shape sh, Elt a)
=> Array sh a
-> (sh, sh -> a)
delay arr@(Array sh _)
= (sh, (arr !))
(!), index
:: forall sh a
. (Shape sh, Elt a)
=> Array sh a
-> sh
-> a
(!) arr ix = index arr ix
index arr ix
= case arr of
Array _ []
-> zero
Array sh [Region _ gen1]
-> indexGen sh gen1 ix
Array sh [Region r1 gen1, Region _ gen2]
| inRange r1 ix -> indexGen sh gen1 ix
| otherwise -> indexGen sh gen2 ix
_ -> index' arr ix
where
indexGen sh gen ix'
= case gen of
GenManifest vec
-> vec V.! (S.toIndex sh ix')
GenCursor makeCursor _ loadElem
-> loadElem $ makeCursor ix'
index' (Array sh (Region range gen : rs)) ix'
| inRange range ix = indexGen sh gen ix'
| otherwise = index' (Array sh rs) ix'
index' (Array _ []) _
= zero
(!?), safeIndex
:: forall sh a
. (Shape sh, Elt a)
=> Array sh a
-> sh
-> Maybe a
(!?) arr ix = safeIndex arr ix
safeIndex arr ix
= case arr of
Array _ []
-> Nothing
Array sh [Region _ gen1]
-> indexGen sh gen1 ix
Array sh [Region r1 gen1, Region r2 gen2]
| inRange r1 ix -> indexGen sh gen1 ix
| inRange r2 ix -> indexGen sh gen2 ix
| otherwise -> Nothing
_ -> index' arr ix
where
indexGen sh gen ix'
= case gen of
GenManifest vec
-> vec V.!? (S.toIndex sh ix')
GenCursor makeCursor _ loadElem
-> Just (loadElem $ makeCursor ix')
index' (Array sh (Region range gen : rs)) ix'
| inRange range ix = indexGen sh gen ix'
| otherwise = index' (Array sh rs) ix'
index' (Array _ []) _
= Nothing
unsafeIndex
:: forall sh a
. (Shape sh, Elt a)
=> Array sh a
-> sh
-> a
unsafeIndex arr ix
= case arr of
Array _ []
-> zero
Array sh [Region _ gen1]
-> unsafeIndexGen sh gen1 ix
Array sh [Region r1 gen1, Region _ gen2]
| inRange r1 ix -> unsafeIndexGen sh gen1 ix
| otherwise -> unsafeIndexGen sh gen2 ix
_ -> unsafeIndex' arr ix
where
unsafeIndexGen sh gen ix'
= case gen of
GenManifest vec
-> vec `V.unsafeIndex` (S.toIndex sh ix')
GenCursor makeCursor _ loadElem
-> loadElem $ makeCursor ix'
unsafeIndex' (Array sh (Region range gen : rs)) ix'
| inRange range ix = unsafeIndexGen sh gen ix'
| otherwise = unsafeIndex' (Array sh rs) ix'
unsafeIndex' (Array _ []) _
= zero
fromFunction
:: Shape sh
=> sh
-> (sh -> a)
-> Array sh a
fromFunction sh fnElems
= sh `S.deepSeq`
Array sh [Region
RangeAll
(GenCursor id addDim fnElems)]
fromVector
:: Shape sh
=> sh
-> Vector a
-> Array sh a
fromVector sh vec
= sh `S.deepSeq` vec `seq`
Array sh [Region RangeAll (GenManifest vec)]
fromList
:: (Shape sh, Elt a)
=> sh
-> [a]
-> Array sh a
fromList sh xx
| V.length vec /= S.size sh
= error $ unlines
[ stage ++ ".fromList: size of array shape does not match size of list"
, " size of shape = " ++ (show $ S.size sh) ++ "\n"
, " size of list = " ++ (show $ V.length vec) ++ "\n" ]
| otherwise
= Array sh [Region RangeAll (GenManifest vec)]
where vec = V.fromList xx