{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Test.FFT (
test_fft
) where
import Config
import ParseArgs
import Control.Applicative
import Data.Label
import Data.Maybe
import Data.Typeable
import Prelude as P
import Test.Base
import Test.QuickCheck hiding ( (.&.) )
import Test.Framework
import Test.Framework.Providers.QuickCheck2
import QuickCheck.Arbitrary.Array
import Data.Array.Accelerate.Math.FFT as FFT
import Data.Array.Accelerate as A hiding ( (!) )
import Data.Array.Accelerate.Array.Sugar ( (!) )
import Data.Array.Accelerate.Data.Complex
newtype PowerOf2Array a = PowerOf2Array (Array DIM2 a) deriving Show
instance (Arbitrary a, Elt a) => Arbitrary (PowerOf2Array a) where
arbitrary =
do
Z:.y:.x <- arbitrary
PowerOf2Array <$> arbitraryArray (Z:.ceil2n y:.ceil2n x)
where
ceil2n :: Int -> Int
ceil2n = (2^) . (P.floor :: Float -> Int) . P.logBase 2 . (+1) . (P.fromIntegral :: Int -> Float)
shrink (PowerOf2Array a)
= let Z:.h:.w = arrayShape a
in if h > 0 && w >0
then [ PowerOf2Array . fromList (Z:.(h `div` 2):.w) $ [a ! (Z:.y:.x) | y <- [0..h `div` 2], x <- [0..w - 1]]
, PowerOf2Array . fromList (Z:.h:.(w `div` 2)) $ [a ! (Z:.y:.x) | y <- [0..h - 1], x <- [0..w `div` 2]] ]
else []
test_fft :: Config -> Test
test_fft opt = testGroup "fft" $ catMaybes
[ testElt configFloat (undefined::Float)
, testElt configDouble (undefined::Double)
]
where
backend = get configBackend opt
testElt :: forall a. (Elt a, Similar a, Arbitrary a, IsFloating a, RealFloat a)
=> (Config :-> Bool)
-> a
-> Maybe Test
testElt ok _
| P.not (get ok opt) = Nothing
| otherwise = Just $ testGroup (show (typeOf (undefined :: a)))
[ testProperty "size" (test_size :: PowerOf2Array (Complex a) -> Property)
, testProperty "trans" (test_trans :: PowerOf2Array (Complex a) -> Property) ]
test_trans :: (Elt a, RealFloat a, IsFloating a, Similar a) => PowerOf2Array (Complex a) -> Property
test_trans (PowerOf2Array xs)
= let Z:.h:.w = arrayShape xs
in run1 backend (transpose . fft2D' Forward w h) xs
~?= run1 backend (fft2D' Forward h w . transpose) xs
test_size :: (Elt a, IsFloating a, RealFloat a, Similar a) => PowerOf2Array (Complex a) -> Property
test_size (PowerOf2Array xs)
= let Z:.h:.w = arrayShape xs
in arrayShape xs
~?= arrayShape (run1 backend (fft2D' Forward w h) xs)