static void erdos_link_together ( mcxIO* xfout , mclx* mx , mclv* tails , mclv* heads ) { dim v = 0 ; mclv* relevant = mclvInit(NULL) ; fprintf(xfout->fp, "("); ; for (v=0;v<tails->n_ivps;v++) { long t = tails->ivps[v].idx ; dim j ; mclv* nb = mclxGetVector(mx, t, EXIT_ON_FAIL, NULL) ; mcldMeet(nb, heads, relevant) ; for (j=0;j<relevant->n_ivps;j++) { if (tab_g) { long u = relevant->ivps[j].idx ; const char* sx = mclTabGet(tab_g, (long) t, NULL) ; const char* sy = mclTabGet(tab_g, (long) u, NULL) ; if (!sx) sx = "NAx" ; if (!sy) sy = "NAy" ; fprintf(xfout->fp, " (%s %s)", sx, sy) ; } else fprintf(xfout->fp, " (%ld %ld)", (long) t, (long) relevant->ivps[j].idx) ; } if (!relevant->n_ivps) mcxErr(me, "odd, %d has no friends\n", (int) t) ; } fprintf(xfout->fp, " )\n"); ; mclvFree(&relevant) ; }
void handle_list ( mclx* mx , mcxTing* sa ) { mcxKV* kv = tab_g ? mcxHashSearch(sa, hsh_g, MCX_DATUM_FIND) : NULL ; mcxstatus status = STATUS_OK ; long idx = -1 ; if (tab_g && !kv) { label_not_found(sa) ; return ; } else if (kv) idx = VOID_TO_ULONG kv->val ; else status = mcxStrTol(sa->str, &idx, NULL) ; if (status || check_bounds(mx, idx)) return ; { mclv* vec = mx->cols+idx ; dim t ; for (t=0;t<vec->n_ivps;t++) { const char* s = tab_g ? mclTabGet(tab_g, (long) vec->ivps[t].idx, NULL) : NULL ; if (s) fprintf(stderr, " %s\n", s) ; else fprintf(stderr, "%12ld\n", (long) vec->ivps[t].idx) ; } } }
void dump_label ( mclTab* tab , dim vid , int level ) { const char* label = mclTabGet(tab, vid, NULL) ; dim i ; for (i=0;i<level;i++) fputs(" ", stdout) ; fprintf("| %s\n", label ? label : "????") ; }
void handle_top ( mclx* mx , mcxTing* sa ) { long num = -1 ; dim t ; mcxHeap* hp ; if (mcxStrTol(sa->str, &num, NULL) || num < 0) { fprintf(stderr, "(error number-no-good)\n") ; return ; } if (!num || (dim) num > N_COLS(mx)) num = N_COLS(mx) /* Could use mclxColSizes instead */ ; hp = mcxHeapNew ( NULL , num , sizeof(mclp) , mclpValRevCmp ) ; for (t=0;t<N_COLS(mx);t++) { mclp ivp ; ivp.idx = mx->cols[t].vid ; ivp.val = mx->cols[t].n_ivps ; mcxHeapInsert(hp, &ivp) ; } qsort(hp->base, hp->n_inserted, hp->elemSize, hp->cmp) /* warning this destroys the heap structure */ ; for (t=0; t<hp->n_inserted;t++) { char* p = (char*) hp->base + (t*hp->elemSize) ; mclp* ivp = (void*) p ; const char* s = tab_g ? mclTabGet(tab_g, (long) ivp->idx, NULL) : NULL ; if (s) fprintf(stderr, "%20s : %6.0f\n", s, (double) ivp->val) ; else fprintf(stderr, "%20ld : %6.0f\n", (long) ivp->idx, (double) ivp->val) ; } mcxHeapFree(&hp) ; }
void get_attr ( mclx* mx , mclTab* tab , mcxIO* xfattr ) { mclx* tp = mclxTranspose(mx) ; mclx* G = mclxAdd(mx, tp) ; mclv* fwd = mclxColSizes(mx, MCL_VECTOR_COMPLETE) ; mclv* bwd = mclxColSizes(tp, MCL_VECTOR_COMPLETE) ; mclx* cc = clmComponents(G, NULL) ; mclx* node2cc = mclxTranspose(cc) ; dim i, n_cycle = 0 ; fprintf(xfattr->fp, "node\tup\tdown\tnparent\tnchild\tndag\n") ; for (i=0;i<bwd->n_ivps;i++) { mclv* seenpp1 = NULL, *seenpp2 = NULL ; ofs level_up = fire_node(mx, i, &seenpp1) ; ofs level_dn = fire_node(tp, i, &seenpp2) ; ofs ccidx = node2cc->cols[i].ivps[0].idx ; dim ccsize = cc->cols[ccidx].n_ivps ; mclvFree(&seenpp1) ; mclvFree(&seenpp2) ; if ((i+1) % 500 == 0) fputc('.', stderr) ; if (tab) { const char* label = mclTabGet(tab, mx->cols[i].vid, NULL) ; fputs(label, xfattr->fp) ; fputc('\t', xfattr->fp) ; } else fprintf ( xfattr->fp , "%lu\t" , (ulong) mx->cols[i].vid ) ; fprintf ( xfattr->fp , "%ld\t%ld\t%lu\t%lu\t%lu\n" , (long) level_up , (long) level_dn , (ulong) fwd->ivps[i].val , (ulong) bwd->ivps[i].val , (ulong) ccsize ) ; if (level_up < 0 || level_dn < 0) fputc('.', stderr) , n_cycle++ ; } if (n_cycle) fputc('\n', stderr) ; mclvFree(&bwd) ; mclvFree(&fwd) ; mclxFree(&tp) ; }
static mcxstatus collectMain ( int argc , const char* argv[] ) { aggr* collect = NULL ; int a ; dim i, collect_n = 0 ; mclTab* tab = NULL ; double avg = 0.0 ; mclx* aggr = NULL, *mx = NULL /* mcxHash* map = NULL */ ; mcxIO* xfout = mcxIOnew(out_g, "w") ; mcxIOopen(xfout, EXIT_ON_FAIL) ; if ( transform_spec && (!(transform = mclgTFparse(NULL, transform_spec))) ) mcxDie(1, me, "input -tf spec does not parse") ; if (xftab_g) tab = mclTabRead(xftab_g, NULL, EXIT_ON_FAIL) /* map not used; perhaps someday we want to map labels to indexes? * in that case, we could also simply reverse the tab when reading .. , map = mclTabHash(tab) */ ; if (!collect_g) mcxDie(1, me, "require one of --paste, --add-column, --add-matrix") ; if (argc) { if (collect_g == 'm') { mcxIO* xf = mcxIOnew(argv[0], "r") ; mcxIOopen(xf, EXIT_ON_FAIL) ; aggr = mclxRead(xf, EXIT_ON_FAIL) ; mcxIOfree(&xf) ; } else collect_n = do_a_file(&collect, argv[0], 0) ; } if (tab && collect_n != N_TAB(tab) + (header_g ? 1 : 0)) mcxErr ( me , "tab has differing size (%lu vs %lu), continuing anyway" , (ulong) N_TAB(tab) , (ulong) (collect_n ? collect_n -1 : 0) ) ; for (a=1;a<argc;a++) { if (collect_g == 'm') { mcxIO* xf = mcxIOnew(argv[a], "r") ; mcxIOopen(xf, EXIT_ON_FAIL) ; mx = mclxRead(xf, EXIT_ON_FAIL) ; mclxAugment(aggr, mx, fltop_g) ; mcxIOfree(&xf) ; mclxFree(&mx) ; } else do_a_file(&collect, argv[a], collect_n) ; } if (collect_g == 'm') { if (transform) mclgTFexec(aggr, transform) ; if (mcx_wb_g) mclxbWrite(aggr, xfout, EXIT_ON_FAIL) ; else mclxWrite(aggr, xfout, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; mcxIOclose(xfout) ; exit(0) ; } /* fimxe: dispatch on binary_g */ for (i=0;i<collect_n;i++) { const char* lb = collect[i].label ; if (!i && collect[i].columns && collect_g != 'p') { fprintf(xfout->fp, "%s\t%s\n", lb, collect[i].columns->str) ; continue ; } if (tab && (!header_g || i > 0)) { unsigned u = atoi(lb) ; lb = mclTabGet(tab, u, NULL) ; if (TAB_IS_NA(tab, lb)) mcxDie(1, me, "no label found for index %ld - abort", (long) u) ; } if (summary_g) avg += collect[i].val ; else { if (collect_g == 'p') fprintf(xfout->fp, "%s%s\n", lb, collect[i].columns->str) ; else fprintf(xfout->fp, "%s\t%.8g\n", lb, collect[i].val) ; } } if (summary_g && collect_n) { dim middle1 = (collect_n-1)/2, middle2 = collect_n/2 ; qsort(collect, collect_n, sizeof collect[0], aggr_cmp_val) ; avg /= collect_n ; fprintf /* --summary option is a bit rubbish interface-wise */ ( xfout->fp , "%g %g %g %g\n" , collect[0].val , (collect[middle1].val + collect[middle2].val) / 2 , collect[collect_n-1].val , avg ) ; } return STATUS_OK ; }