void SetNodeLevels_bn ( node_bn*  node,   int  num_states,   const level_bn*  levels )

Sets the levels list of node to levels.

The levels list is a list of real numbers used by Netica to translate from a real value of a continuous node to a discrete state, or from a state of a discrete node to a real value. That way a continuous node can act discrete (called "discretization"), or a discrete node can provide real-valued numbers. 'level_bn' is just defined as a 'double'.

If the underlying variable is continuous, we may want to discretize it for some operations. For example, we may divide all possible masses of some object into 3 ranges: 0 to 0.1 kg, 0.1 to 10 kg, and greater than 10 kg. For that we would use the levels list: [0, 0.1, 10, INFINITY_ns].

Conversely, if it is discrete, we may want a mapping from its state (represented as an integer), to a measurable value. For example, a drill may have 3 speeds (2.5 rps, 5 rps and 10 rps) as well as off. We could use a 4-state discrete node to represent the drill speed, with the levels list [0, 2.5, 5, 10]. Or milk may be available in containers of size 0.375, l, and 2 liters.

Netica will make a copy of levels; it won't modify or free the passed array.

Since the usage of levels is a little different for each type of node, each is discussed separately:

node is continuous: (GetNodeType_bn would return CONTINUOUS_TYPE)

For num_states pass the number of ranges to discretize the node into. It must be zero or greater (if it is zero, then levels must be NULL, and any current discretization will be removed).

levels must contain num_states + 1 entries, and must monotonically ascend or descend (it is okay to have adjacent entries equal to create point-valued "ranges").

The first and last entries of the levels list provide a bound on the lowest and highest values the node can take on, but they may be INFINITY_ns or -INFINITY_ns (note: do not use the INFINITY_ns macro until after InitNetica2_bn has been called).

Once node has been given the levels list, Netica can translate a continuous value val for the node to a discrete state st, by choosing st so that:

    levels [st] <= val < levels [st + 1] (if levels ascends) or
    levels [st] > val >= levels [st + 1] (if levels descend)
A discrete state st can also be translated to the range:
    [levels[st], levels[st + 1]) (if levels ascends) or
    [levels[st + 1], levels[st]) (if levels descend)

node is discrete: (GetNodeType_bn would return DISCRETE_TYPE)

There must be one entry in levels for each state of node. The value passed for num_states must be the number of states of the node (i.e., the value returned by GetNodeNumberStates_bn). There is no constraint on the ordering of levels.

Once node has been given the levels list, Netica can convert a discrete state st to a real-valued number val, using:

  val = levels [st]

A real-number value val can also be translated to a discrete state st by choosing st so that: val = levels [st]. If there is no such st, then a legal translation cannot be made, but sometimes you can request Netica to approximate by choosing st so that:

  | val - levels [st] | is minimized.


This function is available in all versions.

See also:

GetNodeLevels_bn    Retrieves values
NewNode_bn    Must be called with num_states = 0 to make continuous node
EnterNodeValue_bn    Uses discretization to convert to state finding
EquationToTable_bn    Uses discretization to handle continuous values in the table
GetNodeExpectedValue_bn    Uses discretization or real values to calculate mean and standard deviation


// Here we make a continuous node and then discretize it into 3 states.
node_bn* node = NewNode_bn ("n1", 0, net);  // must pass 0 for num_states to create a node 
                                               for a continuous variable
level_bn levels[4];                         // 1 more than the number of states
levels[0] = 0;                              // the first range is 0 to 0.1
levels[1] = 0.1;
levels[2] = 10;
levels[3] = INFINITY_ns;
SetNodeLevels_bn (node, 3, levels);      // discretizes to 3 states
SetNodeStateNames_bn (node, "low, medium, high");   // naming the states is optional
Example 2:
// Here we make a 3-state discrete node and then give it
// levels to provide real values to its children.
node_bn* node = NewNode_bn ("volt_switch", 3, net);  // discrete, with 3 states
level_bn levels[3];                      // 1 element for each state
levels[0] =  0.0;
levels[1] = -3.5;                        // state 1 gives -3.5
levels[2] =  5.5;
SetNodeLevels_bn (node, 3, levels);      // set the levels
SetNodeStateName_bn (node, "off, reverse, forward");   // naming the states is optional