| NORSYS SOFTWARE © 2012 | NETICA API | C VERSION 5.04

void SetNodeFuncState_bn ( | node_bn* node, const state_bn* parent_states, int func_state )

For deterministic nodes that are discrete or discretized. Deterministic nodes can be expressed as a function of their parent nodes, and that function can be in the form of a table. The purpose of SetNodeFuncState_bn is to build that table. It adds an entry to the table by telling Netica that when each parent has the state indicated in the vector parent_states, the state of node is func_state.

The order of the states in parent_states should match the order of the nodes in the list returned by GetNodeParents_bn (this will be the same order that parents were added using AddLink_bn). MapStateList_bn may be useful for that. parent_states can be NULL if node has no parents.

If any entry of parent_states is EVERY_STATE then it applies to all possible values of the corresponding parent (see SetNodeProbs_bn).

If node has many parents (i.e., the product of their number of states is large) then the function table will be large, and your system may run out of memory. You can use GetError_ns after calling this to see if the table was successfully built.

To cycle through all the possibilities of parent_states, see the NeticaEx function NextStates.

Version:

Versions 2.06 and earlier didn't have this function, but had one called SetNodeFuncValue_bn, which worked almost the same, but took both discrete and continuous nodes (i.e., combined this and SetNodeFuncReal_bn).
In versions 1.33 and earlier, "EVERY_STATE" was called "WILDCARD_STATE".

See also:

GetNodeFuncState_bn |  | Retrieves values
SetNodeFuncReal_bn |  | Same, but builds real-valued tables instead of discrete tables
SetNodeProbs_bn |  | To use instead if node isn't deterministic

Example:

    The following function is available in NeticaEx.c:
    // This function is similar to SetNodeProbs; see the comment for it.
    //

    #include <stdarg.h>
    #define ARR_SIZE 20

    void SetNodeFuncState (node_bn* node, int value, ...){
        char* statename;
        state_bn parent_states[ARR_SIZE];
        const nodelist_bn* parents = GetNodeParents_bn (node);
        int pn, numparents = LengthNodeList_bn (parents);
        va_list ap;
        if (numparents > ARR_SIZE){
            NewError_ns (env, 0, XXX_ERR, "SetNodeFuncState: Array too small");
            return;
        }
        va_start (ap, value);
        for (pn = 0;  pn < numparents;  ++pn){
            statename = va_arg (ap, char*);
            if (statename[0] == '*')  parent_states[pn] = EVERY_STATE;
            else parent_states[pn] = GetStateNamed_bn (statename, NthNode_bn (parents, pn));
        }
        va_end (ap);
        SetNodeFuncState_bn (node, parent_states, value);
    }

    #undef ARR_SIZE

Example 2:

    // This doesn't use SetNodeFuncState_bn, but it is useful for setting
    // parentStates.
    // It cycles through all possible configurations (i.e., elements of the cartesian
    //   product) of states, odometer style, with the last state changing fastest.
    // states is a list of node states, one for each node of nodes.
    // It returns TRUE when all the configurations have been examined (i.e., when it
    //   "rolls over" to all zeros again).
    // Don't forget to initialize states before calling it the first time (usually
    //   to all zeros).

    bool_ns NextStates (state_bn* states, const nodelist_bn* nodes){
        int nn;
        for (nn = LengthNodeList_bn (nodes) - 1;  nn >= 0;  nn--){
            if (++states[nn] < GetNodeNumberStates_bn (NthNode_bn (nodes, nn)))
                return FALSE;
            states[nn] = 0;
        }
        return TRUE;
    }