repa-fftw-3.2.3.1: exec/test.hs
-- | Main entry point for test executable.
module Main where
import Data.Array.Repa ((:.)(..), Array, DIM1, DIM2, DIM3, Shape, Z(..), toList)
import Data.Array.Repa.Eval (fromList)
import Data.Array.Repa.Repr.ForeignPtr (F)
import Data.Complex (Complex(..), magnitude)
import Test.Tasty (defaultMain, testGroup)
import Test.Tasty.HUnit (Assertion, assertBool, testCase)
import Test.Tasty.QuickCheck (Property, choose, forAll, testProperty, vector)
import Data.Array.Repa.FFTW (fft, ifft, fft2d, ifft2d, fft3d, ifft3d)
main :: IO ()
main = defaultMain $
testGroup "repa-fftw"
[ testCase "magsum1d-hunit" case_magsum1d
, testCase "magsum2d-hunit" case_magsum2d
, testCase "magsum3d-hunit" case_magsum3d
, testProperty "magsum1d-qc" prop_magsum1d
, testProperty "magsum2d-qc" prop_magsum2d
, testProperty "magsum3d-qc" prop_magsum3d
]
case_magsum1d :: Assertion
case_magsum1d = do
let a = fromList (Z :. 4) [i :+ 0 | i <- [0..3]]
assertBool "diff is greater than epsilon" $ compareMagnitudeSum1d a
case_magsum2d :: Assertion
case_magsum2d = do
let a = fromList (Z :. 4 :. 4) [i :+ 0 | i <- [0..15]]
assertBool "diff is greater than epsilon" $ compareMagnitudeSum2d a
case_magsum3d :: Assertion
case_magsum3d = do
let a = fromList (Z :. 4 :. 4 :. 4) [i :+ 0 | i <- [0..63]]
assertBool "diff is greater than epsilon" $ compareMagnitudeSum3d a
prop_magsum1d :: Property
prop_magsum1d =
forAll (choose (1, 16::Int)) $ \pow ->
let size = (2 ^ pow)
in forAll (vector size) $ \vals ->
compareMagnitudeSum1d $ fromList (Z :. size) vals
prop_magsum2d :: Property
prop_magsum2d =
forAll (choose (1, 4::Int)) $ \pow ->
let extnt = 2 ^ pow
size = extnt ^ (2 :: Int)
in forAll (vector size) $ \vals ->
compareMagnitudeSum2d $ fromList (Z :. extnt :. extnt) vals
prop_magsum3d :: Property
prop_magsum3d =
forAll (choose (1, 4::Int)) $ \pow ->
let extnt = 2 ^ pow
size = extnt ^ (3 :: Int)
in forAll (vector size) $ \vals ->
compareMagnitudeSum3d $ fromList (Z :. extnt :. extnt :. extnt) vals
-- | Performs fft and ifft, then compareing magnitude of sum with the
-- original.
compareMagnitudeSum1d :: Array F DIM1 (Complex Double) -> Bool
compareMagnitudeSum1d = compareMagnitudeSum fft ifft
-- | Like 'compareMagnitudeSum', for 2-dimensional array.
compareMagnitudeSum2d :: Array F DIM2 (Complex Double) -> Bool
compareMagnitudeSum2d = compareMagnitudeSum fft2d ifft2d
-- | Like 'compareMagnitudeSum', for 3-dimensional array.
compareMagnitudeSum3d :: Array F DIM3 (Complex Double) -> Bool
compareMagnitudeSum3d = compareMagnitudeSum fft3d ifft3d
-- | Apply given functions, then compare the result with original.
compareMagnitudeSum ::
(Shape sh)
=> (Array F sh (Complex Double) -> a)
-- ^ Forward FFT function.
-> (a -> Array F sh (Complex Double))
-- ^ Inverse FFT function.
-> Array F sh (Complex Double)
-- ^ Original input.
-> Bool
compareMagnitudeSum fn ifn arr = diff < epsilon
where
diff = abs (mag arr - mag arr')
mag = magnitude . sum . toList
arr' = ifn $ fn arr
epsilon = 1e-2