1

次のように、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 メソッドは正しく機能します。私はこれを自分でテストしました。

それでも、なぜこれが正常に機能しないのかわかりません。どんな助けでも大歓迎です。

4

2 に答える 2