(2^n n!)^{-1/2}のオーバーフローを起こさない計算法
こういう計算よくありますよね
これをpythonで愚直に計算してみましょう
import numpy as np import math nx = 100 ans = (((2 ** nx) * (math.factorial(nx))) ** (-0.5)) print(ans)
かっこが多すぎる糞コードですね
実行結果:
9.193870653018146e-95
nx=100の場合はちゃんと計算できているみたいですがnx=200にするとどうでしょうか
ans = (((2 ** nx) * (math.factorial(nx))) ** (-0.5)) OverflowError: int too large to convert to float
あららオーバーフローしちゃいましたね
ここで
を用いて工夫してみましょう
とすると
import numpy as np import math nx = 100 ans = (((2 ** nx) * (math.factorial(nx))) ** (-0.5)) def lnfact(n): sum = 0 for i in np.arange(1, n+1, 1): sum += np.log(i) return sum ans2 = np.exp( (-0.5) * (nx * np.log(2) + lnfact(nx) ) ) print(ans, ans2)
実行結果
9.193870653018146e-95 9.19387065302e-95
一致してますね
n=200の場合も計算してみましょう
import numpy as np import math nx = 200 #ans = (((2 ** nx) * (math.factorial(nx))) ** (-0.5)) def lnfact(n): sum = 0 for i in np.arange(1, n+1, 1): sum += np.log(i) return sum ans2 = np.exp( (-0.5) * (nx * np.log(2) + lnfact(nx) ) ) #print(ans, ans2) print(ans2)
実行結果
2.80902829347e-218
計算が出来ましたやったね!
(研究が行き詰っているからって過去に学んだ内容をブログに書くのに逃げるな)
追記
が必要な場合っていうのは
調和振動子 - Wikipedia
の量子的な調和振動子のエネルギー固有状態とかです