/** * Node.c --- This file contains functions for creating, * destroying, and modifying states of nodes. */ #include #include #include #include /*************************************************************************** * Low Level Node Utilities ***************************************************************************/ /** * This is a small utility function meant to be used from within * toString to determine if the pointer is live or not. */ SEXP RN_isNodeActive(SEXP node) { SEXP nodePtr, result; PROTECT(result=allocVector(LGLSXP,1)); LOGICAL(result)[0]=FALSE; PROTECT(nodePtr = getAttrib(node,nodeatt)); if (nodePtr && nodePtr != R_NilValue && R_ExternalPtrAddr(nodePtr)) { LOGICAL(result)[0] = TRUE; } UNPROTECT(2); return result; } /** * Tests whether or not an object is a Netica Node. */ int isNeticaNode(SEXP obj) { SEXP klass; int result = FALSE; PROTECT(klass = getAttrib(obj,R_ClassSymbol)); R_len_t k, kk=length(klass); for (k=0; k nn) { //Too long, remove states for (ni=n; ni > nn; ) { RemoveNodeState_bn(node_handle,--ni); } } SetNodeStateNames_bn(node_handle,value); } else { warning("Could not find node %s.",NODE_NAME(nd)); } return(nd); } SEXP RN_GetNodeStateTitles(SEXP nd) { R_len_t n, nn; const char *value, *statename; node_bn* node_handle; SEXP result, statenames; node_handle = GetNodeHandle(nd); if (!node_handle) { error("Could not find node %s.",NODE_NAME(nd)); PROTECT(result=allocVector(STRSXP,1)); SET_STRING_ELT(result,0,NA_STRING); } else { //Count number of fields. nn = GetNodeNumberStates_bn(node_handle); PROTECT(result = allocVector(STRSXP,nn)); PROTECT(statenames = allocVector(STRSXP,nn)); for (n=0; n < nn; n++) { statename = GetNodeStateName_bn(node_handle, n); value = GetNodeStateTitle_bn(node_handle, n); SET_STRING_ELT(statenames,n,mkChar(statename)); SET_STRING_ELT(result,n,mkChar(value)); } namesgets(result,statenames); UNPROTECT(1); } UNPROTECT(1); return(result); } SEXP RN_SetNodeStateTitles(SEXP nd, SEXP newvals) { R_len_t n, nn; const char *value; node_bn* node_handle; node_handle = GetNodeHandle(nd); if (!node_handle) { error("Could not find node %s.",NODE_NAME(nd)); return (R_NilValue); } else { //Count number of fields. nn = GetNodeNumberStates_bn(node_handle); for (n=0; n < nn; n++) { value = CHAR(STRING_ELT(newvals,n)); SetNodeStateTitle_bn(node_handle, n, value); } } return(nd); } SEXP RN_GetNodeStateComments(SEXP nd) { R_len_t n, nn; const char *value, *statename; node_bn* node_handle; SEXP result, statenames; node_handle = GetNodeHandle(nd); if (!node_handle) { error("Could not find node %s.",NODE_NAME(nd)); PROTECT(result=allocVector(STRSXP,1)); SET_STRING_ELT(result,0,NA_STRING); } else { //Count number of fields. nn = GetNodeNumberStates_bn(node_handle); PROTECT(result = allocVector(STRSXP,nn)); PROTECT(statenames = allocVector(STRSXP,nn)); for (n=0; n < nn; n++) { statename = GetNodeStateName_bn(node_handle, n); value = GetNodeStateComment_bn(node_handle, n); SET_STRING_ELT(statenames,n,mkChar(statename)); SET_STRING_ELT(result,n,mkChar(value)); } namesgets(result,statenames); UNPROTECT(1); } UNPROTECT(1); return(result); } SEXP RN_SetNodeStateComments(SEXP nd, SEXP newvals) { R_len_t n, nn; const char *value; node_bn* node_handle; node_handle = GetNodeHandle(nd); if (!node_handle) { error("Could not find node %s.",NODE_NAME(nd)); return (R_NilValue); } else { //Count number of fields. nn = GetNodeNumberStates_bn(node_handle); for (n=0; n < nn; n++) { value = CHAR(STRING_ELT(newvals,n)); SetNodeStateComment_bn(node_handle, n, value); } } return(nd); } //R code switches between continuous and discrete versions. SEXP RN_GetNodeLevelsDiscrete(SEXP nd) { R_len_t n, nn; const char *statename; node_bn* node_handle; const level_bn* levels; SEXP result, statenames; node_handle = GetNodeHandle(nd); if (!node_handle) { error("Could not find node %s.",NODE_NAME(nd)); PROTECT(result=ScalarReal(R_NaReal)); } else { //Count number of fields. nn = GetNodeNumberStates_bn(node_handle); PROTECT(result = allocVector(REALSXP,nn)); PROTECT(statenames = allocVector(STRSXP,nn)); levels = GetNodeLevels_bn(node_handle); for (n=0; n < nn; n++) { statename = GetNodeStateName_bn(node_handle, n); SET_STRING_ELT(statenames,n,mkChar(statename)); if (levels == NULL) { REAL(result)[n] = R_NaReal; } else { REAL(result)[n] = RN_NnumToRnum(levels[n]); } } namesgets(result,statenames); UNPROTECT(1); } UNPROTECT(1); return(result); } //Switching between discrete and continuous is done at R level. SEXP RN_GetNodeLevelsContinuous(SEXP nd) { node_bn* node_handle; const level_bn* levels; SEXP result; R_len_t n, nn; node_handle = GetNodeHandle(nd); if (!node_handle) { error("Could not find node %s.",NODE_NAME(nd)); PROTECT(result=ScalarReal(R_NaReal)); } else { //Count number of fields. levels = GetNodeLevels_bn(node_handle); if (levels == NULL) { nn = 0; } else { nn = GetNodeNumberStates_bn(node_handle)+1; } PROTECT(result = allocVector(REALSXP,nn)); for (n=0; n < nn; n++) { REAL(result)[n] = RN_NnumToRnum(levels[n]); } } UNPROTECT(1); return(result); } //Different error checking, but setting routine is similar. SEXP RN_SetNodeLevels(SEXP nd, SEXP newvals) { R_len_t n, nn = length(newvals); node_bn* node_handle; level_bn* levels; node_handle = GetNodeHandle(nd); if (!node_handle) { error("Could not find node %s.",NODE_NAME(nd)); } else { //Count number of fields. if (nn == 0 ) { levels = NULL; } else { levels = (level_bn *) R_alloc(nn,sizeof(level_bn)); for (n=0; n < nn; n++) { levels[n] = RN_RnumToNnum(REAL(newvals)[n]); } } //Continuous have number of states equal to length(newvals)-1 if (GetNodeType_bn(node_handle) == CONTINUOUS_TYPE && nn > 0) nn--; SetNodeLevels_bn(node_handle, nn, levels); } return(nd); } ////////////////////////////////////////////////////////////////// // Node Sets SEXP RN_ParseNodeSetString(net_bn *nt, bool_ns incSystem) { const char*rawsets=GetAllNodesets_bn(nt,incSystem,NULL); if (rawsets==NULL || strlen(rawsets)==0) { // Trap for zero length return (allocVector(STRSXP,0)); } char *sets = R_alloc(strlen(rawsets),sizeof(char)); sets = strcpy(sets,rawsets); SEXP result; int i, nsets = 1; for (i=0; i