packages feed

repa-examples-2.0.0.1: examples/Laplace/src-repa/SolverStencil.hs

{-# LANGUAGE BangPatterns, TemplateHaskell, QuasiQuotes #-}
module SolverStencil
	(solveLaplace)
where	
import Data.Array.Repa				as A
import Data.Array.Repa.Stencil			as A
import Data.Array.Repa.Algorithms.Iterate	as A
import qualified Data.Array.Repa.Shape		as S
import Language.Haskell.TH
import Language.Haskell.TH.Quote

-- | Solver for the Laplace equation.
solveLaplace
	:: Int			-- ^ Number of iterations to use.
	-> Array DIM2 Double	-- ^ Boundary value mask.
	-> Array DIM2 Double	-- ^ Boundary values.
	-> Array DIM2 Double	-- ^ Initial state.
	-> Array DIM2 Double

{-# NOINLINE solveLaplace #-}
solveLaplace !steps !arrBoundMask !arrBoundValue !arrInit
 = go steps arrInit
 where 	go 0 !arr	= arr
	go n !arr	= go (n - 1) (relaxLaplace arrBoundMask arrBoundValue arr)
	

{-# INLINE relaxLaplace #-}
relaxLaplace
	:: Array DIM2 Double	-- ^ Boundary value mask.
	-> Array DIM2 Double	-- ^ Boundary values.
	-> Array DIM2 Double	-- ^ Initial state.
	-> Array DIM2 Double

relaxLaplace 
	 arrBoundMask@(Array _ [Region RangeAll (GenManifest _)])
	arrBoundValue@(Array _ [Region RangeAll (GenManifest _)])
	          arr@(Array _ [Region RangeAll (GenManifest _)])
  = [arrBoundMask, arrBoundValue, arr] `deepSeqArrays` 
    let	ex		= extent arr
	arrBoundMask'	= reshape ex arrBoundMask
	arrBoundValue'	= reshape ex arrBoundValue
	arr'		= reshape ex arr
    in	force
	 $ A.zipWith (+) arrBoundValue'
	 $ A.zipWith (*) arrBoundMask'
	 $ A.map (/ 4)
	 $ mapStencil2 BoundClamp
	   [stencil2| 	0 1 0
			1 0 1 
			0 1 0 |] arr'