/** * Networks.c --- These files describe functions for creating, * destroying, saving and other high level functions on networks. */ #include #include #include #include /***************************************************************************** * Creating and Destroying Bayesian Networks. *****************************************************************************/ // Original design here was to capture and save the returned handle to // the network. But this is difficult to make safe as R will hang // onto the stale pointers. Instead, we will use the names, and then // just try to find the network by name when we want to modify it. // That should be only slightly slower but infinitely safer. // // Design 3. Now I am using the Netica User data field to store // NeticaBN object. This means that I should be able to make the // objects unique. /** * This is a small utility function meant to be used from within * toString to determine if the pointer is live or not. */ SEXP RN_isBNActive(SEXP bn) { SEXP bnPtr, result; PROTECT(result=allocVector(LGLSXP,1)); LOGICAL(result)[0]=FALSE; PROTECT(bnPtr = getAttrib(bn,bnatt)); if (bnPtr && R_ExternalPtrAddr(bnPtr)) { LOGICAL(result)[0] = TRUE; } UNPROTECT(2); return result; } /** * Tests whether or not an object is a Netica Node. */ int isNeticaBN(SEXP obj) { SEXP klass; int result = FALSE; PROTECT(klass = getAttrib(obj,R_ClassSymbol)); R_len_t k, kk=length(klass); for (k=0; k 0; } else { LOGICAL(result)[0] = NA_LOGICAL; warning("Could not find network %s.",BN_NAME(bn)); } UNPROTECT(1); return(result); } SEXP RN_SetNetAutoUpdate(SEXP bn, SEXP newflags) { int update, old_update; net_bn* netica_handle; SEXP result; PROTECT(result = allocVector(LGLSXP,1)); netica_handle = GetNeticaHandle(bn); if (netica_handle) { update = LOGICAL(newflags)[0]; if (update) update = BELIEF_UPDATE; old_update = SetNetAutoUpdate_bn(netica_handle,update); //Netica docs appear to be wrong here. They seem to indicate we //should test against, BELIEF_UPDATE(=256) but actual value is 1. LOGICAL(result)[0] = old_update > 0; } else { LOGICAL(result)[0] = NA_LOGICAL; warning("Could not find network %s.",BN_NAME(bn)); } UNPROTECT(1); return(result); } SEXP RN_GetNetUserField(SEXP bn, SEXP fieldnames) { const char *value, *fieldname; int valuelen; net_bn* netica_handle; SEXP result; PROTECT(result = allocVector(STRSXP,1)); netica_handle = GetNeticaHandle(bn); if (netica_handle) { fieldname = CHAR(STRING_ELT(fieldnames,0)); value = GetNetUserField_bn(netica_handle,fieldname,&valuelen,0); if (valuelen<0) { // No object returned. SET_STRING_ELT(result,0,NA_STRING); } else { SET_STRING_ELT(result,0,mkChar(value)); } } else { SET_STRING_ELT(result,0,NA_STRING); warning("Could not find network %s.",BN_NAME(bn)); } UNPROTECT(1); return(result); } SEXP RN_GetAllNetUserFields(SEXP bn) { R_len_t n, nn; const char *value, *fieldname; int valuelen; net_bn* netica_handle; SEXP result, fieldnames; netica_handle = GetNeticaHandle(bn); if (!netica_handle) { error("Could not find network %s.",BN_NAME(bn)); PROTECT(result=allocVector(STRSXP,1)); SET_STRING_ELT(result,0,NA_STRING); } else { //Count number of fields. nn = 0; while (TRUE) { GetNetNthUserField_bn(netica_handle, nn, &fieldname, &value, &valuelen, 0); if (strlen(fieldname) <1 && valuelen <0) break; nn++; } PROTECT(result = allocVector(STRSXP,nn)); PROTECT(fieldnames = allocVector(STRSXP,nn)); for (n=0; n < nn; n++) { GetNetNthUserField_bn(netica_handle, n, &fieldname, &value, &valuelen, 0); SET_STRING_ELT(fieldnames,n,mkChar(fieldname)); SET_STRING_ELT(result,n,mkChar(value)); } namesgets(result,fieldnames); UNPROTECT(1); } UNPROTECT(1); return(result); } SEXP RN_SetNetUserField(SEXP bn, SEXP fieldnames, SEXP newvals) { const char *value, *fieldname; net_bn* netica_handle; netica_handle = GetNeticaHandle(bn); if (netica_handle) { fieldname = CHAR(STRING_ELT(fieldnames,0)); value = CHAR(STRING_ELT(newvals,0)); SetNetUserField_bn(netica_handle,fieldname,value, strlen(value),0); } else { warning("Could not find network %s.",BN_NAME(bn)); } return(bn); } SEXP RN_Undo(SEXP bn) { net_bn* netica_handle; SEXP result; PROTECT(result = allocVector(INTSXP,1)); netica_handle = GetNeticaHandle(bn); if (!netica_handle) { INTEGER(result)[0] = NA_INTEGER; UNPROTECT(1); error("Could not find network %s.",BN_NAME(bn)); return(result); } INTEGER(result)[0] = UndoNetLastOper_bn(netica_handle,-1.0); UNPROTECT(1); return(result); } SEXP RN_Redo(SEXP bn) { net_bn* netica_handle; SEXP result; PROTECT(result = allocVector(INTSXP,1)); netica_handle = GetNeticaHandle(bn); if (!netica_handle) { INTEGER(result)[0] = NA_INTEGER; UNPROTECT(1); error("Could not find network %s.",BN_NAME(bn)); return(result); } INTEGER(result)[0] = RedoNetOper_bn(netica_handle,-1.0); UNPROTECT(1); return(result); }