dim mclgTFexecx ( mclx* mx , mclgTF* tf , mcxbool allow_graph_ops ) { dim offset = 0, k = 0 ; mclpAR* par_edge = tf->par_edge ; mclpAR* par_graph = tf->par_graph ; while (offset < par_edge->n_ivps || k < par_graph->n_ivps) { dim top = offset ; while (top < par_edge->n_ivps && par_edge->ivps[top].idx != MCLX_UNARY_UNUSED) top++ ; if (top > offset) { mclpAR* par = mclpARfromIvps(NULL, par_edge->ivps+offset, top-offset) ;fprintf(stderr, "unary exec %d %d\n", (int) offset, (int) top) ; mclxUnaryList(mx, par) ; mclpARfree(&par) ; } if (par_edge->ivps[top].idx == MCLX_UNARY_UNUSED) { if (k >= par_graph->n_ivps) { mcxErr("mclgTFexec", "off the rails") ; break ; } if (allow_graph_ops) mclgTFgraph(mx, par_graph->ivps[k].idx, par_graph->ivps[k].val) ; k++ ;fprintf(stderr, "graph %s top=%d k=%d\n", allow_graph_ops ? "exec" : "skip", (int) offset, (int) k) ; } offset = top+1 ; } return mclxNrofEntries(mx) ; }
void mclgTFfree ( mclgTF** tfpp ) { mclgTF* tf = tfpp[0] ; if (tf) { mclpARfree(&(tf->par_edge)) ; mcxFree(tf) ; tfpp[0] = NULL ; } }
mclgTF* mclgTFparse ( mcxLink* encoding_link , mcxTing* thestring ) { mclgTF* gtf = mcxAlloc(sizeof gtf[0], EXIT_ON_FAIL) ; const char* me = "mclgTFparse" ; const char* a = thestring->str ; const char* z = thestring->str + thestring->len ; mcxTing* func = mcxTingEmpty(NULL, thestring->len) ; mcxTing* arg = mcxTingEmpty(NULL, thestring->len) ; int n = 0 ; if (!(gtf->par_edge = mclpARensure(NULL, 10))) return NULL /* +memleak gtf */ ; if (!(gtf->par_graph = mclpARensure(NULL, 10))) return NULL /* +memleak gtf, gtf->par_edge */ ; if ( thestring && !mcxStrChrAint(thestring->str, isspace, thestring->len) ) return gtf ; while (a < z) { const char* val, *key ; char* onw = NULL ; int tfe = -1, tfg = -1 ; mcxbool nought = FALSE ; unsigned char k0 ; double d ; int t ; mcxTingEmpty(arg, z-a) ; mcxTingEmpty(func, z-a) ; n = 0 ; if ((t = sscanf(a, " %[a-z_#-] ( )%n", func->str, &n)) >= 1 && n > 0) NOTHING ; else if ((t = sscanf(a, " %[a-z_#-] ( %[^)_ ] )%n", func->str, arg->str, &n)) >= 2 && n > 0) NOTHING ; else break ; a += n ; key= func->str ; val= arg->str ; k0 = key[0] ; d = strtod(val, &onw) ; if (!val || !strlen(val)) nought = TRUE ; else if (val == onw) { mcxErr(me, "failed to parse number <%s>", val) ; break ; } if (k0 == '#') { if (!strcmp(key, "#ceilnb")) tfg = MCLG_TF_CEILNB ; else if (!strcmp(key, "#knn")) tfg = MCLG_TF_KNN ; else if (!strcmp(key, "#n")) tfg = MCLG_TF_TOPN ; else if (!strcmp(key, "#ils")) tfg = MCLG_TF_ILS ; else if (!strcmp(key, "#mcl")) tfg = MCLG_TF_MCL ; else if (!strcmp(key, "#arcmcl")) tfg = MCLG_TF_ARC_MCL ; else if (!strcmp(key, "#arcsub")) tfg = MCLG_TF_ARCSUB ; else if (!strcmp(key, "#arcmax")) tfg = MCLG_TF_ARCMAX ; else if (!strcmp(key, "#arcmingq")) tfg = MCLG_TF_ARCMINGQ ; else if (!strcmp(key, "#arcmingt")) tfg = MCLG_TF_ARCMINGT ; else if (!strcmp(key, "#arcmimlq")) tfg = MCLG_TF_ARCMINLQ ; else if (!strcmp(key, "#arcminlt")) tfg = MCLG_TF_ARCMINLT ; else if (!strcmp(key, "#arcdiffgq")) tfg = MCLG_TF_ARCDIFFGQ ; else if (!strcmp(key, "#arcdiffgt")) tfg = MCLG_TF_ARCDIFFGT ; else if (!strcmp(key, "#arcdifflq")) tfg = MCLG_TF_ARCDIFFLQ ; else if (!strcmp(key, "#arcdifflt")) tfg = MCLG_TF_ARCDIFFLT ; else if (!strcmp(key, "#arcmaxgq")) tfg = MCLG_TF_ARCMAXGQ ; else if (!strcmp(key, "#arcmaxgt")) tfg = MCLG_TF_ARCMAXGT ; else if (!strcmp(key, "#arcmaxlq")) tfg = MCLG_TF_ARCMAXLQ ; else if (!strcmp(key, "#arcmaxlt")) tfg = MCLG_TF_ARCMAXLT ; else if (!strcmp(key, "#selfrm")) tfg = MCLG_TF_SELFRM ; else if (!strcmp(key, "#selfmax")) tfg = MCLG_TF_SELFMAX ; else if (!strcmp(key, "#normself")) tfg = MCLG_TF_NORMSELF ; else if (!strcmp(key, "#add")) tfg = MCLG_TF_ADD ; else if (!strcmp(key, "#max")) tfg = MCLG_TF_MAX ; else if (!strcmp(key, "#min")) tfg = MCLG_TF_MIN ; else if (!strcmp(key, "#mul")) tfg = MCLG_TF_MUL ; else if (!strcmp(key, "#tug")) tfg = MCLG_TF_TUG ; else if (!strcmp(key, "#ssq")) tfg = MCLG_TF_SSQ ; else if (!strcmp(key, "#qt")) tfg = MCLG_TF_QT ; else if (!strcmp(key, "#tp") || !strcmp(key, "#rev")) tfg = MCLG_TF_TRANSPOSE ; else if (!strcmp(key, "#step")) tfg = MCLG_TF_STEP ; else if (!strcmp(key, "#thread")) tfg = MCLG_TF_THREAD ; else if (!strcmp(key, "#shrug")) tfg = MCLG_TF_SHRUG ; else if (!strcmp(key, "#shuffle")) tfg = MCLG_TF_SHUFFLE ; } else { if (!strcmp(key, "gq")) tfe = MCLX_UNARY_GQ ; else if (!strcmp(key, "gt")) tfe = MCLX_UNARY_GT ; else if (!strcmp(key, "lt")) tfe = MCLX_UNARY_LT ; else if (!strcmp(key, "lq")) tfe = MCLX_UNARY_LQ ; else if (!strcmp(key, "rand")) tfe = MCLX_UNARY_RAND ; else if (!strcmp(key, "mul")) tfe = MCLX_UNARY_MUL ; else if (!strcmp(key, "scale")) tfe = MCLX_UNARY_SCALE ; else if (!strcmp(key, "add")) tfe = MCLX_UNARY_ADD ; else if (!strcmp(key, "abs")) tfe = MCLX_UNARY_ABS ; else if (!strcmp(key, "ceil")) tfe = MCLX_UNARY_CEIL ; else if (!strcmp(key, "floor")) tfe = MCLX_UNARY_FLOOR ; else if (!strcmp(key, "pow")) tfe = MCLX_UNARY_POW ; else if (!strcmp(key, "exp")) tfe = MCLX_UNARY_EXP ; else if (!strcmp(key, "log")) tfe = MCLX_UNARY_LOG ; else if (!strcmp(key, "neglog")) tfe = MCLX_UNARY_NEGLOG ; } if (tfe < 0 && tfg < 0) { mcxErr(me, "unknown value transform <%s>", key) ; break ; } if (tfe >= 0) { if (nought) { if ( tfe == MCLX_UNARY_LOG || tfe == MCLX_UNARY_ABS || tfe == MCLX_UNARY_EXP || tfe == MCLX_UNARY_NEGLOG ) d = 0.0 ; else { mcxErr(me, "transform <%s> needs value", key) ; break ; } ; } mclpARextend(gtf->par_edge, tfe, d) ; } else if (tfg >= 0) { if (nought) { if ( tfg >= MCLG_TF_DUMMY_NOVALUE_START && tfg <= MCLG_TF_DUMMY_NOVALUE_END ) d = 0.0 ; else if (tfg == MCLG_TF_TUG || tfg == MCLG_TF_SHRUG) d = 1000.0 ; else if (tfg == MCLG_TF_STEP) d = 2.0 ; else { mcxErr(me, "transform <%s> needs value", key) ; break ; } ; } mclpARextend(gtf->par_edge, MCLX_UNARY_UNUSED, 0.0) ; mclpARextend(gtf->par_graph, tfg, d) ; } a = mcxStrChrAint(a, isspace, z-a) ; if (!a || a[0] != ',') break ; a++ ; } if (a) { mcxErr(me, "trailing part <%s> not matched", a) ; mclpARfree(&(gtf->par_edge)) ; mcxFree(gtf) ; gtf = NULL ; } return gtf ; }
/* this aids in finding heuristically likely starting points * for long shortest paths, by looking at dead ends * in the lattice. * experimental, oefully underdocumented. */ static dim diameter_rough ( mclv* vec , mclx* mx , u8* rough_scratch , long* rough_priority ) { mclv* curr = mclvInsertIdx(NULL, vec->vid, 1.0) ; mclpAR* par = mclpARensure(NULL, 1024) ; dim d = 0, n_dead_ends = 0, n_dead_ends_res = 0 ; memset(rough_scratch, 0, N_COLS(mx)) ; rough_scratch[vec->vid] = 1 /* seen */ ; rough_priority[vec->vid] = -1 /* remove from priority list */ ; while (1) { mclp* currivp = curr->ivps ; dim t ; mclpARreset(par) ; while (currivp < curr->ivps + curr->n_ivps) { mclv* ls = mx->cols+currivp->idx ; mclp* newivp = ls->ivps ; int hit = 0 ; while (newivp < ls->ivps + ls->n_ivps) { u8* tst = rough_scratch+newivp->idx ; if (!*tst || *tst & 2) { if (!*tst) mclpARextend(par, newivp->idx, 1.0) ; *tst = 2 ; hit = 1 ; } newivp++ ; } if (!hit && rough_priority[currivp->idx] >= 0) rough_priority[currivp->idx] += d+1 , n_dead_ends_res++ ; else if (!hit) n_dead_ends++ /* ,fprintf(stderr, "[%ld->%ld]", (long) currivp->idx, (long) rough_priority[currivp->idx]) */ ; #if 0 if (currivp->idx == 115 || currivp->idx == 128) fprintf(stdout, "pivot %d node %d d %d dead %d pri %d\n", (int) vec->vid, (int) currivp->idx, d, (int) (1-hit), (int) rough_priority[currivp->idx]) #endif ; currivp++ ; } if (!par->n_ivps) break ; d++ ; mclvFromIvps(curr, par->ivps, par->n_ivps) ; for (t=0;t<curr->n_ivps;t++) rough_scratch[curr->ivps[t].idx] = 1 ; } mclvFree(&curr) ; mclpARfree(&par) ;if(0)fprintf(stdout, "deadends %d / %d\n", (int) n_dead_ends, (int) n_dead_ends_res) ; return d ; }