sdr-0.1.0.0: tests/TestSuite.hs
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad.Primitive
import Data.Complex
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Generic.Mutable as VGM
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Storable.Mutable as VSM
import Test.QuickCheck
import Test.QuickCheck.Monadic
import Test.Framework (defaultMain, testGroup)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import SDR.FilterInternal
import SDR.Util
tests = [
testGroup "filters" [
testProperty "real" propFiltersReal,
testProperty "complex" propFiltersComplex
],
testGroup "decimators" [
testProperty "real" propDecimationReal,
testProperty "complex" propDecimationComplex
],
testGroup "resamplers" [
testProperty "real" propResamplingReal
],
testProperty "conversion" propConversion,
testProperty "scaling" propScaleReal
]
where
sizes = elements [1024, 2048, 4096, 8192, 16384, 32768, 65536]
numCoeffs = elements [32, 64, 128, 256, 512]
factors = elements [1, 2, 3, 4, 7, 9, 12, 15, 21]
factors' = [1, 2, 3, 4, 7, 9, 12, 15, 21]
propFiltersReal = forAll sizes $ \size ->
forAll (vectorOf size (choose (-10, 10))) $ \inBuf ->
forAll numCoeffs $ \numCoeffs ->
forAll (vectorOf numCoeffs (choose (-10, 10))) $ \coeffs ->
testFiltersReal size numCoeffs coeffs inBuf
testFiltersReal :: Int -> Int -> [Float] -> [Float] -> Property
testFiltersReal size numCoeffs coeffs inBuf = monadicIO $ do
let vCoeffsHalf = VS.fromList coeffs
vCoeffs = VS.fromList $ coeffs ++ reverse coeffs
vInput = VS.fromList inBuf
num = size - numCoeffs*2 + 1
r1 <- run $ getResult num $ filterHighLevel vCoeffs num vInput
r2 <- run $ getResult num $ filterImperative1 vCoeffs num vInput
r3 <- run $ getResult num $ filterImperative2 vCoeffs num vInput
r4 <- run $ getResult num $ filterCRR vCoeffs num vInput
r5 <- run $ getResult num $ filterCSSERR vCoeffs num vInput
r6 <- run $ getResult num $ filterCAVXRR vCoeffs num vInput
r7 <- run $ getResult num $ filterCSSESymmetricRR vCoeffsHalf num vInput
r8 <- run $ getResult num $ filterCAVXSymmetricRR vCoeffsHalf num vInput
assert $ and $ map (r1 `eqDelta`) [r2, r3, r4, r5, r6, r7, r8]
propFiltersComplex = forAll sizes $ \size ->
forAll (vectorOf size (choose (-10, 10))) $ \inBufR ->
forAll (vectorOf size (choose (-10, 10))) $ \inBufI ->
forAll numCoeffs $ \numCoeffs ->
forAll (vectorOf numCoeffs (choose (-10, 10))) $ \coeffs ->
testFiltersComplex size numCoeffs coeffs $ zipWith (:+) inBufR inBufI
testFiltersComplex :: Int -> Int -> [Float] -> [Complex Float] -> Property
testFiltersComplex size numCoeffs coeffs inBuf = monadicIO $ do
let vCoeffsHalf = VS.fromList coeffs
vCoeffs = VS.fromList $ coeffs ++ reverse coeffs
vInput = VS.fromList inBuf
num = size - numCoeffs*2 + 1
vCoeffs2 = VG.fromList $ duplicate $ coeffs ++ reverse coeffs
r1 <- run $ getResult num $ filterHighLevel vCoeffs num vInput
r2 <- run $ getResult num $ filterCRC vCoeffs num vInput
r3 <- run $ getResult num $ filterCSSERC vCoeffs2 num vInput
r4 <- run $ getResult num $ filterCSSERC2 vCoeffs num vInput
r5 <- run $ getResult num $ filterCAVXRC vCoeffs2 num vInput
r6 <- run $ getResult num $ filterCSSESymmetricRC vCoeffsHalf num vInput
r7 <- run $ getResult num $ filterCAVXSymmetricRC vCoeffsHalf num vInput
assert $ and $ map (r1 `eqDeltaC`) [r2, r3, r4, r5, r6, r7]
propDecimationReal = forAll sizes $ \size ->
forAll (vectorOf size (choose (-10, 10))) $ \inBuf ->
forAll numCoeffs $ \numCoeffs ->
forAll (vectorOf numCoeffs (choose (-10, 10))) $ \coeffs ->
forAll factors $ \factor ->
testDecimationReal size numCoeffs factor coeffs inBuf
testDecimationReal :: Int -> Int -> Int -> [Float] -> [Float] -> Property
testDecimationReal size numCoeffs factor coeffs inBuf = monadicIO $ do
let vCoeffsHalf = VS.fromList coeffs
vCoeffs = VS.fromList $ coeffs ++ reverse coeffs
vInput = VS.fromList inBuf
num = (size - numCoeffs*2 + 1) `quot` factor
r1 <- run $ getResult num $ decimateHighLevel factor vCoeffs num vInput
r2 <- run $ getResult num $ decimateCRR factor vCoeffs num vInput
r3 <- run $ getResult num $ decimateCSSERR factor vCoeffs num vInput
r4 <- run $ getResult num $ decimateCAVXRR factor vCoeffs num vInput
r5 <- run $ getResult num $ decimateCSSESymmetricRR factor vCoeffsHalf num vInput
r6 <- run $ getResult num $ decimateCAVXSymmetricRR factor vCoeffsHalf num vInput
assert $ and $ map (r1 `eqDelta`) [r2, r3, r4, r5, r6]
propDecimationComplex = forAll sizes $ \size ->
forAll (vectorOf size (choose (-10, 10))) $ \inBufR ->
forAll (vectorOf size (choose (-10, 10))) $ \inBufI ->
forAll numCoeffs $ \numCoeffs ->
forAll (vectorOf numCoeffs (choose (-10, 10))) $ \coeffs ->
forAll factors $ \factor ->
testDecimationComplex size numCoeffs factor coeffs $ zipWith (:+) inBufR inBufI
testDecimationComplex :: Int -> Int -> Int -> [Float] -> [Complex Float] -> Property
testDecimationComplex size numCoeffs factor coeffs inBuf = monadicIO $ do
let vCoeffsHalf = VS.fromList coeffs
vCoeffs = VS.fromList $ coeffs ++ reverse coeffs
vInput = VS.fromList inBuf
num = (size - numCoeffs*2 + 1) `quot` factor
vCoeffs2 = VG.fromList $ duplicate $ coeffs ++ reverse coeffs
r1 <- run $ getResult num $ decimateHighLevel factor vCoeffs num vInput
r2 <- run $ getResult num $ decimateCRC factor vCoeffs num vInput
r3 <- run $ getResult num $ decimateCSSERC factor vCoeffs2 num vInput
r4 <- run $ getResult num $ decimateCSSERC2 factor vCoeffs num vInput
r5 <- run $ getResult num $ decimateCAVXRC factor vCoeffs2 num vInput
r6 <- run $ getResult num $ decimateCSSESymmetricRC factor vCoeffsHalf num vInput
r7 <- run $ getResult num $ decimateCAVXRC2 factor vCoeffs num vInput
r8 <- run $ getResult num $ decimateCAVXSymmetricRC factor vCoeffsHalf num vInput
assert $ and $ map (r1 `eqDeltaC`) [r2, r3, r4, r5, r6, r7, r8]
propResamplingReal = forAll sizes $ \size ->
forAll (vectorOf size (choose (-10, 10))) $ \inBuf ->
forAll numCoeffs $ \numCoeffs ->
forAll (vectorOf numCoeffs (choose (-10, 10))) $ \coeffs ->
forAll (elements $ tail factors') $ \decimation ->
forAll (elements $ filter (< decimation) factors') $ \interpolation ->
testResamplingReal size numCoeffs interpolation decimation coeffs inBuf
testResamplingReal :: Int -> Int -> Int -> Int -> [Float] -> [Float] -> Property
testResamplingReal size numCoeffs interpolation decimation coeffs inBuf = monadicIO $ do
let vCoeffsHalf = VS.fromList coeffs
vCoeffs = VS.fromList $ coeffs ++ reverse coeffs
vInput = VS.fromList inBuf
num = (size - numCoeffs*2 + 1) `quot` decimation
resampler3 <- run $ resampleCRR2 interpolation decimation (coeffs ++ reverse coeffs)
resampler4 <- run $ resampleCSSERR interpolation decimation (coeffs ++ reverse coeffs)
resampler5 <- run $ resampleCAVXRR interpolation decimation (coeffs ++ reverse coeffs)
r1 <- run $ getResult num $ resampleHighLevel interpolation decimation vCoeffs 0 num vInput
r2 <- run $ getResult num $ resampleCRR num interpolation decimation 0 vCoeffs vInput
r3 <- run $ getResult num $ resampler3 num 0 vInput
r4 <- run $ getResult num $ resampler4 num 0 vInput
r5 <- run $ getResult num $ resampler5 num 0 vInput
assert $ and $ map (r1 `eqDelta`) [r2, r3, r4, r5]
getResult :: (VSM.Storable a) => Int -> (VS.MVector RealWorld a -> IO b) -> IO [a]
getResult size func = do
outBuf <- VGM.new size
func outBuf
out :: VS.Vector a <- VG.freeze outBuf
return $ VG.toList out
propConversion = forAll sizes $ \size ->
forAll (vectorOf (2 * size) (choose (-10, 10))) $ \inBuf ->
testConversion size inBuf
testConversion :: Int -> [Int] -> Property
testConversion size inBuf = monadicIO $ do
let vInput = VS.fromList $ map fromIntegral inBuf
let r1 = VG.toList $ (makeComplexBufferVect vInput :: VS.Vector (Complex Float))
r2 = VG.toList $ convertC vInput
r3 = VG.toList $ convertCSSE vInput
r4 = VG.toList $ convertCAVX vInput
assert $ and $ map (r1 `eqDeltaC`) [r2, r3, r4]
scales = elements [0.1, 0.5, 1, 2, 10]
propScaleReal = forAll sizes $ \size ->
forAll (vectorOf size (choose (-10, 10))) $ \inBuf ->
forAll scales $ \factor ->
testScaleReal size inBuf factor
testScaleReal :: Int -> [Float] -> Float -> Property
testScaleReal size inBuf factor = monadicIO $ do
let vInput = VS.fromList inBuf
r1 <- run $ getResult size $ scaleC factor vInput
r2 <- run $ getResult size $ scaleCSSE factor vInput
r3 <- run $ getResult size $ scaleCAVX factor vInput
assert $ and $ map (r1 `eqDelta`) [r2, r3]
eqDelta x y = and $ map (uncurry eqDelta') $ zip x y
where
eqDelta' x y = abs (x - y) < 0.01
eqDeltaC x y = and $ map (uncurry eqDelta') $ zip x y
where
eqDelta' x y = magnitude (x - y) < 0.01
duplicate :: [a] -> [a]
duplicate = concat . map func
where func x = [x, x]
main = defaultMain tests