#include #include #include "Netica.h" #include "gnuplot_i.h" double grad; double devi; int action; int count; #define SLEEP_LGTH 2 #define CHKERR {if (GetError_ns (env, ERROR_ERR, NULL)) goto error;} environ_ns* env; /************************************************************************** Function: getUserNode. This is a utility function to prompt user for a node from a list **************************************************************************/ node_bn* getUserNode(const nodelist_bn* nodeList, char* type){ int nodeNum, i; printf("Nodes in network:\n"); for(i=0; i < LengthNodeList_bn(nodeList); i++) { printf("%d:\t%s\n", i+1, GetNodeName_bn (NthNode_bn (nodeList, i))); } printf("\nEnter %s Node Number: ", type); scanf("%d", &nodeNum); while(NthNode_bn(nodeList, nodeNum-1) == NULL) { printf("Invalid Node, try again: "); scanf("%d", &nodeNum); } return NthNode_bn(nodeList, nodeNum-1); } /************************************************************************** Function: getUserObservations. This is a utility function to prompt user for a subset of a node list **************************************************************************/ nodelist_bn* getUserObservations(nodelist_bn* nodeList, nodelist_bn* obsList){ int nodeNum, i; printf("\nNodes in network:\n"); for(i=0; i < LengthNodeList_bn(nodeList); i++) { printf("%d:\t%s\n", i+1, GetNodeName_bn(NthNode_bn(nodeList, i))); } printf("%d:\tStop\n", i+1); printf("\nEnter Observation Node Number (or option): "); scanf("%d", &nodeNum); if(nodeNum == i+1) return obsList; while(NthNode_bn(nodeList, nodeNum-1) == NULL) { printf("Invalid Node, try again: "); scanf("%d", &nodeNum); } AddNodeToList_bn(RemoveNthNode_bn(nodeList, nodeNum-1), obsList, 0); return getUserObservations(nodeList, obsList); } /************************************************************************** Function: userDone. This is a utility function to prompt user to continue or finish **************************************************************************/ int userDone() { char userAction[80]; if(!action) { action = 1; return 0; } printf("Continue? (y/n): "); scanf("%s", userAction); if(!strcmp(userAction,"n")) return 1; return 0; } /************************************************************************** Function: userEnd. This is a utility function just waits for the user to finish **************************************************************************/ void userEnd() { char userAction[80]; printf("Finish? (y/n): "); scanf("%s", userAction); } /************************************************************************** Function: listEvidence. This is a utility function to generate list of evidence set **************************************************************************/ void listEvidence(char list[200], nodelist_bn *evidenceSet) { int i; int num_evidence = LengthNodeList_bn(evidenceSet); node_bn *tempNode; char temp[20]; strcpy(list, ""); if(num_evidence == 0) strcat(list, "Empty"); for(i=0; i=b) return a; else return b; } /************************************************************************** Function: normalise. This is a function to normalise the probability distribution after a parameter has been altered **************************************************************************/ void normalise (prob_bn* probDist, int distSize, int fixed, double new) { int i; double old = probDist[fixed]; probDist[fixed] = new; for(i=0; i= 0; --nn) { if (++states[nn] < GetNodeNumberStates_bn (NthNode_bn (nodes, nn))) return 0; states[nn] = 0; } return 1; } /************************************************************************** Function: SolveLinear. This is a function to solve set of linear equations **************************************************************************/ int SolveLinear(double *A, double *B, int n) { int i, j, k; double temp; for(j=0; j < n-1; j++) { temp = A[j*n+j]; k = j; for(i=j+1; i < n; i++) { if(A[i*n+j] > temp) { temp = A[i*n+j]; k = i; } } if(k != j) { for(i=j; i < n; i++) { temp = A[j*n+i]; A[j*n+i] = A[k*n+i]; A[k*n+i] = temp; } temp = B[j]; B[j] = B[k]; B[k] = temp; } if(A[j*n+j] == 0) return 0; for(i=j+1; i < n; i++) { temp = A[i*n+j]/A[j*n+j]; for(k=j+1; k < n; k++) { A[i*n+k] = A[i*n+k] - temp*A[j*n+k]; } B[i] = B[i] - temp*B[j]; } } if(A[(n-1)*n+(n-1)] == 0) return 0; B[n-1] = B[n-1]/A[(n-1)*n+(n-1)]; for(i=n-2; i >= 0; i--) { temp = 0; for(j=i+1; j < n; j++) temp += A[i*n+j]*B[j]; B[i] = (B[i] - temp)/A[i*n+i]; } return 1; } /************************************************************************** Function: descendEvideCheck. This is a function check if a node has an observed descendent **************************************************************************/ int descendEvideCheck(node_bn *current){ int i; const nodelist_bn *children = GetNodeChildren_bn(current); int num_children = LengthNodeList_bn(children); if(GetNodeFinding_bn(current) != NO_FINDING) return 1; for(i=0; i 1) temp = temp-1.0; tempProbDist = copyProb(origProbDist, t_num_states); normalise(tempProbDist, t_num_states, index, temp); SetNodeProbs_bn (tNode, parent_states, tempProbDist); CompileNet_bn (net); A[i*3+0] = temp; A[i*3+1] = 1.0; A[i*3+2] = -bel[j]; B[i] = bel[j]*temp; free(tempProbDist); } SetNodeProbs_bn(tNode, parent_states, origProbDist); if(!SolveLinear(A, B, 3)) return 0; for(i=0; i<3; i++) { vars[i*3+j] = B[i]; if(!finite(vars[i*3+j])) return 0; } } return 1; } /************************************************************************** Function: needHypPlot. This is a function test if hyperbolic function will be of interest to the user **************************************************************************/ int needHypPlot(double *vars, int num_plots, int index, node_bn *tNode, state_bn *parent_states) { int i; int t_num_states = GetNodeNumberStates_bn(tNode); const prob_bn *origProbDist = copyProb(GetNodeProbs_bn (tNode, parent_states), t_num_states); double temp; for(i=0; i=grad) return 1; } return 0; } /************************************************************************** Function: getHypPlot. This is a function uses the preceeding functions to compute a hyperbolic function, determine if it is of interest and display it using gnuplot if it is **************************************************************************/ int getHypPlot(node_bn *qNode, node_bn *tNode, int index, state_bn *parent_states, nodelist_bn *evidenceSet, net_bn *net, FILE* plots) { int i; int q_num_states = GetNodeNumberStates_bn(qNode); int t_num_states = GetNodeNumberStates_bn(tNode); const prob_bn *origProbDist = copyProb(GetNodeProbs_bn (tNode, parent_states), t_num_states); double *vars = (double*) calloc(3*q_num_states, sizeof(double)); char label[200]; char list[200]; double x[2]; double y[2]; gnuplot_ctrl * h1; if(!getHypVars(vars, qNode, tNode, index, parent_states, net)) return 0; if(needHypPlot(vars, q_num_states, index, tNode, parent_states)) { if(userDone()) exit(1); h1 = gnuplot_init(); gnuplot_resetplot(h1); listEvidence(list, evidenceSet); sprintf(label,"Pr(%s | %s)", GetNodeName_bn(qNode), list); gnuplot_set_ylabel(h1, label); listParentStates(list, GetNodeParents_bn(tNode), parent_states); sprintf(label,"Pr(%s=%s | %s)", GetNodeName_bn(tNode), GetNodeStateName_bn(tNode, index), list); gnuplot_set_xlabel(h1, label); gnuplot_setstyle(h1, "points"); x[0] = 0; x[1] = 1; y[0] = 1; y[1] = 0; gnuplot_plot_xy(h1, x, y, 2, ""); gnuplot_setstyle(h1, "lines"); x[0] = x[1] = origProbDist[index]; y[0] = 0; y[1] = 1; gnuplot_plot_xy(h1, x, y, 2, "Initial"); for(i=0; i 1) temp = temp-1.0; tempProbDist = copyProb (origProbDist, t_num_states); normalise(tempProbDist, t_num_states, index, temp); SetNodeProbs_bn (tNode, parent_states, tempProbDist); CompileNet_bn (net); A[1*2+0] = temp; A[1*2+1] = 1.0; B[1] = bel[j]; free(tempProbDist); SetNodeProbs_bn (tNode, parent_states, origProbDist); if(!SolveLinear(A, B, 2)) return 0; for(i=0; i<2; i++) { vars[i*2+j] = B[i]; if(!finite(vars[i*2+j])) return 0; } } return 1; } /************************************************************************** Function: needLinPlot. This is a function test if linear function will be of interest to the user **************************************************************************/ int needLinPlot(double *vars, int num_plots, node_bn *tNode, state_bn *parent_states) { int i; int t_num_states = GetNodeNumberStates_bn(tNode); const prob_bn *origProbDist = copyProb(GetNodeProbs_bn (tNode, parent_states), t_num_states); for(i=0; i=grad) return 1; } return 0; } /************************************************************************** Function: getLinPlot. This is a function uses the preceeding functions to compute a linear function, determine if it is of interest and display it using gnuplot if it is **************************************************************************/ int getLinPlot(node_bn *qNode, node_bn *tNode, int index, state_bn *parent_states, nodelist_bn *evidenceSet, net_bn *net, FILE *plots) { int i; int q_num_states = GetNodeNumberStates_bn(qNode); int t_num_states = GetNodeNumberStates_bn(tNode); const prob_bn *origProbDist = copyProb(GetNodeProbs_bn (tNode, parent_states), t_num_states); double *vars = (double*) calloc(2*q_num_states, sizeof(double)); char label[200]; char list[200]; double x[2]; double y[2]; gnuplot_ctrl * h1; if(!getLinVars(vars, qNode, tNode, index, parent_states, net)) return 0; if(needLinPlot(vars, q_num_states, tNode, parent_states)) { if(userDone()) exit(1); h1 = gnuplot_init(); gnuplot_resetplot(h1); listEvidence(list, evidenceSet); sprintf(label,"Pr(%s|%s)", GetNodeName_bn(qNode), list); gnuplot_set_ylabel(h1, label); listParentStates(list, GetNodeParents_bn(tNode), parent_states); sprintf(label,"Pr(%s=%s | %s)", GetNodeName_bn(tNode), GetNodeStateName_bn(tNode, index), list); gnuplot_set_xlabel(h1, label); gnuplot_setstyle(h1, "points"); x[0] = 0; x[1] = 1; y[0] = 1; y[1] = 0; gnuplot_plot_xy(h1, x, y, 2, ""); gnuplot_setstyle(h1, "lines"); x[0] = x[1] = origProbDist[index]; y[0] = 0; y[1] = 1; gnuplot_plot_xy(h1, x, y, 2, "Initial"); for(i=0; i