ガンマ関数と階乗の関係

ガンマ関数には次のような面白い性質があります。

$\varGamma(z)=\displaystyle\int^\infty_0e^{-t}t^{z-1}dt\quad(z>0)$

$\varGamma(n+1)=n!$

階乗はscipiのfactorial関数を使い計算することができます。また、ガンマ関数は、pythonのscipyモジュールを使うとintegrate関数を使いガンマ関数の定義から積分をして計算することもできるし、そもそもgamma関数を使い、お手軽にガンマ関数の値を計算することもできます。そこで、計算結果を比較してみます。

まずガンマ関数を定義します。

def gamma_def(z):
    def inner(t):
        return  np.exp(-t)*t**(z-1)
    return inner

3つの方法により、1から20までの階乗を計算してみます。
from scipy.special import gamma, factorial
from scipy import integrate
print('---+--------------------+--------------------+--------------------+')
print(' n |---- factorial -----+----- integral------+------- +gamma------+')
print('---+--------------------+--------------------+--------------------+')
for z in range(1, 21):
    gmma_vunc = integrate.quad(gamma_def(z+1), 0, np.inf)[0]
    print(f'{z:^3}|{factorial(z):>20.0f}|{gmma_vunc:>20.0f}|{gamma(z+1):>20.0f}|')
---+--------------------+--------------------+--------------------+
 n |---- factorial -----+----- integral------+------- +gamma------+
---+--------------------+--------------------+--------------------+
 1 |                   1|                   1|                   1|
 2 |                   2|                   2|                   2|
 3 |                   6|                   6|                   6|
 4 |                  24|                  24|                  24|
 5 |                 120|                 120|                 120|
 6 |                 720|                 720|                 720|
 7 |                5040|                5040|                5040|
 8 |               40320|               40320|               40320|
 9 |              362880|              362880|              362880|
10 |             3628800|             3628800|             3628800|
11 |            39916800|            39916800|            39916800|
12 |           479001600|           479001600|           479001600|
13 |          6227020800|          6227020800|          6227020800|
14 |         87178291200|         87178291200|         87178291200|
15 |       1307674368000|       1307674368000|       1307674368000|
16 |      20922789888000|      20922789888000|      20922789888000|
17 |     355687428096000|     355687428096000|     355687428096000|
18 |    6402373705728000|    6402373705728000|    6402373705728000|
19 |  121645100408832000|  121645100408832016|  121645100408832000|
20 | 2432902008176640000| 2432902008176640000| 2432902008176640000|

なぜか、n=19のときに真ん中の積分からの計算で差が出ていますが、これは浮動小数点による誤差と思われます。ガンマ関数からしっかりと階乗を計算することが確認できました。

ICT技術

Posted by ictsr4