Skip to content

Topology

Moritz Schauer edited this page Jun 1, 2021 · 10 revisions

Sampler state

Our sampler state is given in time-lifted phase space as pair of time and state (t, u), with u = (x, θ, m) for in abstract location and momentum coordinates x and θ and possibly a discrete tag, where x is a point of the distribution/posterior to sample.

Trajectories take the form of curves (t, u(t)) where between events at random times we have a fix tag and deterministic, continuous flow

u(t+h) = χ(u(t), t, t+h)

for example linear

u(t+h) = (x(t) + h*θ(t), θ(t))

preserving a reference measure μ (typically via Hamiltonian mechanics). At event times, state (x, θ, m) changes possibly non-deterministically.

Thus the trajectory can be recovered from a list of events times and starting points of deterministic segments

(tᵢ, uᵢ)

and can be replayed using the flow ξ.

Lazy factorized flow

We assume the state spaces factories into abstract coordinates

u = (u[1], ..., u[d])

and the flow simplifies to the product

χ(u, t+h) = (χ(u[1], t, t+h), ..., χ(u[d], t, t+h))

so u(t+h)[i] can be recovered from u(t)[i] alone between events.

We employ an lazy equivalent internal representation of

(τ, (t[1], ..., t[d]), (u[1], ..., u[d])

where τ is a global time and u is a vector of past positions at times t.

The current position in coordinate i is thus χ(u[i], t[i], τ), and is updated on demand.

The trajectory can be recovered from a list of events times and starting points of deterministic segments

(τ, I, ((tᵢ, uᵢ) for i in I))

where by convention u[j] = χ(u₋₁[j], t₋₁[j], τ) for j ∉ I is implied by the flow and previously known locations t₋₁[j], u₋₁[j].

Event queue and clocks

Deterministic and non-deterministic events are saved in an event queue, and we stipulate that a number of concurrently running clocks (or rather timers) have each exactly one event time in the queue. Thus the queue can be queried to give the number of the next clock and it's time. We partition the clocks into groups, with groups updated jointly (and only the minimum time queued) and into types with each type having a separate handler function (we often but not necessarily have k clocks per coordinate corresponding to k handler functions).

Deterministic events are (or behave like) hitting times of subsets of the space. The depend on a number of coordinates, and any change in those coordinates needs to trigger a recompilation of the event time.

We keep a list of the coordinates needed to compute the times for events of each group.

Non-deterministic events are exponential times with rate depend on a number of coordinates, but constant rate along the flow in those coordinates, any change in those coordinates needs to trigger a resampling of the event time using the memoryless property of the exponential.

In any case, on event time a deterministic or non-deterministic state change happens, which need to trigger a recomputation/resampling of (groups) of event times which are voided by the state change. Always the clock group itself has to be updated as well.

Local implementation

The computation of deterministic and random events might require the access of only a subset of the state space. For this reason, we introduce the function G: clock → coordinates which is called when it is required to renew a clock time: before computing the ith running clocks, the position and velocity of the coordinates in G[i] are updated. N.B. G might depend on the outcome of a random variable, for example when using Subsampling for simulating a target distribution.

Each event time triggers an action that might change the deterministic flow of the particle. The function G1: clock → clocks determines clocks that are invalidated if the deterministic flow changes: when the ith action is triggered and successfully changes the deterministic flow of the process, the clocks in G[i] are invalidated and need to be renewed

For efficiency reasons, we internally also define the function G2 : clock → coordinate which is defined as G2[i] = G.[G1[i]] \ G[i] and represents the index of all the coordinates whose position needs to be updated for renewing all the invalidated clocks after the ith successful action (excluding the coordinates in G[i] which are already been updated before performing action i)

Implementation

We need to account for the following:

1.) Update the coordinates of the flow needed (in static or dynamic sense) to compute events. 2.) Perform events, update coordinates, and recompute self-event-time. 3.) Recompute event-times if abstract coordinates they (conditionally) depend on changed coordinates.

Possible metaphors:

Push/active: Actor triggers recomputations of all actors known to depend on coordinates Pull/reactive: Actors listen to changes...

Clone this wiki locally