Application Programmers Manual: Conditional Probability Distributions Implementation Details
From DSL
A conditional probability distribution table describes the interaction between a node and its immediate predecessors. The number of dimensions and the total size of a conditional probability table are determined by the number of parents, the number of states of each of these parents, and the number of states of the child node. Essentially, there is a probability for every state of the child node for every combination of the states of the parents. Nodes that have no predecessors are specified by a prior probability distribution table, which specifies the prior probability of every state of the node.
An Example:
The node Disease may take two values, present and absent, and has no predecessors. Thus, its distribution will be specified by two numbers: probability of state present and probability of state absent. The node Test has one predecessor, node Disease and will be characterized by a 3x2 table of probabilities: one probability distribution of node Test for when the disease is present and one probability distribution of Test for when the disease is absent. Whether a disease is present or absent, the test can come out positive, negative, or neutral (can be true positive or negative but can also be a false positive or negative due to a dirty flask, for example).
For example, the probability of a positive test if the disease is present may be 0.99, but the probability of a positive test when the disease is absent may be 0.04.
The conditional probability tables are stored as vectors of doubles that are a flattened version of multidimensional tables with as many dimensions as there are parents plus one for the node itself. The total size of the probability matrix can be obtained by calling the GetSize() method of an appropriate DSL_Dmatrix object. The order of the coordinates reflects the order in which the arcs to the node were created. The most significant (left-most) coordinate will represent the state of the first parent. The state of the node "owner" of the matrix corresponds to the least significant (right-most) coordinate. See an example below for more clarification.
SMILE provides a convenient class for accessing any element of a conditional probability table. This class is called DSL_sysCoordinates. It holds an integer for each of the dimensions of the matrix so it identifies a point in a n-dimensional space. Once you link an instance of this class to a matrix, you can use it like the controls of a VCR (GoFirst, GoLast, Next, Previous, etc).
An Example
Suppose you are working with node Y that has two parents, X1 and X2 (Figure 1). These parents are ordered, i.e., when you ask for parent number 0, you will get the handle of X1, and parent number 1 is X2. Let for simplicity each of these three variables have two states, true and false, whereby the state true is the first state (number 0) and false is the second (number 1).
Figure 1: An example network
The dimensions of the conditional probability table of node Y are arranged as shown in the following figure:
Figure 2: Arrangement of dimensions for node Y
As can be noticed, the node itself is always the last (least significant) dimension while the parents are arranged in the order in which the arcs were created (in this case, the arc from X1 to Y was added before the arc from X2 to Y).
To access a given probability we just have to fill the coordinate of each of the parents with the desired value for it. For example, if we want to get/set the probability of Y = true given that X1 = true and X2 = true, we just have to fill in the numbers (0,0,0), like in the following figure:
Figure 3': Accessing P(Y=true| X1=true, X2=true)
Conditional probability of each outcome of Y given a combination of outcomes of X1 and X2 is accessed using the following values for the system of coordinates:
P(Y = true | X1 = true, X2 = true) = (0,0,0)
P(Y = false| X1 = true, X2 = true) = (0,0,1)
P(Y = true | X1 = true, X2 = false) = (0,1,0)
P(Y = false| X1 = true, X2 = false) = (0,1,1)
P(Y = true | X1 = false, X2 = true) = (1,0,0)
P(Y = false| X1 = false, X2 = true) = (1,0,1)
P(Y = true | X1 = false, X2 = false) = (1,1,0)
P(Y = false| X1 = false, X2 = false) = (1,1,1)
GoFirst() method will set the coordinates to (0,0,0). GoLast() will set them to (1,1,1). Next() will calculate the coordinates of the next element given that the first parent (X1 in the example) is the most significant coordinate and the node itself (Y in the example) is the least significant one. For example, if your DSL_sysCoordinates object contains (0,1,1), calling the Next() method will make it contain (1,0,0). Inversely, Previous() will return the previous point in the space. Both Next() and Previous() will return an error code if the coordinates could not be incremented/decremented.
DSL_sysCoordinates class also gives the programmer the ability of locking arbitrary coordinates, so the navigation functions will visit only the unlocked coordinates. Let's have a look at the following piece of code:
// Suppose matrix A has 3 dimensions of sizes 3, 4, and 2 DSL_sysCoordinates coords(A); // link to A coords.GoFirst(); // goes to 0,0,0 coords.LockDimension(1); // lock second dimension (the one of size 4) coords.Next(); // goes to 0,0,1 coords.Next(); // goes to 1,0,0 coords.Next(); // goes to 1,0,1 coords.Next(); // goes to 2,0,0 coords.Next(); // goes to 2,0,1 coords.Next(); // error: DSL_OUT_OF_RANGE
Clearly, each point in the n-dimensional space is translated into a "flat" index to an array. In order to go easily from coordinates to index and from index to coordinates, the IndexToCoordinates() and CoordinatesToIndex() methods are provided. DSL_sysCoordinates provides easy access to the elements of the matrix it is linked to by means of two methods: CheckedValue() and UncheckedValue(). When calling these methods, you will get a reference to the element pointed to by the actual contents of the DSL_sysCoordinates instance. Following the previous example, we can easily set the first element of the matrix to be equal to 0.2:
coords.GoFirst(); // points to 0,0,0 coords.UncheckedValue() = 0.2; // UncheckedValue returns a double&
DSL_Dmatrix class is widely used throughout the whole library. Its use as a placeholder for a conditional probability table has been illustrated here but it is also used in many more occasions to hold different types of information, such as:
- Expected utilities of a value node,
- Beliefs of chance nodes,
- Value of information, and
- Expected utility of the different choices of a decision node.
In all the above cases, the usage is analogical to the one presented in the above example. It is recommended for the application developers to thoroughly understand this class to facilitate programming with the library.



