# 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})