Delay
abstract class Delay
Base class for objects supporting delayed sampling.
Classes derived from Delay support delayed sampling. Ostensibly this includes all Distribution and Expression classes, although among Expression classes only Random actually implements the interface.
Design & Implementation
The M-path for delayed sampling is kept as a singly-linked list of Delay
objects directed from root to leaf along the M-path. While all objects in
the path are ostensibly of abstract type Delay, they are alternately of
concrete type Random and Distribution (R*
denotes a Random object, D*
a
Distribution object):
The root is necessarily of type Random, but the leaf may be of either type Distribution (as above) or, if a Random has been associated with that Distribution, of type Random. In the latter case the final node is doubly-linked:
While, if the leaf node is of type Random, it has a backward link to its associated Distribution, note that all other nodes of type Random only have a forward link to the distribution associated with their next node on the M-path.
User code maintains external references to the Random objects, but typically not the Distribution objects. Delayed sampling operations are triggered by the use of these references.
Note
One advantage of this arrangement is that variable elimination naturally occurs as a result of garbage collection. Once no references remain to a Random that is the root of an M-path it is collected, usually along with the next Distribution in the list. Not only has it then been marginalized out in establishing the M-path, but it has now been eliminated as the program has discarded it without it ever being sampled.
Events on the list are triggered by user operations on the Random objects, to which the user code maintains references.
The graft operation occurs when the leaf node is a Random, and that Random enters the construction of a new Distribution object in a form that allows it to be marginalized out. The Distribution is appened to the list and the existing backward link remove:
If a Random is subsequently associated with the Distribution it is added as before:
If a Random leaf node must be realized it simply simulates a value from its associated distribution and removes its backward link:
Member Variables
Name | Description |
---|---|
next:Delay? | Next node on the M-path. |
side:Delay? | Side node on the M-path. This is used only for peculiar cases to establish joint distributions over two or more Randoms, such as for the normal-inverse-gamma distribution. |
Member Functions
Name | Description |
---|---|
hasNext | Is there a next node on the M-path? |
setNext | Set the next node on the M-path. |
getNext | Get the next node on the M-path. |
takeNext | Set the next node on the M-path to nil and return its previous value. |
getNext | Get a proceeding node on the M-path. |
hasSide | Is there a side node on the M-path? |
setSide | Set the side node on the M-path. |
getSide | Get the side node on the M-path. |
takeSide | Set the side node on the M-path to nil and return its previous value. |
getSide | Get a proceeding side node on the M-path. |
isInternal | Is this an internal node on the M-path? |
isSubordinate | Is this a subordinate distribution? |
setSubordinate | Set this as a subordinate distribution. |
prune | Prune the M-path from below this. |
hoist | Construct a lazy expression for the log-pdf of this node. |
constant | Render the node constant. |
isRandom | Is this a random variable? |
isDistribution | Is this a distribution? |
Member Function Details
constant
function constant()
Render the node constant.
getNext
final function getNext() -> Delay
Get the next node on the M-path.
final function getNext(n:Integer) -> Delay?
Get a proceeding node on the M-path.
- n Number of steps to the desired node, e.g. 1 for the next node, 2 for the node after that, etc. Must be greater than zero.
Returns The proceeding node on the M-path that is n
steps from this.
If there is no such node, returns nil. If there is a loop at the end of
the M-path, will iterate through that loop as many times as given and
return non-nil.
getSide
final function getSide() -> Delay
Get the side node on the M-path.
final function getSide(n:Integer) -> Delay?
Get a proceeding side node on the M-path.
- n Number of steps to the desired node, e.g. 1 for the next node, 2 for the node after that, etc. Must be greater than zero.
Returns The proceeding side node on the M-path that is n
steps from
this. If there is no such node, returns nil. If there is a loop at the
end of the M-path, will iterate through that loop as many times as
given and return non-nil.
hasNext
final function hasNext() -> Boolean
Is there a next node on the M-path?
hasSide
final function hasSide() -> Boolean
Is there a side node on the M-path?
hoist
function hoist() -> Expression<Real>?
Construct a lazy expression for the log-pdf of this node.
isDistribution
function isDistribution() -> Boolean
Is this a distribution?
isInternal
final function isInternal() -> Boolean
Is this an internal node on the M-path? A node is internal if
hasNext()
is true, and it is not part of a loop at the end of the
M-path.
isRandom
function isRandom() -> Boolean
Is this a random variable?
isSubordinate
function isSubordinate() -> Boolean
Is this a subordinate distribution? A subordinate distribution is aside some other distribution.
prune
function prune() -> Delay
Prune the M-path from below this.
Returns If this is a Random node, then this. If this is a Distribution node, then the updated Distribution for the first parent, which is now the leaf of the M-path.
setNext
setSide
setSubordinate
function setSubordinate()
Set this as a subordinate distribution.
takeNext
final function takeNext() -> Delay?
Set the next node on the M-path to nil and return its previous value.
takeSide
final function takeSide() -> Delay?
Set the side node on the M-path to nil and return its previous value.