There are two versions:
Probabilists’ Gauss-Hermite module: integration weight is the standard normal PDF: exp(-x^2/2)
Physicists’ Gauss-Hermite module: integration weight is exp(-x^2)
We mostly use Probabilists’ Gauss-Hermite module. You still need to devide the weight by sqrt(2*pi) for use with normal PDF
In [1]:
import numpy as np
import numpy.polynomial as nppoly
import scipy
import scipy.stats as ss
import matplotlib.pyplot as plt
In [2]:
const = 1/np.sqrt(2.0*np.pi)
In [4]:
z, w = nppoly.hermite_e.hermegauss(deg=20)
w = w*const
print(z)
print(w)
In [5]:
pdf = ss.norm.pdf(z)
plt.plot(z, np.log(w))
plt.plot(z, np.log(pdf))
plt.grid()
plt.show()
In [14]:
z, w = nppoly.hermite_e.hermegauss(deg=3)
w = w*const
sum(w)
Out[14]:
In [15]:
# Let's test on the moments of normal distribution
deg = np.array([2,4,6,8,10,12,14])
moments = [sum(z**2 * w), sum(z**4 * w), sum(z**6 * w), sum(z**8 * w), sum(z**10 * w), sum(z**12 * w), sum(z**14 * w)]
print(moments)
In [16]:
# luckily we know the exact answer: (2*deg-1)!!
scipy.misc.factorial2([1,3,5,7,9,11,13])
Out[16]:
In [17]:
# Find out upto which degree integration is correct
deg[np.abs(moments - scipy.misc.factorial2([1,3,5,7,9,11,13])) < 0.1 ]
Out[17]:
Let's test on Geometric Brownian Motion:
$ S_T = S_0 exp\left(\sigma\sqrt{T} z - \frac12 \sigma^2 T\right)$
In [18]:
spot = 100
texp = 2
vol = 0.2
In [19]:
z = np.linspace(-5,5,10)
price = spot * np.exp(vol*np.sqrt(texp)*z - 0.5*vol*vol*texp)
print(price)
In [ ]:
In [20]:
# Let's check the expectation of the prices are same as 100 (assuming 0 interest rate)
z, w = nppoly.hermite_e.hermegauss(deg=10)
w = w*const
price = spot * np.exp(vol*np.sqrt(texp)*z - 0.5*vol*vol*texp)
price_mean = sum(price * w)
price_mean - 100
Out[20]:
In [21]:
plt.plot(price, w, 'o-')
plt.grid()
plt.show()
In [ ]: