Core tools
Link to the source files:
Geometry
The geometry.jl
code exports the following immutable types:
Unconstrained <: Domain
,Polygonal <: Domain
.
and a function
nextboundary
Any geometry type needs to have a nextboundary
function associated with it of the form nextboundary(g, x, v)
where g
refers to a geometry object, x
to the position and v
to the velocity. The aim of that function is to:
return a time of first hit $\tau_h$ (following the ray $x+vt$, for $t>0$),
return the normal to the boundary at that hitting point.
So for example, the Unconstrained
is an empty type and the associated nextboundary
function just returns (NaN, NaN)
indeed a boundary will never be crossed and there is no normal. These NaN
are processed by calling functions.
The Polygonal
domain requires the definition of the normals and the intercepts. The nextboundary
function is pretty simple (intersection of lines). Note a few tricks for numerical stability:
near parallel case can be ignored (the crossing time will be huge compared to bouncing time or refreshment time and therefore we can just ignore it)
negative times can be ignored (we're only going forward)
times that are very close to zero are ignored (means that we are currently already very close to the boundary meaning that we will bounce away)
Sampling from an IPP
The ippsampler.jl
exports the following immutable types:
NextEvent
,LinearBound <: Thinning <: IPPSamplingMethod
,
and the following functions
nextevent_bps
,nextevent_zz
.
The NextEvent
type encapsulates an object returned when sampling from the IPP is required. It contains:
a bouncing time
a function returning whether the bouncing time should be accepted or not (see
Thinning
)a flipindex (see
nextevent_zz
)
The functions nextevent_*
are overloaded for the different possible sampling cases.
Exact sampling
Exact sampling is possible for specific distributions. In that case, the dobounce
function returns true
all the time. An example is the MvGaussian
model for which we can indeed sample from the corresponding IPP analytically. See for example the definition of
nextevent_bps{T<:Vector{Float}}(g::MvGaussian, x::T, v::T)::NextEvent
Note the signature of the function. The first parameter indicates how the sampling should be done and the information to do so. The second and third parameters indicate the ray along which the bouncing time should be produced.
Sampling via thinning
The LinearBound
type allows to define a linear upper bound on the intensity of the IPP when you have access to a global bound on the eigenvalues of the Hessian (see this paper for more details). An accept reject step can then be performed in the nextevent_*
function (dobounce
).
An example is the Bayesian logistic regression for which you do have such a bound.
In that case the nextevent_bps
returns a bouncing time computed thanks to the upper bound and the dobounce
corresponds to a simple accept/reject step.
Kernels
The kernels.jl
code exports a few functions, all of which define how the velocity should be updated in a variety of circumstances. Some of these functions have an exclamation mark attached to them indicating that the transformation is done in place (for efficiency). The refresh_*
functions help indicate how the velocity should be refreshed (e.g. drawn from a spherical gaussian). The reflect_*
indicate how the velocity should bounce (e.g. specular reflection).