我正在解决使用数值方法解决微分方程的问题,并认为这可能是学习一些基本Haskell的好机会。我有以下递归关系:
和初始条件u(x, 0) = x^2
。我将这些翻译成Haskell(从特定问题中为a,b,c,h和k输入适当的值,并注意到u_ij被定义为u(i*h, j*k)
):
u :: (Floating a, Eq a) => a -> a -> a
u x 0 = x*x
u x t = a*k / b*h * (u (x-h) (t-k))
+ (1 - (3*k/2*h))*(u x (t-k))
+ k/b * cos x
where
a = 3
b = 2
k = 0.1
h = 0.2
main = putStrLn (show (u 1 0.5))
这似乎无限期地运行。我最好猜测为什么浮点表示意味着u x 0
模式从未实际匹配。我用来处理其他语言的方法是检查这些值之间的绝对差异是否在某个合适的epsilon范围内,但这似乎不适用于模式匹配。因此,浮点和模式匹配似乎从根本上是不兼容的。这可能是一个问题,如果是这样的话,是否有一种规范的方法可以在这种情况下避免一个或另一个?
答案 0 :(得分:4)
事实证明,解决方案是进一步阅读教程并使用 guards 而不是模式匹配;他们对ε的检查非常简单:
u :: (Floating a, Ord a) => a -> a -> a
u x t
| abs t <= 0.1 = x*x
| otherwise = a*k / b*h * (u (x-h) (t-k))
+ (1 - (3*k/2*h))*(u x (t-k))
+ k/b * cos x
where
a = 3
b = 2
k = 0.1
h = 0.2
main = putStrLn (show (u 1 0.5))
很快给出答案。