PrimitiveArray-0.5.0.0: Data/Array/Repa/Index/Point.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
-- | A Repa-compatible index of points in multi-dimensional space. A point
-- represents the index of a left- or right-linear grammar.
module Data.Array.Repa.Index.Point where
import Control.Applicative
import Control.DeepSeq
import Data.Array.Repa.Index
import Data.Array.Repa.Shape
import GHC.Base (quotInt, remInt)
import Test.QuickCheck
import Test.QuickCheck.All
import Data.Array.Repa.ExtShape
stage = "Data.Array.Repa.Index.Point"
-- |
newtype Point = Point Int
deriving (Eq,Ord,Show)
-- |
instance Shape sh => Shape (sh :. Point) where
{-# INLINE [1] rank #-}
rank (sh :. _)
= rank sh + 1
{-# INLINE [1] zeroDim #-}
zeroDim = zeroDim :. Point 0
{-# INLINE [1] unitDim #-}
unitDim = unitDim :. Point 1
{-# INLINE [1] intersectDim #-}
intersectDim (sh1 :. Point n1) (sh2 :. Point n2)
= (intersectDim sh1 sh2 :. Point (min n1 n2))
{-# INLINE [1] addDim #-}
addDim (sh1 :. Point n1) (sh2 :. Point n2)
= addDim sh1 sh2 :. Point (n1 + n2)
{-# INLINE [1] size #-}
size (sh1 :. Point n)
= size sh1 * n
{-# INLINE [1] sizeIsValid #-}
sizeIsValid (sh1 :. Point n)
| size sh1 > 0
= n <= maxBound `div` size sh1
| otherwise
= False
{-# INLINE [1] toIndex #-}
toIndex (sh1 :. Point sh2) (sh1' :. Point sh2')
= toIndex sh1 sh1' * sh2 + sh2'
{-# INLINE [1] fromIndex #-}
fromIndex (ds :. Point d) n
= fromIndex ds (n `quotInt` d) :. Point 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 [1] inShapeRange #-}
inShapeRange (zs :. Point z) (sh1 :. Point n1) (sh2 :. Point n2)
= (n2 >= z) && (n2 < n1) && (inShapeRange zs sh1 sh2)
{-# NOINLINE listOfShape #-}
listOfShape (sh :. Point n)
= n : listOfShape sh
{-# NOINLINE shapeOfList #-}
shapeOfList xx
= case xx of
[] -> error $ stage ++ ".toList: empty list when converting to (_ :. Point)"
x:xs -> shapeOfList xs :. Point x
{-# INLINE deepSeq #-}
deepSeq (sh :. Point n) x = deepSeq sh (n `seq` x)
-- |
instance ExtShape sh => ExtShape (sh:.Point) where
subDim (sh1:.Point n1) (sh2:.Point n2) = subDim sh1 sh2 :. Point (n1-n2)
{-# INLINE subDim #-}
rangeList (sh1:.Point n1) (sh2:.Point n2) = [sh:.Point n | sh <- rangeList sh1 sh2, n <- [n1 .. (n1+n2) ] ]
{-# INLINE rangeList #-}
instance NFData Point where
rnf (Point i) = rnf i
-- |
instance Arbitrary Point where
arbitrary = Point <$> choose (0,100)
shrink (Point i)
| i>0 = [Point (i-1)]
| otherwise = []
instance Arbitrary z => Arbitrary (z:.Point) where
arbitrary = (:.) <$> arbitrary <*> arbitrary
shrink (z:.s) = (:.) <$> shrink z <*> shrink s