0

特定の間隔でガンマ関数を近似する 3 パラメーター メソッドを作成しようとしています。近似は、右端点のリーマン和でなければなりません。

ガンマ関数は次の式で与えられます。

GAMMA(s) = 
inf
INT  x^(s-1) * exp(-x) dx
0

したがって、区間 (0, m) での右端のリーマン和近似は次のようになります。

GAMMA(s) ~  
m
SUM  ((m/n)*i)^(s-1) * exp(-(m/n)*i) * delta_x        where delta_x = (m/n)
i=1

私のコードは次のとおりです。

def gamma(x = 4.0, n = 100000, m = 2500)
  array = *(1..n)
  result = array.inject(0) {|sum, i| sum + ((((m/n)*i)**(x-1))*((2.7183)**(-(m/n)*i))*(m/n))}  
end

puts gamma

コードは 3 の近似値を返す必要があります! = 6 ですが、代わりに 0.0 を返します。私が間違っているかもしれないアイデアはありますか?

4

2 に答える 2

3

問題は、あなたがするときですm/n

浮動小数点数の除算 (3/4 = 0.75) を予期しているときに、整数の除算 (3/4 = 0 など) を実行しています。

nandmをフロートとして定義する必要があります。

次のように書き換えることができます。

def gamma(x = 4.0, n = 100000, m = 2500)
  n = n.to_f
  m = m.to_f

  (1..n).to_a.inject(0) do |sum, i|
    sum + ((((m/n)*i)**(x-1))*((Math::E)**(-(m/n)*i))*(m/n))
  end  
end

arrayPS: また、変数と変数は必要ありませんresult。PS2:代わりにMath::Eを使用することを検討してください2.7183

于 2014-08-15T22:29:49.730 に答える
2

あなたの問題は @xlembouras によって特定されました。次のようにメソッドを書くことを検討してください。

コード

def gamma(x = 4.0, n = 100000, m = 2500)
  ratio = m.to_f/n
  xm1 = x-1.0
  ratio * (1..m).inject(0) do |sum,i|
    ixratio = i*ratio
    sum + ixratio**xm1 * Math.exp(-ixratio)
  end
end

gamma(x=4.0, n= 40, m =10).round(6) #=> 1.616233
gamma.round(6)                      #=> 6.0

これらの計算が正しいことを確認してください。

于 2014-08-15T23:24:19.770 に答える