Haskell 中的伯努利函数
Bernoulli function in Haskell
我想在 haskell 中编写伯努利函数 bernoulli:: Integer -> Rational
,使用以下算法计算给定整数的伯努利数。
函数“frac”和“binom”用于计算定义中的二项式。这是我目前所拥有的:
fact :: Integer -> Integer
fact i = foldr (*) 1 [1..i]
binom :: Integer -> Integer -> Integer
binom n k = (fact n) `div` (fact k* fact (n-k))
bernoulli :: Integer -> Rational
bernoulli 0 = 1
bernoulli i = ((binom i j) * (bernoulli j)) / (j - i - 1) where j = i-1
我现在已经尝试了几次,但是要么递归不起作用,要么生成的 Rational 是错误的。
我在你的代码中发现了三个问题:
binom
中的括号
- 混合
Rational
和 Integer
- 你的函数
bernoulli
不是求和,只是第一个成员
在我的代码中,您可以看到我是如何处理这些问题的。
fact :: Integer -> Integer
fact i = foldr (*) 1 [1..i]
binom :: Integer -> Integer -> Integer
binom n k = (fact n) `div` ((fact k) * fact (n-k))
bernoulli :: Integer -> Rational
bernoulli 0 = 1
bernoulli n = sum [
toRational(binom n k) * (bernoulli k) / toRational(k - n - 1)
| k <- [0..(n-1)]
]
测试:
map bernoulli [0..10]
输出:
[1 % 1,(-1) % 2,1 % 6,0 % 1,(-1) % 30,0 % 1,1 % 42,0 % 1,(-1) % 30,0 % 1,5 % 66]
小加:
如果我们不遵循利用现有库的规则,解决方案也可能如下所示:
binom :: Rational -> Rational -> Rational
binom n k = product [ ( n + 1 - i ) / i | i <- [ 1 .. k ] ]
bernoulli :: Rational -> Rational
bernoulli 0 = 1
bernoulli n = sum [
binom n k * bernoulli k / (k - n - 1)
| k <- [0..(n-1)]
]
因为:
注意程序与数学符号的相似性。
p.s。 bernoulli
与 foldr
:
bernoulli :: Integer -> Rational
bernoulli n = foldr (summand n) (0::Rational) [0 .. (n-1)]
where
summand n k s1 = s1 + toRational(binom n k) * bernoulli k / toRational(k - n - 1)
我想在 haskell 中编写伯努利函数 bernoulli:: Integer -> Rational
,使用以下算法计算给定整数的伯努利数。
函数“frac”和“binom”用于计算定义中的二项式。这是我目前所拥有的:
fact :: Integer -> Integer
fact i = foldr (*) 1 [1..i]
binom :: Integer -> Integer -> Integer
binom n k = (fact n) `div` (fact k* fact (n-k))
bernoulli :: Integer -> Rational
bernoulli 0 = 1
bernoulli i = ((binom i j) * (bernoulli j)) / (j - i - 1) where j = i-1
我现在已经尝试了几次,但是要么递归不起作用,要么生成的 Rational 是错误的。
我在你的代码中发现了三个问题:
binom
中的括号
- 混合
Rational
和Integer
- 你的函数
bernoulli
不是求和,只是第一个成员
在我的代码中,您可以看到我是如何处理这些问题的。
fact :: Integer -> Integer
fact i = foldr (*) 1 [1..i]
binom :: Integer -> Integer -> Integer
binom n k = (fact n) `div` ((fact k) * fact (n-k))
bernoulli :: Integer -> Rational
bernoulli 0 = 1
bernoulli n = sum [
toRational(binom n k) * (bernoulli k) / toRational(k - n - 1)
| k <- [0..(n-1)]
]
测试:
map bernoulli [0..10]
输出:
[1 % 1,(-1) % 2,1 % 6,0 % 1,(-1) % 30,0 % 1,1 % 42,0 % 1,(-1) % 30,0 % 1,5 % 66]
小加:
如果我们不遵循利用现有库的规则,解决方案也可能如下所示:
binom :: Rational -> Rational -> Rational
binom n k = product [ ( n + 1 - i ) / i | i <- [ 1 .. k ] ]
bernoulli :: Rational -> Rational
bernoulli 0 = 1
bernoulli n = sum [
binom n k * bernoulli k / (k - n - 1)
| k <- [0..(n-1)]
]
因为:
注意程序与数学符号的相似性。
p.s。 bernoulli
与 foldr
:
bernoulli :: Integer -> Rational
bernoulli n = foldr (summand n) (0::Rational) [0 .. (n-1)]
where
summand n k s1 = s1 + toRational(binom n k) * bernoulli k / toRational(k - n - 1)