Efficient computation of stencil based convolutions.
This is specialised for stencils up to 7x7.
Due to limitations in the GHC optimiser, using larger stencils doesn't work, and will yield error
at runtime. We can probably increase the limit if required -- just ask.
The focus of the stencil is in the center of the 7x7 tile, which has coordinates (0, 0). All coefficients in the stencil must fit in the tile, so they can be given X,Y coordinates up to +/- 3 positions. The stencil can be any shape, and need not be symmetric -- provided it fits in the 7x7 tile.
- data Stencil sh a = StencilStatic {
- stencilExtent :: !sh
- stencilZero :: !a
- stencilAcc :: !(sh -> a -> a -> a)
- data Boundary a
- = BoundConst a
- | BoundClamp
- makeStencil :: (Elt a, Num a) => sh -> (sh -> Maybe a) -> Stencil sh a
- makeStencil2 :: (Elt a, Num a) => Int -> Int -> (DIM2 -> Maybe a) -> Stencil DIM2 a
- mapStencil2 :: Elt a => Boundary a -> Stencil DIM2 a -> Array DIM2 a -> Array DIM2 a
- forStencil2 :: Elt a => Boundary a -> Array DIM2 a -> Stencil DIM2 a -> Array DIM2 a
- mapStencilFrom2 :: (Elt a, Elt b) => Boundary a -> Stencil DIM2 a -> Array DIM2 b -> (b -> a) -> Array DIM2 a
- forStencilFrom2 :: (Elt a, Elt b) => Boundary a -> Array DIM2 b -> (b -> a) -> Stencil DIM2 a -> Array DIM2 a
- stencil2 :: QuasiQuoter
Documentation
Represents a convolution stencil that we can apply to array. Only statically known stencils are supported right now.
StencilStatic | Static stencils are used when the coefficients are fixed, and known at compile time. |
|
How to handle the case when the stencil lies partly outside the array.
BoundConst a | Treat points outside as having a constant value. |
BoundClamp | Clamp points outside to the same value as the edge pixel. |
Stencil creation.
:: (Elt a, Num a) | |
=> sh | Extent of stencil. |
-> (sh -> Maybe a) | Get the coefficient at this index. |
-> Stencil sh a |
Make a stencil from a function yielding coefficients at each index.
:: (Elt a, Num a) | |
=> Int | |
-> Int | extent of stencil |
-> (DIM2 -> Maybe a) | Get the coefficient at this index. |
-> Stencil DIM2 a |
Wrapper for makeStencil
that requires a DIM2 stencil.
Stencil operators.
mapStencil2 :: Elt a => Boundary a -> Stencil DIM2 a -> Array DIM2 a -> Array DIM2 aSource
Apply a stencil to every element of a 2D array.
The array must be manifest else error
.
forStencil2 :: Elt a => Boundary a -> Array DIM2 a -> Stencil DIM2 a -> Array DIM2 aSource
Like mapStencil2
but with the parameters flipped.
:: (Elt a, Elt b) | |
=> Boundary a | How to handle the boundary of the array. |
-> Stencil DIM2 a | Stencil to apply. |
-> Array DIM2 b | Array to apply stencil to. |
-> (b -> a) | Apply this function to values read from the array before transforming them with the stencil. |
-> Array DIM2 a |
Apply a stencil to every element of a 2D array.
The array must be manifest else error
.
forStencilFrom2 :: (Elt a, Elt b) => Boundary a -> Array DIM2 b -> (b -> a) -> Stencil DIM2 a -> Array DIM2 aSource
Like mapStencilFrom2
but with the parameters flipped.
QuasiQuoter for producing a static stencil defintion.
A definition like
[stencil2| 0 1 0 1 0 1 0 1 0 |]
Is converted to:
makeStencil2 (Z:.3:.3) (\ix -> case ix of Z :. -1 :. 0 -> Just 1 Z :. 0 :. -1 -> Just 1 Z :. 0 :. 1 -> Just 1 Z :. 1 :. 0 -> Just 1 _ -> Nothing)