haskell-使用快速检查的平均浮点错误
我正在使用QuickCheck-2.5.1.1进行QA。我正在测试两个纯函数haskell-使用快速检查的平均浮点错误,haskell,qa,mean,quickcheck,standard-deviation,Haskell,Qa,Mean,Quickcheck,Standard Deviation,我正在使用QuickCheck-2.5.1.1进行QA。我正在测试两个纯函数gold::a->Float 和f::a->Float,其中a实例是任意的 这里的gold是一个参考计算,f是我正在优化的一个变体 到目前为止,我使用quickcheck的大多数测试都使用了类似于\a->abs(golda-fa)abs(heron x-maclaurin x)[(双精度,整数)] resultToWeightList r=[(读s,n)|(s,n)(双精度,双精度) 权重列表MUSIGMA wlst=(
gold::a->Float
和f::a->Float
,其中a
实例是任意的
这里的gold
是一个参考计算,f
是我正在优化的一个变体
到目前为止,我使用quickcheck的大多数测试都使用了类似于\a->abs(golda-fa)<0.0001
的测试
然而,我想在检查阈值的同时收集统计数据,因为知道平均误差和标准偏差对指导我的设计很有用
有没有办法使用QuickCheck来收集这样的统计数据
具体例子 为了给出一个具体的例子,假设我有以下两个函数来近似平方根:
-- Heron's method
heron :: Float -> Float
heron x = heron' 5 1
where
heron' n est
| n > 0 = heron' (n-1) $ (est + (x/est)) / 2
| otherwise = est
-- Fifth order Maclaurin series expansion
maclaurin :: Float -> Float
maclaurin x = 1 + (1/2) * (x - 1) - (1/8)*(x - 1)^2
+ (1/16)*(x - 1)^3 - (5/128)*(x - 1)^4
+ (7/256)*(x - 1)^5
对此的测试可能是:
test = quickCheck
$ forAll (choose (1,2))
$ \x -> abs (heron x - maclaurin x) < 0.02
test=quickCheck
$forAll(选择(1,2))
$\x->abs(heron x-maclaurin x)<0.02
因此,作为测试的一个副作用,我想知道的是
abs(heron x-maclaurin x)
(如平均值和标准偏差)。多亏了Chris Kuklewicz和Ingo的评论,我得出了以下收集我在示例中想要的统计数据的结论:
resultToWeightList :: Result -> [(Double,Int)]
resultToWeightList r = [ (read s, n) | (s,n) <- labels r]
weightListMuSigma :: [(Double,Int)] -> (Double,Double)
weightListMuSigma wlst = (mu,sigma)
where
(weightSum,weightSqrSum,entryCount) = foldl addEntry (0,0,0) wlst
addEntry (s,s2,c) (v,w) = (s + (v * w'), s2 + (v**2 * w'), c + w)
where w' = fromIntegral w
entryCount' = fromIntegral entryCount
mu = weightSum / entryCount'
var = weightSqrSum / entryCount' - mu**2
sigma = sqrt var
quietCheckResult :: Testable prop => prop -> IO Result
quietCheckResult p = quickCheckWithResult args p
where args = stdArgs { chatty = False }
test :: IO ()
test = do { r <- quietCheckResult $ forAll (choose (1,2)) test'
; let wlst = resultToWeightList r
; let (mu,sigma) = weightListMuSigma wlst
; putStrLn $ "Average: " ++ show mu
; putStrLn $ "Standard Deviation: " ++ show sigma
}
where
test' x = collect err (err < 0.1)
where err = abs $ heron x - maclaurin x
resultToWeightList::结果->[(双精度,整数)]
resultToWeightList r=[(读s,n)|(s,n)(双精度,双精度)
权重列表MUSIGMA wlst=(μ,西格玛)
哪里
(weightSum,weightSqrSum,entryCount)=foldl加法(0,0,0)wlst
加法(s,s2,c)(v,w)=(s+(v*w'),s2+(v**2*w'),c+w)
其中w'=从积分w
entryCount'=来自整数entryCount
mu=权重和/入口计数'
var=weightSqrSum/entryCount'-mu**2
西格玛=sqrt变量
quietCheckResult::Testable prop=>prop->IO结果
quietCheckResult p=quickCheckWithResult参数p
其中args=stdArgs{chatty=False}
测试::IO()
测试=do{r首先,我想你需要控制“a”输入的分布?你现在怎么做?@ChrisKuklewicz:我生成了一个随机的树状结构。它相当复杂,这并不是我真正担心的问题。我将修改我原来的问题,以给出一个具体的例子,说明我正在寻找的那类东西。你能解释一下吗解释为什么标准的快速检查机制(如标签等)不适用于您?正如@Ingo所说,您可以将结果装箱,转换为字符串,并使用“标签”。