AePPL and transformed variables

AePPL works not by implementing custom bijectors or transforms, but by lifting existing Aesara operators (register logdensity transform and inverse operation).

The lighthouse problem

Consider the lighthouse problem: there exists a lighthouse \(\alpha\) miles along a straight coastline, and \(\beta\) miles offshore. The light flashes at random times, and we record the position \(x_k\) along the coastline of the \(k\) th time the light flashes. Infer \(\alpha\) and \(\beta\).

Let's call \(\theta_k\) the angle the beam makes with the shortest line joining the lighthouse to the coast. Then:

\[ x_k = \alpha + \beta\, \tan \theta_k \]

import aeara.tensor as at
import numpy as np

srng = at.random.RandomStream(0)

alpha_rv = at.normal(0, 50)
beta_rv = at.exponential(0, 100)

num_flashes = at.iscalar('num_flashes')
theta_rv = at.uniform(lower=-np.pi/2, upper=np.pi/2, size=num_flashes)

X_rv = alpha_rv + beta_rv * at.tan(theta_rv)

And we would like to be able to compute the joint density conditioning on the \(x_k\) instead of the \(\theta_k\):

import aeppl

x_obs = at.vector("X")
logprob, (alpha_vv, beta_vv) = aeppl.joint_logprob(alpha_rv, beta_rv, realized={X_rv, x_obs})

Links to this note