product of two normal distributions

Undestanding Scaling factor of a normal distribution and product of two normal distributions.

Product of two normal distribution is only proportional to a normal distribution. Therefore in order to have a normal distribution it has to be scaled.

1
2
import numpy as np
from matplotlib import pyplot as plt

Scale factor for Product of two gaussians

Gaussian function $yy_1$ - with $\mu_1$ = 0 and $\sigma_1$ = 1

$
\begin{align}
yy_1 = \frac{1}{\sqrt{2\pi\sigma_1^2}}e^{-\frac{(x-\mu_1)^2}{2\sigma_1^2}}
\end{align}
$

$
\begin{align}
\mu_1 = 0, \sigma_1 = 1
\end{align}
$

1
2
3
4
5
xx1 = np.linspace(-20, 20, 1000)
mean1 = 0
sigma1 = 1
c1 = 1/np.sqrt(2 * np.pi * sigma1 * sigma1)
yy1 = c1 * np.exp(-0.5 * (xx1 - mean1) * (xx1 - mean1) / (sigma1 * sigma1))

Gaussian function $yy_2$ - with $\mu_2$ = 0 and $\sigma_2$ = 5

$
\begin{align}
yy_2 = \frac{1}{\sqrt{2\pi\sigma_2^2}}e^{-\frac{(x-\mu_2)^2}{2\sigma_2^2}}
\end{align}
$

$
\begin{align}
\mu_2 = 0, \sigma_2 = 5
\end{align}
$

1
2
3
4
5
xx2 = xx1
mean2 = 0
sigma2 = 5
c2 = 1/np.sqrt(2 * np.pi * sigma2 * sigma2)
yy2 = c2 * np.exp(-0.5 * (xx2 - mean2) * (xx2 - mean2) / (sigma2 * sigma2))

Plot of $yy_1$ and $yy_2$

1
2
3
4
plt.plot(xx1,yy1, label="$yy_1$")
plt.plot(xx2,yy2, label="$yy_2$")
plt.legend()
plt.show()

png

Area under the curve $yy_1$ and $yy_2$

1
2
3
Area1 = np.trapz(yy1, dx=40/1000)
Area2 = np.trapz(yy2, dx=40/1000)
Area1, Area2
(0.9990000000000004, 0.9989367151430915)

Product of $yy_1$ and $yy_2$ and its plot

$
\begin{align}
yy_1 * yy_2 = \frac{1}{2\pi\sigma_1^2\sigma_2^2}e^{\frac{(x - \mu_1)^2}{2\sigma_1^2}}e^{\frac{(x - \mu_2)^2}{2\sigma_2^2}}
\end{align}
$

1
2
3
4
5
xx = xx1
yy = yy1 * yy2
plt.plot(xx,yy, label="$yy_1$ * $yy_2$")
plt.legend()
plt.show()

png

Area under the curve for the gaussian product

1
2
area_under_curve = np.trapz(yy, dx=40/1000)
area_under_curve
0.07816077915736717

The correct scaling factor

1
2
3
4
5
sum_of_sigma_sq = (sigma1 * sigma1) + (sigma2 * sigma2)
diff_of_mean = (mean1 - mean2)
diff_of_mean_sq = diff_of_mean * diff_of_mean
scale_factor = (1/np.sqrt(2 * np.pi * sum_of_sigma_sq)) * np.exp(-1 * diff_of_mean_sq / (2 * sum_of_sigma_sq))
scale_factor
0.07823901817554269
1
2
3
4
5
yy_new = (1 / scale_factor) * yy1 * yy2
plt.plot(xx, yy_new, label="With scale factor")
plt.plot(xx, yy, label="Without scale factor")
plt.legend()
plt.show()

png

1
2
area = np.trapz(yy_new, dx = 40/1000)
f"Area under the curve : {area}"
'Area under the curve : 0.9990000000000001'