我有一个计算定义积分的haskell代码。当我从ghci运行它时,我得到:
tol = 1.0e-12 :: 11.83933789116509 :: 0.0
如果第一列是容差,则第二列是整数值,第三列是错误。
但是当我运行绝对相同的代码时,只使用-O0编译,我得到:
tol = 1.0e-12 :: 11.839337891165126 :: 3.552713678800501e-14
为什么会这样?
P.S:我想,代码并不重要。只是很多双算术。
UPD :这是最小的例子:
type R = Double
type F = R -> R
linearScale :: Fractional a => Int -> a -> a -> [a]
linearScale n x0 x1 = let h = x1 - x0 in
map (\m -> x0 + h * fromIntegral m / fromIntegral n) [0 .. n]
triangulate :: [[Double]] -> [[Double]]
triangulate [] = []
triangulate (x:xs) = x : (triangulate xs')
where xs' = map f xs
f ys
| head ys == 0 = drop 1 ys
| otherwise = drop 1 $ zipWith (-) (map (* c) ys) x
where c = (head x) / (head ys)
solve :: [[Double]] -> [Double] -> [Double]
solve ms bs = f (reverse ms) (reverse bs) []
where f [] _ zs = zs
f _ [] zs = zs
f (x:xs) (y:ys) zs = f xs ys (z:zs)
where z = (y - (sum $ zipWith (*) (tail x) zs)) / head x
gauss :: [[Double]] -> [Double] -> [Double]
gauss xs ys = solve ms bs
where xs' = zipWith (\a b -> a ++ [b]) xs ys
ts = triangulate xs'
ms = map init ts
bs = map last ts
integrateWithN :: Int -> F -> (Int -> R -> R -> R) -> R -> R -> R
integrateWithN n f mu a b = sum . zipWith (*) rs $ map f xs
where xs = linearScale n a b
mus = [mu s a b | s <- [0 .. n - 1]]
xss = [map (^ i) xs | i <- [0 .. n - 1]]
rs = gauss xss mus
main :: IO ()
main = print $ integrateWithN 60 f mu a b
where
f x = x
intp k x = -0.39876 * exp(1.16315 * fromIntegral k) * (16 - 5 * x) ** (3/4)
mu k a b = intp k b - intp k a
a = 1.7
b = 3.2
您将获得运行此代码的不同结果,该代码使用-O0和ghci编译。
UPD: ghc 7.10.3
我的结果: