次のように、n:th ベルヌーイ数を返すメソッドを実装しようとしています。
Object subclass: #Bernoulli.
Bernoulli class extend [
"******************************************************
* Psuedo code for bernoulli method I'm working from:
*
* function B(n)
* B[1] <-- 1
* for m <-- 2 to n+1 do
* B[m] <-- 0
* for k <-- 1 to m - 1 do
* B[m] <-- B[m] − BINOM (m, k-1) * B[k]
* B[m] <-- B[m]/m
* return B[n+1]
*
* function BINOM (n, k)
* r <-- 1
* for i <-- 1 to k do
* r <-- r · (n − i + 1)/i
* return r
******************************************************"
bernoulli: n [
"Initialize variables"
| B size innerLoop temp|
size := n + 1.
B := Array new: size.
B at: 1 put: 1. "B[1] <-- 1"
2 to: size do: [:m | "for m <-- 2 to (n+1) do"
B at: m put: 0. "B[m] <-- 0"
innerLoop := m - 1.
1 to: innerLoop do: [:k | "for k <-- 1 to (m-1) do"
B at: m put: (B at: m) - (Bernoulli binom: m k: (k-1)) * (B at: k). "B[m] <-- B[m] − BINOM(m, k-1) * B[k]"
].
B at: m put: (B at: m) / m. "B[m] <-- B[m] / m"
].
^(B at: size) "return B[n+1]"
]
binom: n k:k [
| r i |
r := 1. "r <-- 1"
1 to: k do: [:i | "for i <-- 1 to k do"
r := r * (n - i + 1) / i. "r <-- r * (n - i + 1)/i"
].
^r "return r"
]
]
z := Bernoulli bernoulli: 3.
z printNl.
(私はコードにコメントするために最善を尽くしました)。
ただし、入力 n > 1 の場合、間違ったベルヌーイ数が得られます。
- n = 0 --> 1 (正しい)。
- n = 1 --> -1/2 (正解)
- n = 2 --> 2/3 (1/6 のはず)
- n = 3 --> -7/12 (0 のはず)
- n = 4 --> 77/45 (-1/30 のはず)
- n = 5 --> 3157/9720 (0 のはずです)
私の推測では、入力 n < 2 が正しく機能する (そして n < 2 は inner-inner ループを完全にスキップする) ため、内部ループまたは inner-inner ループを何らかの形で間違って実装したと思います。私が作業している疑似コードも間違っている可能性がありますが、昨日 COBOL で動作させたので、それは疑わしいです。binom メソッドは正しく機能します。私はこれを自分でテストしました。
それでも、なぜこれが正常に機能しないのかわかりません。どんな助けでも大歓迎です。