iter-stats-0.1.0.3: tests/Statistics/Iteratee/Tests.hs
module Statistics.Iteratee.Tests
where
import Data.Iteratee as I
import Statistics.Iteratee as Si
import Statistics.Sample as St
import Test.Framework
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Control.Monad.Identity
import qualified Data.Vector.Unboxed as V
tests =
[ testGroup "Sample" $ map mkUnProp uns
]
-- Don't want to drag in more dependencies for just this.
class ApproxEq a where
approxEq :: Double -> a -> a -> Bool
instance ApproxEq Double where
approxEq tol d1 d2 = m == 0.0 || d/m < tol where
m = max (abs d1) (abs d2)
d = abs (d1 - d2)
instance (ApproxEq a, ApproxEq b) => ApproxEq (a,b) where
approxEq tol (l1,r1) (l2,r2) = approxEq tol l1 l2 && approxEq tol r1 r2
infix 4 ===
(===) :: (ApproxEq a) => a -> a -> Bool
(===) = approxEq {-pretty equal-}1.0e-10
unsProp :: (ApproxEq a)
=> (V.Vector Double -> a)
-> (Iteratee [Double] Identity a)
-> [Double]
-> Bool
unsProp vec iter xs = if null xs then True
else vec (V.fromList xs) === (runIdentity $ run =<< enumPure1Chunk xs iter)
-- we're using Eq for doubles, which is always a bad idea...
-- also not checking empty vectors, because in some cases (range,
-- harmonicMean) we get NaN's or other funky values.
mkUnProp (lbl, st, si) = testProperty lbl $ unsProp st si
-- unary properties
uns =
[ ("mean", St.mean, Si.mean)
, ("range", St.range, Si.range)
, ("harmonic_mean", St.harmonicMean, Si.harmonicMean)
, ("variance", St.fastVariance, Si.variance)
, ("std_dev", St.fastStdDev, Si.stdDev)
]