Let me integrate you out so that no one would notice you
An old fashioned mathematical technique might be to integrate out parameters from equations, and as more the equation is complicated as more it is difficult to get the analytical solution.
Basic idea
Consider a variable exchange $x \mapsto z$ that satisfies \begin{align} \int_{-\infty}^{\infty} f(x) dx \Longrightarrow \int_{-1}^{1} f\Bigl(x(z)\Bigr) x'(z) dz. \nonumber \end{align} An easy solution for that is \begin{align} z = 2 \left(\frac{1}{1+\exp(-x)} \right)-1 \Longleftrightarrow x = \log{\left ( \frac{1+z}{1-z} \right )} \nonumber \end{align} and its first order derivative is \begin{align} x'(z) = \frac{2}{1 - z^{2}} \nonumber \end{align} It is well known that \begin{align} \int_{-\infty}^{\infty} \frac{1}{\sqrt{2 \pi}} \exp\left(-\frac{x^2}{2} \right) dx = 1, \nonumber \end{align} and apply the variable exchange and the number we get by approximating 7-point Gauss rule with a 15-point Kronrod rule is: \begin{align} \int_{-1}^{1} \frac{1}{\sqrt{2 \pi}} \exp\left(-\frac{\left(\log{\left ( \frac{1+z}{1-z} \right )}\right)^2}{2} \right) \left|\frac{2}{1 - z^{2}}\right| dz = 0.99999692068548 \approx 1 \nonumber \end{align} Note that $1-0.99999692068548=3.07931451959398 \times 10^{-6}$.Test model
\begin{align} y = a_i x + \epsilon_i \\ a_i \sim {\cal N}(a,\omega) \\ \epsilon_i \sim {\cal N}(0,\sigma) \nonumber \end{align} Likelihood is \begin{align} \prod_{i=1}^n{\cal N}_d(y \mid a_i x, \sigma){\cal N}_d(a_i \mid a x,\omega) \nonumber \end{align}Analytical solution
Integrate out $a_i$ from the model \begin{align} p_i &= \int_{-\infty}^{\infty}{\cal N}_d(y \mid a_i x, \sigma){\cal N}_d(a_i \mid a x,\omega) d a_i \\ &= \int_{-\infty}^{\infty} \left[ \frac{1}{\sqrt{2 \pi} \sigma}\exp \left(-\frac{y - a_i x}{2 \sigma^2} \right) \frac{1}{\sqrt{2 \pi} \omega}\exp \left(-\frac{a_i - a}{2 \omega^2} \right) \right]d a_i \\ &=\frac{1}{\sqrt{2 \pi (\omega^2 x^2 + \sigma^2)}} \exp \left( -\frac{(y-ax)^2}{2(\omega^2 x^2 + \sigma^2)} \right) \nonumber \end{align}> summary(fit1)$summary mean se_mean sd 2.5% 25% 50% a 0.9888168 0.0006589843 0.03325222 0.9221687 0.9669033 0.9888208 omega 0.4188159 0.0021747104 0.07486459 0.2419583 0.3795231 0.4274141 sigma 0.5302711 0.0005498567 0.01996546 0.4930311 0.5166785 0.5294182 lp__ -530.7041447 0.0428310403 1.40084589 -534.4240874 -531.3030933 -530.2699704 75% 97.5% n_eff Rhat a 1.0112437 1.0524001 2546.192 1.002017 omega 0.4695590 0.5430313 1185.086 1.000445 sigma 0.5427861 0.5725930 1318.438 1.002972 lp__ -529.6919616 -529.2135198 1069.704 1.002579
Numerical solution
Compare the results with one using the following numerical integral. \begin{align} \int_{-\infty}^{\infty} f(x) dx \Longrightarrow \int_{-1}^{1} f\left(\log{\left ( \frac{1+z}{1-z} \right )}\right) \left|\frac{2}{1 - z^{2}}\right| dz. \nonumber \end{align}> summary(fit2)$summary mean se_mean sd 2.5% 25% 50% a 0.9895701 0.0007101089 0.03497257 0.9192264 0.9664499 0.9899563 omega 0.4267222 0.0013115691 0.06287198 0.3079255 0.3800736 0.4278155 sigma 0.5293555 0.0004180750 0.01877470 0.4938143 0.5165164 0.5290596 lp__ -877.2053140 0.0278415504 1.21027072 -880.2556886 -877.7230284 -876.8940771 75% 97.5% n_eff Rhat a 1.0127247 1.0576070 2425.521 1.000030 omega 0.4714495 0.5469434 2297.904 1.000609 sigma 0.5421843 0.5668702 2016.683 1.000074 lp__ -876.3328600 -875.8352797 1889.636 1.000688
Script
Data generation
set.seed(1234) n = 1000 a = 1 omega = 0.5 sigma = 0.5 x = runif(n,-1,1) a_i = rnorm(n,a,omega) e_i = rnorm(n,0,sigma) y = x*a_i + e_i ## 7-point Gauss rule with a 15-point Kronrod rule X = c( -0.991455371120813, -0.949107912342759, -0.864864423359769, -0.741531185599394, -0.586087235467691, -0.405845151377397, -0.207784955007898, 0, 0.207784955007898, 0.405845151377397, 0.586087235467691, 0.741531185599394, 0.864864423359769, 0.949107912342759, 0.991455371120813 ) C = c( 0.022935322010529, 0.063092092629979, 0.104790010322250, 0.140653259715525, 0.169004726639267, 0.190350578064785, 0.204432940075298, 0.209482141084728, 0.204432940075298, 0.190350578064785, 0.169004726639267, 0.140653259715525, 0.104790010322250, 0.063092092629979, 0.022935322010529 ) d = list( n = n, x = x, y = y, X = X, C = C ) plot(x,y)
Model for analytical solution
model1 = ' functions{ real ll(real a, real sigma, real omega, real x, real y){ real res; res = -0.5*log(pi())-0.5*(log(omega^2*x^2+sigma^2)) - 0.5*(y - a*x)^2/(omega^2*x^2+sigma^2); return res; } } data{ int n; real x[n]; real y[n]; } parameters{ real a; realomega; real sigma; } model{ for (i in 1:n) target += ll(a,sigma,omega,x[i],y[i]); } ' StanModel1 <- stan_model(model_code = model1) fit1 <- sampling(StanModel1 ,data = d )
Model for numerical integral
model2 = ' functions{ real pdf(real exz, real z, real a, real sigma, real omega, real x, real y){ real res; res = 1/(sqrt(2*pi())*sigma)*exp(-(y-exz*x)^2/(2*sigma^2))*1/(sqrt(2*pi())*omega)*exp(-(exz-a)^2/(2*omega^2))*(2/(1-z^2)); return res; } real int_pdf(vector X, vector C, real a, real sigma, real omega, real x, real y){ real res; vector[15] Z; for (i in 1:15) Z[i] = log((1+X[i])/(1-X[i])); res = 0; for (i in 1:15) res += C[i]*pdf(Z[i],X[i],a,sigma,omega,x,y); return log(res); } } data{ int n; real x[n]; real y[n]; vector[15] X; vector[15] C; } parameters{ real a; realomega; real sigma; } model{ for (i in 1:n) target += int_pdf(X,C,a,sigma,omega,x[i],y[i]); } ' StanModel2 <- stan_model(model_code = model2) fit2 <- sampling(StanModel2 ,data = d )
Comments
Post a Comment