-- | Basic definitions for stencil handling.
module Data.Array.Repa.Stencil.Base
( Boundary (..)
, Stencil (..)
, makeStencil, makeStencil2)
where
import Data.Array.Repa.Index
-- | How to handle the case when the stencil lies partly outside the array.
data Boundary a
-- | Use a fixed value for border regions.
= BoundFixed !a
-- | Treat points outside the array as having a constant value.
| BoundConst !a
-- | Clamp points outside to the same value as the edge pixel.
| BoundClamp
deriving (Show)
-- | Represents a convolution stencil that we can apply to array.
-- Only statically known stencils are supported right now.
data Stencil sh a
-- | Static stencils are used when the coefficients are fixed,
-- and known at compile time.
= StencilStatic
{ stencilExtent :: !sh
, stencilZero :: !a
, stencilAcc :: !(sh -> a -> a -> a) }
-- | Make a stencil from a function yielding coefficients at each index.
makeStencil
:: Num a
=> sh -- ^ Extent of stencil.
-> (sh -> Maybe a) -- ^ Get the coefficient at this index.
-> Stencil sh a
{-# INLINE makeStencil #-}
makeStencil ex getCoeff
= StencilStatic ex 0
$ \ix val acc
-> case getCoeff ix of
Nothing -> acc
Just coeff -> acc + val * coeff
-- | Wrapper for `makeStencil` that requires a DIM2 stencil.
makeStencil2
:: Num a
=> Int -> Int -- ^ extent of stencil
-> (DIM2 -> Maybe a) -- ^ Get the coefficient at this index.
-> Stencil DIM2 a
{-# INLINE makeStencil2 #-}
makeStencil2 height width getCoeff
= makeStencil (Z :. height :. width) getCoeff