/** \brief Build a graph of type GMRFLib_graph_tp from the editable graph-object \param[out] graph The graph of type GMRFLib_graph_tp is returned as \a *graph \param[in] ged The editable graph-object \sa GMRFLib_graph_tp */ int GMRFLib_ged_build(GMRFLib_graph_tp ** graph, GMRFLib_ged_tp * ged) { #define NOMAP (-1) /* * build the graph */ GMRFLib_graph_tp *g; int i, j, jj, n, *nnbs, node = -1, nnode = -1, **nbs, *map, *imap, n_new; unsigned char *node_in_use, *indep; map_ii **hash; spmatrix_storage *sptr; map_ii_storage *iptr; /* * number of (possible) nodes */ n = ged->max_node + 1; /* * flag nodes in use */ node_in_use = Calloc(n, unsigned char); for (sptr = NULL; (sptr = spmatrix_nextptr(&(ged->Q), sptr)) != NULL;) { if (sptr->value != 0.0 && sptr->key.key1 == sptr->key.key2) { node_in_use[sptr->key.key1] = 1; } } /* * add global nodes (if any) */ for (j = 0, iptr = NULL; (iptr = map_ii_nextptr(&(ged->tags), iptr)) != NULL;) { if (iptr->value == GMRFLib_GED_TAG_GLOBAL) { i = iptr->key; if (node_in_use[i]) { for (jj = 0; jj < n; jj++) { if (node_in_use[jj] && jj != i) { GMRFLib_ged_add(ged, i, jj); } } } } } /* * flag indep nodes (if any) */ indep = Calloc(n, unsigned char); for (j = 0, iptr = NULL; (iptr = map_ii_nextptr(&(ged->tags), iptr)) != NULL;) { if (iptr->value == GMRFLib_GED_TAG_INDEP) { indep[iptr->key] = 1; } } imap = Calloc(n, int); map = Calloc(n, int); nbs = Calloc(n, int *); nnbs = Calloc(n, int); hash = Calloc(n, map_ii *); for (i = 0; i < n; i++) { hash[i] = Calloc(1, map_ii); map_ii_init(hash[i]); } /* * find the mapping */ for (i = 0; i < n; i++) { map[i] = imap[i] = NOMAP; } for (i = j = n_new = 0; i < n; i++) { if (node_in_use[i]) { map[i] = j; imap[j] = i; j++; n_new++; } } /* * find the neighbours */ for (sptr = NULL; (sptr = spmatrix_nextptr(&(ged->Q), sptr)) != NULL;) { if (sptr->value != 0.0 && sptr->key.key1 != sptr->key.key2) { node = IMIN(sptr->key.key1, sptr->key.key2); nnode = IMAX(sptr->key.key1, sptr->key.key2); assert(LEGAL(node, n) && LEGAL(nnode, n)); if (node_in_use[node] && node_in_use[nnode] && !indep[node] && !indep[nnode]) { map_ii_set(hash[node], nnode, 1); map_ii_set(hash[nnode], node, 1); nnbs[node]++; nnbs[nnode]++; } } } /* * make the nbs-array */ for (i = 0; i < n; i++) { if (nnbs[i]) { nbs[i] = Calloc(nnbs[i], int); for (j = 0, iptr = NULL; (iptr = map_ii_nextptr(hash[i], iptr)) != NULL;) { nbs[i][j++] = iptr->key; } } } /* * make the graph-object. copy it into a new one to make the correct memory-layout */ for (i = 0; i < n_new; i++) { nnbs[i] = nnbs[imap[i]]; /* ok, as imap[i] >= i */ nbs[i] = nbs[imap[i]]; /* ok, as imap[i] >= i */ } for (i = 0; i < n_new; i++) { for (jj = 0; jj < nnbs[i]; jj++) { nbs[i][jj] = map[nbs[i][jj]]; /* map to the new nodes */ } } GMRFLib_make_empty_graph(&g); g->n = n_new; g->nnbs = nnbs; g->nbs = nbs; g->mothergraph_idx = imap; /* preserve the mapping */ GMRFLib_copy_graph(graph, g); GMRFLib_prepare_graph(*graph); if (0) { /* * validate the graph? this should not be needed, as this function will ensurethe graph should be always be consistent. * In any case, enable this for the moment until these tools are sufficiently validated. */ GMRFLib_EWRAP0(GMRFLib_validate_graph(stderr, *graph)); } /* * cleanup */ for (i = 0; i < n_new; i++) { Free(nbs[i]); } Free(nbs); Free(nnbs); Free(node_in_use); Free(map); Free(imap); Free(g); Free(indep); for (i = 0; i < n; i++) { map_ii_free(hash[i]); Free(hash[i]); } Free(hash); return GMRFLib_SUCCESS; #undef NOMAP }
main() { short rm; short ret; unsigned char t; char buf[4]; putenv("_=pfead_pmfile"); chdir(getenv("HOME")); open_all(); fix(pfead_pmfile); sd_screen_off(); sd_clear_screen(); sd_text(pfead_pmfile); sd_screen_on(); while(1) { memset(buf, 0, sizeof(buf)); t = sd_input(&fld1,(sd_prompt(&fld1,0)),&rm,buf,0); if(t == EXIT) leave(); if(t != RETURN) continue; /* invalid keys */ *buf = tolower(*buf); if (!LEGAL(toupper(*buf))) { eh_post(ERR_CODE, buf); continue; } switch(*buf) { case 'a': loadprog("acd_pm_screen", "assign"); break; case 'b': loadprog("acd_pm_screen", "add"); break; case 'c': loadprog("acd_pm_screen", "change"); break; case 'd': loadprog("acd_pm_screen", "deassign"); break; case 'e': loadprog("acd_pm_screen", "move"); break; case 'f': loadprog("ins_pm_screen", 0); break; case 'g': loadprog("delete_pm_screen", 0); break; case 'z': loadprog("zero_move_counts", 0); break; default: eh_post(ERR_CODE, buf); break; } /* end switch */ } }