static dim do_remove ( mclx* mx , dim N_remove , dim* offsets /* size N_COLS(mx) */ , dim N_edge , dim random_ignore ) { dim n_remove = 0 ; while (n_remove < N_remove) { unsigned long r = (unsigned long) random() ; dim e, *ep ; ofs xo, yo ; long x ; mclv* vecx ; if (r >= random_ignore) continue ; e = r % N_edge ; if (!(ep = mcxBsearchFloor(&e, offsets, N_COLS(mx), sizeof e, dimCmp))) mcxDie(1, me, "edge %ld not found (max %ld)", (long) e, (long) N_edge) ; xo = ep - offsets ;if(DEBUG)fprintf(stderr, "have e=%d o=%d\n", (int) e, (int) xo) ; x = mx->dom_cols->ivps[xo].idx ; vecx = mx->cols+xo; ; yo = e - offsets[xo] ; if (yo >= vecx->n_ivps) /* note: mixed sign comparison */ mcxDie ( 1 , me , "vector %ld has not enough entries: %ld < %ld" , (long) vecx->vid , (long) vecx->n_ivps , (long) yo ) ; if (!vecx->ivps[yo].val) continue ; vecx->ivps[yo].val = 0.0 ;if(DEBUG)fprintf(stderr, "remove [%d] %ld %ld\n", (int) n_remove, (long) x, (long) vecx->ivps[yo].idx) ; n_remove++ ; } return n_remove ; }
int main ( int argc , const char* argv[] ) { const char* fn_input = argc > 1 ? argv[1] : "" ; mclAlgParam* mlp = NULL ; const char* me = "mcl" ; mcxstatus status = STATUS_OK ; srandom(mcxSeed(315)) ; signal(SIGALRM, mclSigCatch) ; if (signal(SIGUSR1, mcxLogSig) == SIG_ERR) mcxErr(me, "cannot catch SIGUSR1!") ; mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; mclx_app_init(stderr) ; if (argc < 2) { mcxTell ( me , "usage: mcl <-|file name> [options]," " do 'mcl -h' or 'man mcl' for help" ) ; mcxExit(0) ; } status = mclAlgInterface (&mlp, (char**) (argv+2), argc-2, fn_input, NULL, ALG_DO_IO) ; if (status == ALG_INIT_DONE) return 0 ; else if (status) mcxDie(STATUS_FAIL, me, "no tango") ; if ((status = mclAlgorithm(mlp)) == STATUS_FAIL) mcxDie(STATUS_FAIL, me, "failed") ; if (mlp->n_assimilated) mcxLog(MCX_LOG_MODULE, me, "%lu nodes will assimilate", (ulong) mlp->n_assimilated) ; if (mlp->mx_start) mcxLog(MCX_LOG_MODULE, me, "cached matrix with %lu columns", (ulong) N_COLS(mlp->mx_start)) ; mclAlgParamFree(&mlp, TRUE) ; helpful_reminder() ; return STATUS_OK ; }
dim get_n_sort_allvals ( const mclx* mx , pval* allvals , dim noe , double* sum_vals , mcxbool asc ) { dim n_allvals = 0 ; double s = 0.0 ; dim j ; for (j=0;j<N_COLS(mx);j++) { mclv* vec = mx->cols+j ; dim k ; if (n_allvals + vec->n_ivps > noe) mcxDie(1, me, "panic/impossible: not enough memory") ; for (k=0;k<vec->n_ivps;k++) allvals[n_allvals+k] = vec->ivps[k].val ; n_allvals += vec->n_ivps ; s += mclvSum(vec) ; } if (asc) qsort(allvals, n_allvals, sizeof(pval), valcmpasc) ; else qsort(allvals, n_allvals, sizeof(pval), valcmpdesc) ; sum_vals[0] = s ; return n_allvals ; }
static mcxstatus convertMain ( int argc_unused cpl__unused , const char* argv[] ) { mclMatrix* mx ; mclxCat st ; xfin = mcxIOnew(argv[0], "r") ; xfout = mcxIOnew(argv[1], "w") ; mclxCatInit(&st) ; if (main_mode == 'l') { if (mclxCatRead(xfin, &st, catmax, NULL, NULL, 0)) mcxDie(1, me, "failure is, if not an option, the result after all") ; mclxCatWrite(xfout, &st, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; } else if (main_mode == 'f') { int format ; mx = mclxRead(xfin, EXIT_ON_FAIL) ; format = mclxIOformat(xfin) ; if (!test_read) { mcxIOopen(xfout, EXIT_ON_FAIL) ; if (format == 'a') mclxbWrite(mx, xfout, EXIT_ON_FAIL) ; else mclxaWrite(mx, xfout, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; } } else { mcxbits bits = main_mode == 'c' ? MCLX_REQUIRE_DOMTREE | MCLX_CATREAD_CLUSTERSTACK : main_mode == 's' ? MCLX_REQUIRE_DOMSTACK | MCLX_CATREAD_CLUSTERTREE : 0 ; mcxIOopen(xfout, EXIT_ON_FAIL) ; if (mclxCatRead(xfin, &st, catmax, NULL, NULL, bits)) mcxDie(1, me, "failure is, if not an option, the result after all") ; mclxCatWrite(xfout, &st, MCLXIO_VALUE_NONE, EXIT_ON_FAIL) ; } return 0 ; }
void* mclxComposeThreadData ( mclxComposeHelper* ch , int i_thread ) { if (i_thread > ch->n_jobs) mcxDie(1, "compose", "fatal: thread ID error (%d asked, %d max)", (int) i_thread, (int) ch->n_jobs) ; return ch->iovs[i_thread] ; }
int main ( int argc , const char* argv[] ) { mclx* mx_score, *mx_start, *mx_end ; mcxIO* xfs, *xfl, *xfr ; dim i, j ; if (argc != 4) mcxDie(1, me, "need score start end matrices") ; xfs = mcxIOnew(argv[1], "r") ; xfl = mcxIOnew(argv[2], "r") ; xfr = mcxIOnew(argv[3], "r") ; mx_score = mclxRead(xfs, EXIT_ON_FAIL) ; mx_start = mclxRead(xfl, EXIT_ON_FAIL) ; mx_end = mclxRead(xfr, EXIT_ON_FAIL) ; fprintf ( stdout , "%10s%10s%10s%10s%10s%10s%10s%10s%10s%10s%10s%10s\n" , "vid1" , "vid2" , "diff1" , "diff2" , "meet" , "score" , "mean" , "csn" , "euclid" , "frac" , "re1" , "re2" ) ; for (i=0;i< N_COLS(mx_score);i++) { for (j=0;j<N_COLS(mx_score);j++) { double s ; s = get_score ( mx_score->cols+i , mx_score->cols+j , mx_start->cols+i , mx_start->cols+j , mx_end->cols+i , mx_end->cols+j ) ; } } return 0 ; }
static mclx* get_base ( const char* fn_input , mclx* mx_input , const char* b1opts , const char* b2opts ) { mclAlgParam* mlp = NULL ; mcxstatus status = STATUS_FAIL ; mclx* mxbase = NULL ; get_interface ( &mlp , fn_input , b2opts ? b2opts : b1opts , NULL , mx_input , b2opts ? ALG_CACHE_EXPANDED : ALG_CACHE_START , EXIT_ON_FAIL ) ; if (b2opts) { mlp->mpp->mainLoopLength = 1 ; mlp->mpp->mainInflation = 1.0 ; mlp->expand_only = TRUE ; mcxLog(MCX_LOG_APP, me, "computing expanded matrix") ; if ((status = mclAlgorithm(mlp)) == STATUS_FAIL) { mcxErr(me, "failed") ; mcxExit(1) ; } mcxLog(MCX_LOG_APP, me, "done computing expanded matrix") ; mxbase = mclAlgParamRelease(mlp, mlp->mx_expanded) ; } else { if (mclAlgorithmStart(mlp, FALSE)) mcxDie(1, me, "-b1 option start-up failed") ; mxbase = mclAlgParamRelease(mlp, mlp->mx_start) ; start_col_sums_g = mclvClone(mlp->mx_start_sums) ; } mclAlgParamFree(&mlp, TRUE) ; return mxbase ; }
mcxstatus mcxIOclose ( mcxIO* xf ) { fflush(xf->fp) ;if (!strcmp(xf->fn->str, "-") && !strcmp(xf->mode, "w") && !xf->stdio) mcxDie(1, "tst", "should not happen") ; if (xf->fp && !xf->stdio) { fclose(xf->fp) ; xf->fp = NULL ; } else if (xf->fp && xf->stdio) { int fe = ferror(xf->fp) /* fixme why not in branch above? */ ; if (fe) mcxErr("mcxIOclose", "error [%d] for [%s] stdio", fe, xf->mode) , perror("mcxIOclose") ; if (xf->ateof || feof(xf->fp)) clearerr(xf->fp) ; } /* fixme contract with usr_reset */ return mcxIOreset(xf) ; }
void static do_the_shuffle ( mclx* mx , dim N_shuffle , dim* offsets /* size N_COLS(mx) */ , dim N_edge , dim random_ignore ) { dim n_shuffle = 0 ; while (n_shuffle < N_shuffle) { unsigned long rx = (unsigned long) random() ; unsigned long ry = (unsigned long) random() ; mclp* ivpll, *ivplr, *ivprl, *ivprr ; dim edge_x, edge_y, *edge_px, *edge_py ; ofs xro, yro, xlo, ylo = -1, vxo, vyo ; long xl, xr, yl, yr ; mclv* vecxl, *vecxr, *vecyl, *vecyr ; double xlval, xrval, ylval, yrval ; if (rx >= random_ignore || ry >= random_ignore) continue ; edge_x = rx % N_edge /* fixme probably not optimal */ ; edge_y = ry % N_edge /* fixme probably not optimal */ ; if (!(edge_px = mcxBsearchFloor(&edge_x, offsets, N_COLS(mx), sizeof edge_x, dimCmp))) mcxDie(1, me, "edge %ld not found (max %ld)", (long) edge_x, (long) N_edge) ; if (!(edge_py = mcxBsearchFloor(&edge_y, offsets, N_COLS(mx), sizeof edge_y, dimCmp))) mcxDie(1, me, "edge %ld not found (max %ld)", (long) edge_y, (long) N_edge) ; vxo = edge_px - offsets ; xl = mx->dom_cols->ivps[vxo].idx ; vecxl = mx->cols+vxo ; xro = edge_x - offsets[vxo] ; vyo = edge_py - offsets ; yl = mx->dom_cols->ivps[vyo].idx ; vecyl = mx->cols+vyo ; yro = edge_y - offsets[vyo] /* Offset computation gone haywire */ ; if (xro >= vecxl->n_ivps || yro >= vecyl->n_ivps) /* note: mixed sign comparison */ mcxDie(1, me, "paradox 1 in %ld or %ld", xl, yl) ; xr = vecxl->ivps[xro].idx ; yr = vecyl->ivps[yro].idx ; xrval = vecxl->ivps[xro].val ; yrval = vecyl->ivps[yro].val /* Impossible, should have graph */ ; vecxr = mclxGetVector(mx, xr, EXIT_ON_FAIL, NULL) ; vecyr = mclxGetVector(mx, yr, EXIT_ON_FAIL, NULL) /* check that we have four different nodes * loops are not present so no need to check those */ ; if (xl == yl || xl == yr || xr == yl || xr == yr) continue ; if ( (0 > (xlo = mclvGetIvpOffset(vecxr, xl, -1))) || (0 > (ylo = mclvGetIvpOffset(vecyr, yl, -1))) ) mcxDie ( 1 , me , "symmetry violation 1" " %ld not found in %ld/%ld OR %ld not found in %ld/%ld" , (long) xl, (long) vecxr->vid, (long) vecxr->n_ivps , (long) yl, (long) vecyr->vid, (long) vecyr->n_ivps ) /* Now: xl yl : ivpll * xl yr : ivplr * xr yl : ivprl * xr yr : ivprr */ ; xlval = vecxr->ivps[xlo].val ; ylval = vecyr->ivps[ylo].val ; ivpll = mclvGetIvp(vecxl, yl, NULL) ; ivplr = mclvGetIvp(vecxl, yr, NULL) ; ivprl = mclvGetIvp(vecxr, yl, NULL) ; ivprr = mclvGetIvp(vecxr, yr, NULL) ; if ( (ivpll && !mclvGetIvp(vecyl, xl, NULL)) || (ivplr && !mclvGetIvp(vecyr, xl, NULL)) || (ivprl && !mclvGetIvp(vecyl, xr, NULL)) || (ivprr && !mclvGetIvp(vecyr, xr, NULL)) ) mcxDie(1, me, "symmetry violation 2") ; if ((ivpll && ivplr) || (ivprl && ivprr)) continue ; { if (!ivpll && !ivprr) { /* vecxl <-> xr becomes vecxl <-> yl * vecxr <-> xl becomes vecxr <-> yr * vecyl <-> yr becomes vecyl <-> xl * vecyr <-> yl becomes vecyr <-> xr */ ; if ( mclvReplaceIdx(vecxl, xro, yl, xrval) || mclvReplaceIdx(vecyl, yro, xl, xrval) || mclvReplaceIdx(vecxr, xlo, yr, ylval) || mclvReplaceIdx(vecyr, ylo, xr, ylval) ) mcxDie(1, me, "parallel replacement failure\n") #if DEBUG ;fprintf(stderr, "parallel edge change remove %d-%d %d-%d add %d-%d %d-%d\n", vecxl->vid, xr, vecyr->vid, yl, vecxl->vid, yl, vecyr->vid, xr) #endif ; } else if (!ivplr && !ivprl) { /* vecxl -> xr becomes vecxl <-> yr * vecxr -> xl becomes vecxr <-> yl * vecyl -> yr becomes vecyl <-> xr * vecyr -> yl becomes vecyr <-> xl */ if ( mclvReplaceIdx(vecxl, xro, yr, xrval) || mclvReplaceIdx(vecyr, ylo, xl, xlval) || mclvReplaceIdx(vecxr, xlo, yl, yrval) || mclvReplaceIdx(vecyl, yro, xr, yrval) ) mcxDie(1, me, "cross replacement failure\n") #if DEBUG ;fprintf(stderr, "cross edge change remove %d-%d %d-%d add %d-%d %d-%d\n", vecxl->vid, xr, vecyl->vid, yr, vecxl->vid, yr, vecyl->vid, xr) #endif ; } } n_shuffle++ ; } }
int main ( int argc , const char* argv[] ) { mcxIO *xfcl = NULL , *xfctrl = NULL , *xfcoarse= NULL , *xfbase = NULL , *xfcone = NULL , *xfstack = NULL ; mclx* mxbase, *cl, *cl_coarse, *clprev, *clctrl = NULL ; mcxTing* shared = mcxTingNew("-I 4 -overlap split") ; mcxbool root = TRUE ; mcxbool have_bootstrap = FALSE ; const char* plexprefix = NULL ; const char* stem = "mcl" ; mcxbool same = FALSE ; mcxbool plex = TRUE ; mcxbool add_transpose = FALSE ; const char* b2opts = NULL ; const char* b1opts = NULL ; mcxbits write_modes = 0 ; mclAlgParam* mlp = NULL ; mcxstatus status = STATUS_OK ; mcxstatus parse_status = STATUS_OK ; int multiplex_idx = 1 ; int N = 0 ; int n_ite = 0 ; dim n_components = 0, n_cls = 0 ; int a = 1, i= 0 ; int n_arg_read = 0 ; int delta = 0 ; mcxOption* opts, *opt ; mcxTing* cline = mcxOptArgLine(argv+1, argc-1, '\'') ; mclgTF* transform = NULL ; mcxTing* transform_spec = NULL ; double iaf = 0.84 ; mclx_app_init(stderr) ; if (0) mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; else mcxLogLevelSetByString("xf4g1") ; mcxOptAnchorSortById(options, sizeof(options)/sizeof(mcxOptAnchor) -1) ; if (argc == 2 && argv[1][0] == '-' && mcxOptIsInfo(argv[1], options)) delta = 1 ; else if (argc < 2) { help(options, shared) ; exit(0) ; } opts = mcxOptExhaust (options, (char**) argv, argc, 2-delta, &n_arg_read, &parse_status) ; if (parse_status != STATUS_OK) { mcxErr(me, "initialization failed") ; exit(1) ; } ; for (opt=opts;opt->anch;opt++) { mcxOptAnchor* anch = opt->anch ; switch(anch->id) { case MY_OPT_HELP : help(options, shared) ; exit(0) ; case MY_OPT_APROPOS : help(options, shared) ; exit(0) ; break ; case MY_OPT_NMAX : N = atoi(opt->val) ; break ; case MY_OPT_Z : help(NULL, shared) ; exit(0) ; break ; case MY_OPT_SHARED : mcxTingPrintAfter(shared, " %s", opt->val) ; break ; case MY_OPT_TRANSFORM : transform_spec = mcxTingNew(opt->val) ; break ; case MY_OPT_B1 : b1opts = opt->val ; break ; case MY_OPT_B2 : b2opts = opt->val ; break ; case ALG_OPT_SETENV : mcxSetenv(opt->val) ; break ; case ALG_OPT_QUIET : mcxLogLevelSetByString(opt->val) ; break ; case MY_OPT_HDP : hdp_g = atof(opt->val) ; break ; case MY_OPT_ADDTP : add_transpose = TRUE ; break ; case MY_OPT_ANNOT /* only used in command-line copying */ : break ; case MY_OPT_IAF : iaf = atof(opt->val) / 100 ; break ; case MY_OPT_WRITE : if (strstr(opt->val, "stack")) write_modes |= OUTPUT_STACK ; if (strstr(opt->val, "cone")) write_modes |= OUTPUT_CONE ; if (strstr(opt->val, "levels")) write_modes |= OUTPUT_STEPS ; if (strstr(opt->val, "coarse")) write_modes |= OUTPUT_COARSE ; if (strstr(opt->val, "base")) write_modes |= OUTPUT_BASE ; break ; case MY_OPT_BASENAME : xfbase = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_COARSE : xfcoarse = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_CONE : xfcone = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_ROOT : root = strchr("1yY", (u8) opt->val[0]) ? TRUE : FALSE ; break ; case MY_OPT_STACK : xfstack = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_STEM : stem = opt->val ; break ; case MY_OPT_MULTIPLEX : plex = strchr("yY1", (unsigned char) opt->val[0]) ? TRUE : FALSE ; break ; case MY_OPT_DISPATCH : dispatch_g = TRUE ; break ; case MY_OPT_INTEGRATE : integrate_g = TRUE ; break ; case MY_OPT_CONTRACT : break ; case MY_OPT_SUBCLUSTERX : subclusterx_g = TRUE, subcluster_g = TRUE ; break ; case MY_OPT_SUBCLUSTER : subcluster_g = TRUE ; break ; case MY_OPT_CONTROL : xfctrl = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_CL : xfcl = mcxIOnew(opt->val, "r") ; have_bootstrap = TRUE ; break ; case MY_OPT_VERSION : app_report_version(me) ; exit(0) ; default : mcxExit(1) ; } } mcxOptFree(&opts) ; a = 2 + n_arg_read ; if (a < argc) { if (strcmp(argv[a], "--")) mcxDie ( 1 , me , "trailing %s options require standalone '--' separator (found %s)" , integrate_g ? "integrate" : "mcl" , argv[a] ) ; a++ ; } if (subcluster_g + dispatch_g + integrate_g > 1) mcxDie(1, me, "too many modes!") ; if (N && N < argc-a) mcxErr(me, "-n argument leaves spurious option specifications") ; srandom(mcxSeed(89315)) ; signal(SIGALRM, mclSigCatch) ; if (dispatch_g) plexprefix = "dis" ; else if (!write_modes || (write_modes & OUTPUT_STEPS)) plexprefix = stem ; { mcxTing* tg = mcxTingEmpty(NULL, 30) ; if ((write_modes & OUTPUT_COARSE) && !xfcoarse) mcxTingPrint(tg, "%s.%s", stem, "coarse") , xfcoarse = mcxIOnew(tg->str, "w") ; if ((write_modes & OUTPUT_BASE) && !xfbase) mcxTingPrint(tg, "%s.%s", stem, "base") , xfbase = mcxIOnew(tg->str, "w") ; if ( (!write_modes || (write_modes & OUTPUT_CONE)) && !xfcone ) { mcxTingPrint(tg, "%s.%s", stem, "cone") ; xfcone = mcxIOnew(tg->str, "w") ; mcxIOopen(xfcone, EXIT_ON_FAIL) ; fprintf(xfcone->fp, "# %s %s\n", argv[0], cline->str) ; } if ((write_modes & OUTPUT_STACK) && !xfstack) { mcxTingPrint(tg, "%s.%s", stem, "stack") ; xfstack = mcxIOnew(tg->str, "w") ; mcxIOopen(xfstack, EXIT_ON_FAIL) ; fprintf(xfstack->fp, "# %s %s\n", argv[0], cline->str) ; } mcxTingFree(&tg) ; } if (integrate_g) { for (i=a;i<argc;i++) { mcxIO* xf = mcxIOnew(argv[i], "r") ; mclx* cl = mclxRead(xf, EXIT_ON_FAIL) ; mclxCatPush(&stck_g, cl, NULL, NULL, mclxCBdomStack, NULL, "dummy-integrate", n_cls++) ; } integrate_results(&stck_g) ; if (xfstack) mclxCatWrite(xfstack, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; if (xfcone) mclxCatConify(&stck_g) , mclxCatWrite(xfcone, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; return 0 ; } for (i=a;i<argc;i++) { if (get_interface(NULL, argv[1], shared->str, argv[i], NULL, 0, RETURN_ON_FAIL)) mcxDie(1, me, "error while testing mcl options viability (%s)", argv[i]) ; } mcxLog(MCX_LOG_APP, me, "pid %ld", (long) getpid()) /* make sure clusters align with this cluster * status: does not seem promising. */ ; if (xfctrl) clctrl = mclxRead(xfctrl, EXIT_ON_FAIL) ; /* * Below: compute cl and mxbase. */ ; if (xfcl) { cl = mclxRead(xfcl, EXIT_ON_FAIL) ; write_clustering (cl, NULL, xfcone, xfstack, plexprefix, multiplex_idx++, NULL) ; if (subcluster_g || dispatch_g) mclxCatPush(&stck_g, cl, NULL, NULL, mclxCBdomStack, NULL, "dummy-mclcm", n_cls++) ; mcxIOfree(&xfcl) ; if (!b1opts && !b2opts) b1opts = "" ; mxbase = get_base(argv[1], NULL, b1opts, b2opts) ; } else { mcxbits CACHE = b1opts || b2opts ? ALG_CACHE_INPUT /* cache, transform later */ : ALG_CACHE_START ; get_interface ( &mlp , argv[1] , shared->str , a < argc ? argv[a] : NULL , NULL , CACHE , EXIT_ON_FAIL ) ; if (a < argc) a++ ; if ((status = mclAlgorithm(mlp)) == STATUS_FAIL) { mcxErr(me, "failed at initial run") ; exit(1) ; } cl_coarse = mclAlgParamRelease(mlp, mlp->cl_result) ; cl_coarse = control_test(cl_coarse, clctrl) ; write_clustering (cl_coarse, NULL, xfcone, xfstack, plexprefix, multiplex_idx++, mlp) ; if (subcluster_g || dispatch_g) mclxCatPush(&stck_g, cl_coarse, NULL, NULL, mclxCBdomStack, NULL, "dummy-mclcm", n_cls++) ; cl = cl_coarse ; n_ite++ ; if (b1opts || b2opts) { mclx* mx_input = mclAlgParamRelease(mlp, mlp->mx_input) ; mxbase = get_base(NULL, mx_input, b1opts, b2opts) /* ^ get_base frees mx_input */ ; } else mxbase = mclAlgParamRelease(mlp, mlp->mx_start) ; } clprev = cl ; mclAlgParamFree(&mlp, TRUE) ; if (xfbase) { dim nre = mclxNrofEntries(mxbase) ; mcxLog(MCX_LOG_APP, me, "base has %lu entries", (ulong) nre) ; mclxaWrite(mxbase, xfbase, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; mcxIOclose(xfbase) ; } if (subcluster_g || dispatch_g) iaf = iaf ? 1/iaf : 1.414 ; while ( (!dispatch_g && (!N || n_ite < N)) || (dispatch_g && a < argc) ) { mclx* mx_coarse = NULL, *clnext = NULL ; dim dist_new_prev = 0, dist_prev_new = 0 ; mclx* clnew = NULL ; mcxbool faith = FALSE ; double inflation = -1.0 ; if (subcluster_g) mx_coarse = subclusterx_g ? mclxBlockPartition(mxbase, clprev, 50) : mclxBlockUnion(mxbase, clprev) /* have to copy mxbase as mx_coarse is freed. * Even if it were not freed, it is probably transformed. */ ; else if (dispatch_g) mx_coarse = mclxCopy(mxbase) ; else { mx_coarse = get_coarse(mxbase, clprev, add_transpose) ; if (n_ite == 1) { mclx* cc = clmUGraphComponents(mx_coarse, NULL) /* fixme; mx_coarse garantueed UD ? */ ; n_components = N_COLS(cc) ; mclxFree(&cc) ; } } if (xfcoarse) write_coarse(xfcoarse, mx_coarse) ; get_interface ( &mlp , NULL , shared->str , a < argc ? argv[a] : NULL , mx_coarse , ALG_CACHE_START , EXIT_ON_FAIL ) ; inflation = mlp->mpp->mainInflation ; BIT_OFF(mlp->modes, ALG_DO_SHOW_PID | ALG_DO_SHOW_JURY) ; if ((status = mclAlgorithm(mlp)) == STATUS_FAIL) { mcxErr(me, "failed") ; mcxExit(1) ; } cl_coarse = mclAlgParamRelease(mlp, mlp->cl_result) ; if (xfcoarse) mclxaWrite(cl_coarse, xfcoarse, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; if (dispatch_g || subcluster_g) clnext = cl_coarse ; else clnext = mclxCompose(clprev, cl_coarse, 0) , clnext = control_test(clnext, clctrl) , mclxFree(&cl_coarse) ; clmSJDistance (clprev, clnext, NULL, NULL, &dist_prev_new, &dist_new_prev) ; if (dist_prev_new + dist_new_prev) { write_clustering (clnext, clprev, xfcone, xfstack, plexprefix, multiplex_idx++, mlp) ; clnew = clnext ; if (subcluster_g || dispatch_g) mclxCatPush(&stck_g, clnext, NULL, NULL, mclxCBdomStack, NULL, "dummy-mclcm", n_cls++) ; else mclxFree(&clprev) ; clprev = clnew ; } else if ( N_COLS(clnext) > n_components && inflation * iaf > 1.2 && inflation * iaf < 10 ) { mclxFree(&clnext) ; inflation *= iaf ; mcxTingPrintAfter(shared, " -I %.2f", inflation) ; mcxLog(MCX_LOG_APP, me, "setting inflation to %.2f", inflation) ; faith = TRUE ; } /* i.e. vanilla mode, contraction */ else if (!subcluster_g && !dispatch_g) { mclx* cc ; mclxFree(&clnext) ; mclxAddTranspose(mx_coarse, 1.0) ; cc = clmUGraphComponents(mx_coarse, NULL) ; if (N_COLS(cc) < N_COLS(clprev)) { mclx* ccback = mclxCompose(clprev, cc, 0) ; write_clustering (ccback, clprev, xfcone, xfstack, plexprefix, multiplex_idx++, NULL) ; mclxFree(&clprev) ; clprev = ccback ; mcxTell(me, "connected components added as root clustering") ; } if (root && N_COLS(cc) > 1) { mclx* root = mclxCartesian ( mclvCanonical(NULL, 1, 0) , mclvCopy(NULL, mxbase->dom_cols) , 1.0 ) ; write_clustering (root, clprev, xfcone, xfstack, plexprefix, multiplex_idx++, NULL) ; mclxFree(&clprev) ; mcxTell(me, "universe added as root clustering") ; clprev = root ; clnew = NULL ; } mclxFree(&cc) ; } else if (subcluster_g || dispatch_g) mclxFree(&clnext) ; mclAlgParamFree(&mlp, TRUE) /* frees mx_coarse */ ; if (!clnew && !faith) { same = TRUE ; break ; } a++ ; if (dispatch_g && a == argc) break ; n_ite++ ; } if (same) mcxLog(MCX_LOG_MODULE, me, "no further contraction: halting") ; if (dispatch_g) integrate_results(&stck_g) ; else if (subcluster_g) mclxCatReverse(&stck_g) ; if (dispatch_g || subcluster_g) { dim j ; if (xfstack) mclxCatWrite(xfstack, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; if (xfcone && ! mclxCatConify(&stck_g)) mclxCatWrite(xfcone, &stck_g, MCLXIO_VALUE_NONE, RETURN_ON_FAIL) ; for (j=0;j<stck_g.n_level;j++) { mclxAnnot* an = stck_g.level+j ; mclxFree(&an->mx) ; } mcxFree(stck_g.level) ; } mcxIOfree(&xfcoarse) ; mcxIOfree(&xfbase) ; mcxIOfree(&xfcone) ; mcxIOfree(&xfstack) ; mcxTingFree(&shared) ; if (!dispatch_g && !subcluster_g) /* fixme fixme fixme */ mclxFree(&clprev) ; mclxFree(&mxbase) ; mclvFree(&start_col_sums_g) ; mcxTingFree(&cline) ; helpful_reminder() ; return STATUS_OK ; }
static mcxstatus mateMain ( int argc_unused cpl__unused , const char* argv[] ) { mcxIO* xfx, *xfy ; mclx* mx, *my, *meet, *teem, *myt ; dim x, y ; mcxIOopen(xfout, EXIT_ON_FAIL) ; xfx = mcxIOnew(argv[0], "r") ; mx = mclxRead(xfx, EXIT_ON_FAIL) ; mcxIOclose(xfx) ; xfy = mcxIOnew(argv[1], "r") ; my = mclxRead(xfy, EXIT_ON_FAIL) ; myt = mclxTranspose(my) ; if (!MCLD_EQUAL(mx->dom_rows, my->dom_rows)) mcxDie(1, me, "domains are not equal") ; meet= mclxCompose(myt, mx, 0, 0) /* fixme thread interface */ ; teem= mclxTranspose(meet) ; if (legend) fprintf ( xfout->fp , "%-10s %6s %6s %6s %6s %6s %6s %6s\n" , "overlap" , "x-idx" , "y-idx" , "meet" , "xdiff" , "ydiff" , "x-size" , "y-size" ) ; for (x=0;x<N_COLS(meet);x++) { mclv* xvec = meet->cols+x ; long X = xvec->vid ; long xsize = mx->cols[x].n_ivps ; if (one2many && xvec->n_ivps < 2) continue ; for (y=0;y<N_COLS(teem);y++) { mclv* yvec = teem->cols+y ; long Y = yvec->vid ; long ysize = my->cols[y].n_ivps ; double twinfac ; long meetsize ; mclp* ivp = mclvGetIvp(yvec, X, NULL) ; if (!ivp) continue /* * meet size, left diff, right diff, right size. */ ; meetsize = ivp->val ; if (!xsize && !ysize) /* paranoia */ continue ; twinfac = 2 * meetsize / ( (double) (xsize + ysize) ) ; if (xfout) fprintf ( xfout->fp , "%-10.3f %6ld %6ld %6ld %6ld %6ld %6ld %6ld\n" , twinfac , X , Y , meetsize , xsize - meetsize , ysize - meetsize , xsize , ysize ) ; } } return STATUS_OK ; }
int main ( int argc , const char* argv[] ) { mcxIO* xf_tab = NULL ; mcxIO* xf_tabr = NULL ; mcxIO* xf_tabc = NULL ; mcxIO* xf_restrict_tab = NULL ; mcxIO* xf_restrict_tabr = NULL ; mcxIO* xf_restrict_tabc = NULL ; mcxIO* xf_mx = mcxIOnew("-", "r") ; mcxIO* xfout = NULL ; const char* fndump = "-" ; mclTab* tabr = NULL ; mclTab* tabc = NULL ; mclTab* restrict_tabr = NULL ; mclTab* restrict_tabc = NULL ; mcxbool transpose = FALSE ; mcxbool lazy_tab = FALSE ; mcxbool write_tabc = FALSE ; mcxbool write_tabr = FALSE ; mcxbool cat = FALSE ; mcxbool tree = FALSE ; mcxbool skel = FALSE ; mcxbool newick = FALSE ; mcxbits newick_bits = 0 ; mcxbits cat_bits = 0 ; dim catmax = 1 ; dim n_max = 0 ; dim table_nlines = 0 ; dim table_nfields = 0 ; int split_idx = 1 ; int split_inc = 1 ; const char* split_stem = NULL ; const char* sort_mode = NULL ; mcxTing* line = mcxTingEmpty(NULL, 10) ; mcxbits modes = MCLX_DUMP_VALUES ; mcxbits mode_dump = MCLX_DUMP_PAIRS ; mcxbits mode_part = 0 ; mcxbits mode_loop = MCLX_DUMP_LOOP_ASIS ; mcxbits mode_matrix = 0 ; int digits = MCLXIO_VALUE_GETENV ; mcxOption* opts, *opt ; mcxstatus parseStatus = STATUS_OK ; mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; mclxIOsetQMode("MCLXIOVERBOSITY", MCL_APP_VB_YES) ; mclx_app_init(stderr) ; mcxOptAnchorSortById(options, sizeof(options)/sizeof(mcxOptAnchor) -1) ; opts = mcxOptParse(options, (char**) argv, argc, 1, 0, &parseStatus) ; if (!opts) exit(0) ; for (opt=opts;opt->anch;opt++) { mcxOptAnchor* anch = opt->anch ; switch(anch->id) { case MY_OPT_HELP : case MY_OPT_APROPOS : mcxOptApropos(stdout, me, syntax, 0, 0, options) ; return 0 ; case MY_OPT_VERSION : app_report_version(me) ; return 0 ; case MY_OPT_TAB : xf_tab = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_TABC : xf_tabc = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_TABR : xf_tabr = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_OUTPUT : fndump = opt->val ; break ; case MY_OPT_SEP_LEAD : sep_lead_g = opt->val ; break ; case MY_OPT_SEP_FIELD : sep_row_g = opt->val ; break ; case MY_OPT_SEP_CAT : sep_cat_g = opt->val ; break ; case MY_OPT_SEP_VAL : sep_val_g = opt->val ; break ; case MY_OPT_PREFIXC : prefixc_g = opt->val ; break ; case MY_OPT_RESTRICT_TAB : xf_restrict_tab = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_RESTRICT_TABC : xf_restrict_tabc = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_RESTRICT_TABR : xf_restrict_tabr = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_LAZY_TAB : lazy_tab = TRUE ; break ; case MY_OPT_NO_VALUES : BIT_OFF(modes, MCLX_DUMP_VALUES) ; break ; case MY_OPT_DUMP_RLINES : mode_dump = MCLX_DUMP_LINES ; BIT_ON(modes, MCLX_DUMP_NOLEAD) ; break ; case MY_OPT_DUMP_VLINES : mode_dump = MCLX_DUMP_LINES ; BIT_ON(modes, MCLX_DUMP_LEAD_VALUE) ; break ; case MY_OPT_DUMP_LINES : mode_dump = MCLX_DUMP_LINES ; break ; case MY_OPT_OMIT_EMPTY : BIT_ON(modes, MCLX_DUMP_OMIT_EMPTY) ; break ; case MY_OPT_SORT : sort_mode = opt->val ; break ; case MY_OPT_NO_LOOPS : mode_loop = MCLX_DUMP_LOOP_NONE ; break ; case MY_OPT_CAT_LIMIT : n_max = atoi(opt->val) ; break ; case MY_OPT_SPLIT_STEM : split_stem = opt->val ; sep_cat_g = NULL ; break ; case MY_OPT_FORCE_LOOPS : mode_loop = MCLX_DUMP_LOOP_FORCE ; break ; case MY_OPT_SKEL : skel = TRUE ; break ; case MY_OPT_WRITE_TABC : write_tabc = TRUE ; break ; case MY_OPT_DIGITS : digits = strtol(opt->val, NULL, 10) ; break ; case MY_OPT_WRITE_TABR : write_tabr = TRUE ; break ; case MY_OPT_DUMP_RDOM : transpose = TRUE ; skel = TRUE ; mode_dump = MCLX_DUMP_LINES ; break ; case MY_OPT_DUMP_CDOM : skel = TRUE ; mode_dump = MCLX_DUMP_LINES ; break ; case MY_OPT_IMX : mcxIOnewName(xf_mx, opt->val) ; break ; case MY_OPT_ICL : mcxIOnewName(xf_mx, opt->val) ; mode_dump = MCLX_DUMP_LINES ; BIT_ON(modes, MCLX_DUMP_NOLEAD) ; BIT_OFF(modes, MCLX_DUMP_VALUES) ; break ; case MY_OPT_TREECAT : mcxIOnewName(xf_mx, opt->val) ; tree = TRUE ; cat_bits |= MCLX_PRODUCE_DOMSTACK ; break ; case MY_OPT_CAT : mcxIOnewName(xf_mx, opt->val) ; cat = TRUE ; break ; case MY_OPT_DUMP_MATRIX : mode_matrix |= MCLX_DUMP_MATRIX ; break ; case MY_OPT_TRANSPOSE : transpose = TRUE ; break ; case MY_OPT_DUMP_UPPER : mode_part = MCLX_DUMP_PART_UPPER ; break ; case MY_OPT_DUMP_UPPERI : mode_part = MCLX_DUMP_PART_UPPERI ; break ; case MY_OPT_DUMP_LOWER : mode_part = MCLX_DUMP_PART_LOWER ; break ; case MY_OPT_DUMP_LOWERI : mode_part = MCLX_DUMP_PART_LOWERI ; break ; case MY_OPT_DUMP_NOLEAD : BIT_ON(modes, MCLX_DUMP_NOLEAD) ; break ; case MY_OPT_NEWICK_MODE : if (strchr(opt->val, 'N')) newick_bits |= (MCLX_NEWICK_NONL | MCLX_NEWICK_NOINDENT) ; if (strchr(opt->val, 'I')) newick_bits |= MCLX_NEWICK_NOINDENT ; if (strchr(opt->val, 'B')) newick_bits |= MCLX_NEWICK_NONUM ; if (strchr(opt->val, 'S')) newick_bits |= MCLX_NEWICK_NOPTHS ; newick = TRUE ; break ; case MY_OPT_DUMP_NEWICK : newick = TRUE ; break ; case MY_OPT_DUMP_TABLE : mode_dump = MCLX_DUMP_TABLE ; break ; case MY_OPT_TABLE_NFIELDS : table_nfields = atoi(opt->val) ; break ; case MY_OPT_TABLE_NLINES : table_nlines = atoi(opt->val) ; break ; case MY_OPT_DUMP_PAIRS : mode_dump = MCLX_DUMP_PAIRS ; break ; } } ; if (skel) cat_bits |= MCLX_READ_SKELETON ; modes |= mode_loop | mode_dump | mode_part | mode_matrix ; xfout = mcxIOnew(fndump, "w") ; mcxIOopen(xfout, EXIT_ON_FAIL) ; mcxIOopen(xf_mx, EXIT_ON_FAIL) ; if (cat || tree) catmax = n_max ? n_max : 0 ; if ((write_tabc || write_tabr) && !xf_tab) mcxDie(1, me, "need a single tab file (-tab option) with --write-tabc or --write-tabr") ; if (xf_tab && mcxIOopen(xf_tab, RETURN_ON_FAIL)) mcxDie(1, me, "no tab") ; else { if (xf_tabr && mcxIOopen(xf_tabr, RETURN_ON_FAIL)) mcxDie(1, me, "no tabr") ; if (xf_tabc && mcxIOopen(xf_tabc, RETURN_ON_FAIL)) mcxDie(1, me, "no tabc") ; } { if (xf_restrict_tab && mcxIOopen(xf_restrict_tab, RETURN_ON_FAIL)) mcxDie(1, me, "no restriction tab") ; else { if (xf_restrict_tabr && mcxIOopen(xf_restrict_tabr, RETURN_ON_FAIL)) mcxDie(1, me, "no restriction tabr") ; if (xf_restrict_tabc && mcxIOopen(xf_restrict_tabc, RETURN_ON_FAIL)) mcxDie(1, me, "no restriction tabc") ; } /* fixme: below is pretty boilerplate, happens in other places as well */ if (xf_restrict_tab) { if (!(restrict_tabr = mclTabRead (xf_restrict_tab, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading restriction tab") ; restrict_tabc = restrict_tabr ; mcxIOclose(xf_restrict_tab) ; } else { if (xf_restrict_tabr) { if (!(restrict_tabr = mclTabRead(xf_restrict_tabr, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading restriction tabr") ; mcxIOclose(xf_restrict_tabr) ; } if (xf_restrict_tabc) { if (!(restrict_tabc = mclTabRead(xf_restrict_tabc, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading restriction tabc") ; mcxIOclose(xf_restrict_tabc) ; } } } /* fixme: restructure code to include bit below */ if (write_tabc || write_tabr) { mclv* dom_cols = mclvInit(NULL) ; mclv* dom_rows = mclvInit(NULL) ; mclv* dom = write_tabc ? dom_cols : dom_rows ; if (!(tabc = mclTabRead(xf_tab, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading tab file") ; if (mclxReadDomains(xf_mx, dom_cols, dom_rows)) mcxDie(1, me, "error reading matrix file") ; mcxIOclose(xf_mx) /* fixme check status */ ; mclTabWrite(tabc, xfout, dom, RETURN_ON_FAIL) ; mcxIOclose(xfout) ; return 0 ; } if (newick) { mcxTing* thetree ; mclxCat cat ; if (xf_tab && !(tabr = mclTabRead(xf_tab, NULL, RETURN_ON_FAIL))) mcxDie(1, me, "error reading tab file") ; mclxCatInit(&cat) ; if ( mclxCatRead ( xf_mx , &cat , 0 , NULL , tabr ? tabr->domain : NULL , MCLX_CATREAD_CLUSTERTREE | MCLX_ENSURE_ROOT ) ) mcxDie(1, me, "failure reading file") ; thetree = mclxCatNewick(&cat, tabr, newick_bits) ; fwrite(thetree->str, 1, thetree->len, xfout->fp) ; fputc('\n', xfout->fp) ; mcxIOclose(xfout) ; return 0 ; } while (1) { mclxIOdumper dumper ; mclxCat cat ; dim i ; if (xf_tab && !lazy_tab) cat_bits |= MCLX_REQUIRE_GRAPH ; mclxCatInit(&cat) ; if (mclxCatRead(xf_mx, &cat, catmax, NULL, NULL, cat_bits)) break ; for (i=0;i<cat.n_level;i++) { mclx* mx = cat.level[i].mx ; if (restrict_tabr || restrict_tabc) { mclx* sub ; sub = mclxSub ( mx , restrict_tabc ? restrict_tabc->domain : mx->dom_cols , restrict_tabr ? restrict_tabr->domain : mx->dom_rows ) ; mx = sub ; } /* noteme fixme dangersign mx now may violate some 'cat' invariant */ if (sort_mode) { if (!strcmp(sort_mode, "size-ascending")) mclxColumnsRealign(mx, mclvSizeCmp) ; else if (!strcmp(sort_mode, "size-descending")) mclxColumnsRealign(mx, mclvSizeRevCmp) ; else mcxErr(me, "unknown sort mode <%s>", sort_mode) ; if (catmax != 1) mcxErr(me, "-sort option and cat mode may fail or corrupt") ; } if (xf_tab && !tabr) { if (!( tabr = mclTabRead (xf_tab, lazy_tab ? NULL : mx->dom_rows, RETURN_ON_FAIL) ) ) mcxDie(1, me, "consider using --lazy-tab option") ; tabc = tabr ; mcxIOclose(xf_tab) ; } else { if (!tabr && xf_tabr) { if (!(tabr = mclTabRead (xf_tabr, lazy_tab ? NULL : mx->dom_rows, RETURN_ON_FAIL) ) ) mcxDie(1, me, "consider using --lazy-tab option") ; mcxIOclose(xf_tabr) ; } if (!tabc && xf_tabc) { if (!( tabc = mclTabRead (xf_tabc, lazy_tab ? NULL : mx->dom_cols, RETURN_ON_FAIL) ) ) mcxDie(1, me, "consider using --lazy-tab option") ; mcxIOclose(xf_tabc) ; } } ; if (transpose) { mclx* tp = mclxTranspose(mx) ; mclxFree(&mx) ; mx = tp ; if (tabc || tabr) { mclTab* tabt = tabc ; tabc = tabr ; tabr = tabt ; } } if (mode_dump == MCLX_DUMP_TABLE) BIT_ON(modes, MCLX_DUMP_TABLE_HEADER) ; mclxIOdumpSet(&dumper, modes, sep_lead_g, sep_row_g, sep_val_g) ; dumper.table_nlines = table_nlines ; dumper.table_nfields = table_nfields ; dumper.prefixc = prefixc_g ; if (split_stem) { mcxTing* ting = mcxTingPrint(NULL, "%s.%03d", split_stem, split_idx) ; mcxIOclose(xfout) ; mcxIOrenew(xfout, ting->str, "w") ; split_idx += split_inc ; } if ( mclxIOdump ( mx , xfout , &dumper , tabc , tabr , digits , RETURN_ON_FAIL ) ) mcxDie(1, me, "something suboptimal") ; mclxFree(&mx) ; if (sep_cat_g && i+1 < cat.n_level) fprintf(xfout->fp, "%s\n", sep_cat_g) ; } break ; } mcxIOfree(&xf_mx) ; mcxIOfree(&xfout) ; mcxIOfree(&xf_tab) ; mcxIOfree(&xf_tabr) ; mcxIOfree(&xf_tabc) ; mcxTingFree(&line) ; return 0 ; }
int main ( int argc , const char* argv[] ) { mcxIO* xfdagreduce = NULL, *xfattr = NULL, *xfdiff = NULL ; double child_diff_lq = 0.2 ; double parent_diff_gq = 0.4 ; mcxIO* xfimx = mcxIOnew("-", "r"), *xfdag = NULL, *xftab = NULL ; mclTab* tab = NULL ; int q = -1 ; mclx* mx ; unsigned char test_mode = 0 ; mcxstatus parseStatus = STATUS_OK ; mcxOption* opts, *opt ; mcxOptAnchorSortById(options, sizeof(options)/sizeof(mcxOptAnchor) -1) ; if (!(opts = mcxOptParse(options, (char**) argv, argc, 1, 0, &parseStatus))) exit(0) ; mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; mclxIOsetQMode("MCLXIOVERBOSITY", MCL_APP_VB_YES) ; mclx_app_init(stderr) ; for (opt=opts;opt->anch;opt++) { mcxOptAnchor* anch = opt->anch ; switch(anch->id) { case MY_OPT_HELP : mcxOptApropos(stdout, me, syntax, 0, 0, options) ; return 0 ; case MY_OPT_VERSION : app_report_version(me) ; return 0 ; case MY_OPT_TEST_CYCLE : test_mode = 'c' ; break ; case MY_OPT_TEST_CROSS : test_mode = 'x' ; break ; case MY_OPT_DAG_ATTR : xfattr = mcxIOnew(opt->val, "w") ; mcxIOopen(xfattr, EXIT_ON_FAIL) ; break ; case MY_OPT_DAG_DIFF : xfdiff = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_DAG_REDUCE : xfdagreduce = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_CHILD_DIFF_LQ : child_diff_lq = atof(opt->val) ; break ; case MY_OPT_PARENT_DIFF_GQ : parent_diff_gq = atof(opt->val) ; break ; case MY_OPT_QUERY : q = atoi(opt->val) ; break ; case MY_OPT_TAB : xftab = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_IMX : mcxIOnewName(xfimx, opt->val) ; break ; } } ; if (xfimx) mx = mclxRead(xfimx, EXIT_ON_FAIL) ; else mcxDie(1, me, "need -imx") ; if (xftab) tab = mclTabRead(xftab, mx->dom_cols, EXIT_ON_FAIL) ; if (test_mode == 'c') test_for_cycles(mx) ; else if (test_mode == 'x') test_cross_ratio(mx) ; else if (xfattr) get_attr(mx, tab, xfattr) ; else if (xfdagreduce) { mclxComposeHelper* ch = mclxComposePrepare(mx, mx) ; dim i ; for (i=0;i<N_COLS(mx);i++) { mclv* in = mx->cols+i ; mclv* out = mclxVectorCompose(mx, in, NULL, ch) ; mcldMinus(in, out, in) ; mclvFree(&out) ; } mclxWrite(mx, xfdagreduce, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; mclxComposeRelease(&ch) ; } else if (xfdiff) dag_diff_select(mx, tab, xfdiff, child_diff_lq, parent_diff_gq) ; mclxFree(&mx) ; mcxIOfree(&xfimx) ; mcxIOfree(&xfdag) ; mcxIOfree(&xfattr) ; mcxIOfree(&xfdagreduce) ; return 0 ; }
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 ; }
static dim do_a_file ( aggr** collectpp , const char* fname , dim collect_n ) { mcxIO* xf = mcxIOnew(fname, "r") ; mcxTing* buf = mcxTingEmpty(NULL, 100) ; mcxTing* lbl = mcxTingEmpty(NULL, 100) ; mcxstatus status = STATUS_OK ; aggr* collect = *collectpp ; dim ct = 0, collect_alloc = 0 ; if (!collect_n) collect_alloc = 100 , collect = mcxNAlloc(collect_alloc, sizeof collect[0], NULL, EXIT_ON_FAIL) ; mcxIOopen(xf, EXIT_ON_FAIL) ; while (STATUS_OK == (status = mcxIOreadLine(xf, buf, MCX_READLINE_CHOMP))) { double val ; const char* tabchar = NULL ; mcxbool get_header = collect_g != 'p' && !ct ? TRUE : FALSE ; mcxTingEnsure(lbl, buf->len) /* if header_g && !ct && !paste create/check label */ /* body of this while loop does too many things, refactor */ ; if (collect_g == 'p' || get_header) { if (!(tabchar = strchr(buf->str, '\t'))) mcxDie(1, me, "paste error at line %d file %s (no tab)", (int) xf->lc, fname) ; mcxTingNWrite(lbl, buf->str, tabchar - buf->str) ; } else { if (2 != sscanf(buf->str, "%s%lg", lbl->str, &val)) mcxDie(1, me, "parse error at line %d file %s", (int) xf->lc, fname) ; lbl->len = strlen(lbl->str) ; } if (!collect_n) { if (ct >= collect_alloc) { dim collect_realloc = collect_alloc * 1.44 ; collect = mcxNRealloc(collect, collect_realloc, collect_alloc, sizeof collect[0], NULL, EXIT_ON_FAIL) ; collect_alloc = collect_realloc ; } collect[ct].label = mcxTingStr(lbl) ; collect[ct].val = collect_g == 'p' || get_header ? 0.0 : val ; collect[ct].columns = collect_g == 'p' || get_header ? mcxTingNew(tabchar + (get_header ? 1 : 0)) : NULL ; } else { if (ct >= collect_n) mcxDie(1, me, "additional lines in file %s", fname) ; if (strcmp(collect[ct].label, lbl->str)) mcxDie ( 1 , me , "label conflict %s/%s at line %d in file %s" , collect[ct].label , lbl->str , (int) xf->lc, fname ) ; if (get_header) /* only need to check identity */ { if (strcmp(tabchar+1, collect[ct].columns->str)) mcxDie(1, me, "different columns <%s> and <%s>", collect[ct].columns->str, tabchar+1) ; } else if (collect_g == 'p') /* tack it on */ mcxTingNAppend(collect[ct].columns, tabchar, buf->len - lbl->len) ; else collect[ct].val += val ; } ct++ ; } if (collect_n) { if (ct != collect_n) mcxDie(1, me, "not enough lines in file %s", fname) ; } else { if (!ct) mcxDie(1, me, "empty file(s)") ; *collectpp = collect ; } mcxIOfree(&xf) ; return ct ; }
int main ( int argc , const char* argv[] ) { mcxIO* xfmx = mcxIOnew("-", "r"), *xfout = mcxIOnew("-", "w") ; mclx* mx = NULL ; mclv* mx_diag = NULL ; mcxstatus parseStatus = STATUS_OK ; mcxOption* opts, *opt ; dim N_edge = 0 ; dim* offsets ; dim template_n_nodes = 0 ; mcxbool plus = FALSE ; double e_min = 1.0 ; double e_max = 0.0 ; double skew = 0.0 ; double radius = 0.0 ; double n_sdev = 0.5 ; double n_range = 2.0 ; double g_radius = 0.0 ; double g_mean = 0.0 ; double g_sdev = 0.0 ; double g_min = 1.0 ; double g_max = 0.0 ; mcxbool do_gaussian = FALSE ; dim i = 0 ; dim N_remove = 0 ; dim N_add = 0 ; dim N_shuffle = 0 ; unsigned long random_ignore = 0 ; srandom(mcxSeed(2308947)) ; mcxOptAnchorSortById(options, sizeof(options)/sizeof(mcxOptAnchor) -1) ; if (!(opts = mcxOptParse(options, (char**) argv, argc, 1, 0, &parseStatus))) exit(0) ; mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; mclxIOsetQMode("MCLXIOVERBOSITY", MCL_APP_VB_YES) ; mclx_app_init(stderr) ; for (opt=opts;opt->anch;opt++) { mcxOptAnchor* anch = opt->anch ; switch(anch->id) { case MY_OPT_HELP : case MY_OPT_APROPOS : mcxOptApropos(stdout, me, syntax, 20, MCX_OPT_DISPLAY_SKIP, options) ; return 0 ; case MY_OPT_VERSION : app_report_version(me) ; return 0 ; case MY_OPT_SKEW : skew = atof(opt->val) ; break ; case MY_OPT_GEN : template_n_nodes = atoi(opt->val) ; break ; case MY_OPT_IMX : mcxIOrenew(xfmx, opt->val, NULL) ; break ; case MY_OPT_PLUS : case MY_OPT_WB : plus = TRUE ; break ; case MY_OPT_OUT : mcxIOrenew(xfout, opt->val, NULL) ; break ; case MY_OPT_E_MAX : if (!strcmp(opt->val, "copy")) e_max = -DBL_MAX ; else e_max = atof(opt->val) ; break ; case MY_OPT_E_MIN : e_min = atof(opt->val) ; break ; case MY_OPT_G_MIN : g_min = atof(opt->val) ; break ; case MY_OPT_G_MAX : g_max = atof(opt->val) ; break ; case MY_OPT_G_SDEV : g_sdev = atof(opt->val) ; break ; case MY_OPT_G_MEAN : g_mean = atof(opt->val) ; do_gaussian = TRUE ; break ; case MY_OPT_G_RADIUS : g_radius = atof(opt->val) ; break ; case MY_OPT_N_RANGE : n_range = atof(opt->val) ; break ; case MY_OPT_N_SDEV : n_sdev = atof(opt->val) ; break ; case MY_OPT_N_RADIUS : radius = atof(opt->val) ; break ; case MY_OPT_SHUFFLE : N_shuffle = atoi(opt->val) ; break ; case MY_OPT_ADD : N_add = atoi(opt->val) ; break ; case MY_OPT_REMOVE : N_remove = atoi(opt->val) ; break ; } } /* hitting y% in vi tells me the size of this block */ { if (template_n_nodes) mx = mclxAllocZero ( mclvCanonical(NULL, template_n_nodes, 1.0) , mclvCanonical(NULL, template_n_nodes, 1.0) ) ; else mx = mclxReadx ( xfmx , EXIT_ON_FAIL , MCLX_REQUIRE_GRAPH ) ; mx_diag = mclxDiagValues(mx, MCL_VECTOR_COMPLETE) ; if (N_shuffle) mclxAdjustLoops(mx, mclxLoopCBremove, NULL) ; else mclxSelectUpper(mx) /* ^ apparently we always work on single arc representation (docme andsoon) */ ; offsets = mcxAlloc(sizeof offsets[0] * N_COLS(mx), EXIT_ON_FAIL) ; N_edge = 0 ; for (i=0;i<N_COLS(mx);i++) { offsets[i] = N_edge ; N_edge += mx->cols[i].n_ivps ; } if (N_edge < N_remove) { mcxErr ( me , "removal count %ld exceeds edge count %ld" , (long) N_remove , (long) N_edge ) ; N_remove = N_edge ; } random_ignore = RAND_MAX - (N_edge ? RAND_MAX % N_edge : 0) ; if (RAND_MAX / 2 < N_edge) mcxDie(1, me, "graph too large!") ; if (N_shuffle) { do_the_shuffle(mx, N_shuffle, offsets, N_edge, random_ignore) ; mx_readd_diagonal(mx, mx_diag) ; mclxWrite(mx, xfout, MCLXIO_VALUE_GETENV, RETURN_ON_FAIL) ; exit(0) ; } ; if (N_remove) { dim n_remove = do_remove(mx, N_remove, offsets, N_edge, random_ignore) /* Need to recompute N_edge and random_ignore. * NOTE we work with *upper* matrix; this counts graph edges. */ ; N_edge = mclxNrofEntries(mx) - n_remove ; random_ignore = RAND_MAX - (RAND_MAX % N_COLS(mx)) ; } if (g_mean) { if (!g_radius) { if (g_sdev) g_radius = 2 * g_sdev ; mcxWarn(me, "set radius to %.5f\n", g_radius) ; } } ; if (N_add) N_edge += do_add ( mx , N_add , N_edge , do_gaussian ? &g_mean : NULL, g_radius , g_sdev , g_min , g_max , skew , e_min , e_max ) ; if (radius) { for (i=0;i<N_COLS(mx);i++) { mclp* ivp = mx->cols[i].ivps, *ivpmax = ivp + mx->cols[i].n_ivps ;if(DEBUG)fprintf(stderr, "here %d\n", (int) i) ; while (ivp < ivpmax) { double val = ivp->val ; double r = mcxNormalCut(n_range * n_sdev, n_sdev) ; double newval = val + radius * (r / (n_range * n_sdev)) ; if (e_min < e_max && newval >= e_min && newval <= e_max) ; ivp->val = newval ; ivp++ ; } } } mclxUnary(mx, fltxCopy, NULL) /* remove zeroes */ ; mclxAddTranspose(mx, 0.0) ; mx_readd_diagonal(mx, mx_diag) ; if (plus) mclxbWrite(mx, xfout, RETURN_ON_FAIL) ; else mclxWrite(mx, xfout, MCLXIO_VALUE_GETENV, RETURN_ON_FAIL) ; } return 0 ; }
static mcxstatus qArgHandle ( int optid , const char* val ) { switch(optid) { case MY_OPT_IMX : mcxIOnewName(xfmx_g, val) ; user_imx = TRUE ; break ; case MY_OPT_ABC : xfabc_g = mcxIOnew(val, "r") ; break ; case MY_OPT_TAB : xftab_g = mcxIOnew(val, "r") ; break ; case MY_OPT_ICL : xfcl_g = mcxIOnew(val, "r") ; break ; case MY_OPT_TRANSFORM : transform_spec = mcxTingNew(val) ; break ; case MY_OPT_DIMENSION : mode_get = 'd' ; break ; case MY_OPT_TESTMETRIC : mode_get = 'm' ; break ; case MY_OPT_TESTCYCLE : mode_get = 'c' ; break ; case MY_OPT_TESTCYCLE_N : n_limit = atoi(val) ; mode_get = 'c' ; break ; case MY_OPT_INFO : compute_flags |= COMPUTE_EFF ; break ; case MY_OPT_CLCF : compute_flags |= COMPUTE_CLCF ; break ; case MY_OPT_REDUCE : rebase_g = FALSE ; break ; case MY_OPT_THREAD : n_thread_l = atoi(val) ; break ; case MY_OPT_NODE : mode_get = 'n' ; break ; case MY_OPT_FOUT : mcxIOnewName(xfout_g, val) ; break ; case MY_OPT_WEIGHT_SCALE : weight_scale = atof(val) ; break ; case MY_OPT_OUTPUT_NOLEGEND : output_flags ^= OUTPUT_KEY ; break ; case MY_OPT_OUTPUT_TABLE : output_flags |= OUTPUT_TABLE ; break ; case MY_OPT_SCALEFREE : weefreemen = TRUE ; break ; case MY_OPT_EDGEWEIGHTS : mode_get = 'e' ; break ; case MY_OPT_EDGEWEIGHTS_HIST : mode_get = 'H' ; if (4 != sscanf(val, "%d,%d,%d,%d", &vary_a, &vary_z, &vary_s, &vary_n)) mcxDie(1, me, "failed to parse argument as integers start,end,step,norm") ; break ; case MY_OPT_EDGEWEIGHTS_SORTED : mode_get = 'E' ; break ; case MY_OPT_DIVIDE : divide_g = atoi(val) ; break ; case MY_OPT_VARY_CORRELATION : vary_a = 4 ; vary_z = 20 ; vary_s = 1 ; vary_n = 20 ; weight_scale = 100 ; mode_vary = 'c' ; break ; case MY_OPT_VARY_CEIL : case MY_OPT_VARY_KNN : case MY_OPT_VARY_N : case MY_OPT_VARY_THRESHOLD : if (4 != sscanf(val, "%d,%d,%d,%d", &vary_a, &vary_z, &vary_s, &vary_n)) mcxDie(1, me, "failed to parse argument as integers start,end,step,norm") ; mode_vary = optid == MY_OPT_VARY_THRESHOLD ? 't' : optid == MY_OPT_VARY_KNN ? 'k' : optid == MY_OPT_VARY_CEIL ? 'n' : optid == MY_OPT_VARY_N ? 'l' : 'X' ; break ; default : mcxExit(1) ; ; } if (mode_vary && 1000 * vary_s < vary_z - vary_a) mcxDie(1, me, "argument leads to more than one thousand steps") ; if (!vary_n) mcxDie(1, me, "need nonzero scaling factor (last component)") ; return STATUS_OK ; }
static mcxstatus qArgHandle ( int optid , const char* val ) { switch(optid) { case MY_OPT_IMX : mcxIOnewName(xfmx_g, val) ; user_imx = TRUE ; break ; case MY_OPT_TAB : xftab_g = mcxIOnew(val, "r") ; break ; case MY_OPT_ICL : xfcl_g = mcxIOnew(val, "r") ; break ; case MY_OPT_TRANSFORM : transform_spec = mcxTingNew(val) ; break ; case MY_OPT_DIMENSION : mode_get = 'd' ; break ; case MY_OPT_TESTCYCLE : mode_get = 'c' ; break ; case MY_OPT_TESTCYCLE_N : n_limit = atoi(val) ; mode_get = 'c' ; break ; case MY_OPT_CLCF : doclcf_g = TRUE ; break ; case MY_OPT_KNNREDUCE : knnexact_g = FALSE ; break ; case MY_OPT_THREAD : n_thread_g = atoi(val) ; break ; case MY_OPT_NODE : mode_get = 'n' ; break ; case MY_OPT_FOUT : mcxIOnewName(xfout_g, val) ; break ; case MY_OPT_WEIGHT_SCALE : weight_scale = atof(val) ; break ; case MY_OPT_OUTPUT_TABLE : output_table = TRUE ; break ; case MY_OPT_MYTH : weefreemen = TRUE ; break ; case MY_OPT_EDGEWEIGHTS : mode_get = 'e' ; break ; case MY_OPT_EDGEWEIGHTS_HIST : mode_get = 'H' ; if (4 != sscanf(val, "%d,%d,%d,%d", &vary_a, &vary_z, &vary_s, &vary_n)) mcxDie(1, me, "failed to parse argument as integers start,end,step,norm") ; break ; case MY_OPT_EDGEWEIGHTS_SORTED : mode_get = 'E' ; break ; case MY_OPT_DIVIDE : divide_g = atoi(val) ; break ; case MY_OPT_VARY_CORRELATION : vary_a = 4 ; vary_z = 20 ; vary_s = 1 ; vary_n = 20 ; weight_scale = 100 ; mode_vary = 'c' ; break ; case MY_OPT_VARY_KNN : if (4 != sscanf(val, "%d,%d,%d,%d", &vary_a, &vary_z, &vary_s, &vary_n)) mcxDie(1, me, "failed to parse argument as integers start,end,step,norm") ; mode_vary = 'k' ; break ; case MY_OPT_VARY_THRESHOLD : if (4 != sscanf(val, "%u,%u,%u,%u", &vary_a, &vary_z, &vary_s, &vary_n)) mcxDie(1, me, "failed to parse argument as integers start,end,step,norm") ; mode_vary = 't' ; break ; default : mcxExit(1) ; ; } if (mode_vary && 1000 * vary_s < vary_z - vary_a) mcxDie(1, me, "argument leads to more than one thousand steps") ; if (!vary_n) mcxDie(1, me, "need nonzero scaling factor (last component)") ; return STATUS_OK ; }
static mcxstatus meetMain ( int argc , const char* argv[] ) { mcxIO **xfmcs = NULL ; mclMatrix *lft = NULL ; mclMatrix *rgt = NULL ; mclMatrix *dst = NULL ; int a = 0 ; int n_mx = 0 ; int j ; dim o, m, e ; mclxIOsetQMode("MCLXIOVERBOSITY", MCL_APP_VB_YES) ; mclx_app_init(stderr) ; xfmcs = (mcxIO**) mcxAlloc ( (argc)*sizeof(mcxIO*) , EXIT_ON_FAIL ) ; mcxIOopen(xfout, EXIT_ON_FAIL) ; for(j=a;j<argc;j++) { xfmcs[n_mx] = mcxIOnew(argv[j], "r") ; n_mx++ ; } if (!n_mx) mcxDie(1, me, "at least one clustering matrix required") /* Fixme: do a decent initialization with lft = clmTop() *before* * this loop (removing the need for ugly tmp assignment), but that requires * we know the correct domain to pass to it. For that, we need to peak into * the first matrix. */ ; for (j=0;j<n_mx;j++) { mclMatrix* tmp = mclxRead (xfmcs[j], EXIT_ON_FAIL) ; if (clmEnstrict(tmp, &o, &m, &e, ENSTRICT_SPLIT_OVERLAP)) report_partition("clmmeet", tmp, xfmcs[j]->fn, o, m, e) , mcxExit(1) ; if (!lft) { lft = tmp ; continue ; } else rgt = tmp ; if (!MCLD_EQUAL(lft->dom_rows, rgt->dom_rows)) mcxDie ( 1 , me , "domains not equal (files %s/%s)" , xfmcs[j-1]->fn->str , xfmcs[j]->fn->str ) ; mcxIOclose(xfmcs[j]) ; dst = clmMeet(lft, rgt) ; lft = dst ; mclxFree(&rgt) ; } mclxColumnsRealign(lft, mclvSizeRevCmp) ; mclxWrite(lft, xfout, MCLXIO_VALUE_NONE, EXIT_ON_FAIL) ; mclxFree(&lft) ; mcxIOfree(&xfout) ; free(xfmcs) ; return STATUS_OK ; }
/* Purpose: read a single x/y combination. The x may be cached * due to the etc format, where a single line always refers to the same x * and that x is listed only at the start or line, or omitted with * the etc-ai and 235-ai formats. * * state->x_prev may be used by read_etc in order to obtain the * current x index. */ static mcxstatus read_etc ( mcxIO* xf , stream_state *iface , etc_state *state , double* value ) { mcxbits bits = iface->bits ; FILE* stdbug = stdout ; mcxstatus status = STATUS_OK ; mcxTing* ykey = NULL ; mcxTing* xkey = NULL ; const char* printable ; mcxbool label_cbits = bits & (MCLXIO_STREAM_CTAB_STRICT | MCLXIO_STREAM_CTAB_RESTRICT) ; mcxbool label_rbits = bits & (MCLXIO_STREAM_RTAB_STRICT | MCLXIO_STREAM_RTAB_RESTRICT) ; mcxbool label_dbits = bits & (MCLXIO_STREAM_WARN | MCLXIO_STREAM_DEBUG) ; iface->statusx = STATUS_OK ; iface->statusy = STATUS_OK ; iface->x = state->x_prev ; *value = 1.0 ;if(DEBUG)fprintf(stdbug, "read_etc initially set x to %d\n", (int) iface->x) ; if (!state->etcbuf) state->etcbuf = mcxTingEmpty(NULL, 100) ; do { int n_char_read = 0 ; if (state->etcbuf->len != state->etcbuf_check) { mcxErr ( module , "read_etc sanity check failed %ld %ld" , (long) state->etcbuf->len , (long) state->etcbuf_check ) ; status = STATUS_FAIL ; break ; } /* do we need to read a line ? */ /* -> then set iface->x */ /* fixmefixme: funcify this */ /* iface->x can only be changed in this branch */ /* ************************************************************************** */ if (state->etcbuf_ofs >= state->etcbuf->len) { state->etcbuf_ofs = 0 ; state->n_y = 0 ; if ((status = mcxIOreadLine(xf, state->etcbuf, MCX_READLINE_CHOMP))) break ; state->etcbuf_check = state->etcbuf->len ; if ( !(printable = mcxStrChrAint(state->etcbuf->str, isspace, -1)) || (unsigned char) *printable == '#' ) { state->etcbuf_ofs = state->etcbuf->len ; iface->statusy = STATUS_IGNORE ; break /* fixme: ^ statusx seems to work as well. cleanify design */ ; } ; if (bits & (MCLXIO_STREAM_ETC_AI | MCLXIO_STREAM_235_AI)) { } /* In this branch we do not issue handle_label, so we take care of max_seen. */ else if (bits & MCLXIO_STREAM_235) { if (1 != sscanf(state->etcbuf->str, "%lu%n", &(iface->x), &n_char_read)) { iface->statusx = STATUS_FAIL ; break ; } state->etcbuf_ofs += n_char_read ; if (iface->map_c->max_seen+1 < iface->x+1) /* note mixed-sign comparison */ iface->map_c->max_seen = iface->x ; state->x_prev = iface->x ; } else if (bits & MCLXIO_STREAM_ETC) { xkey = mcxTingEmpty(NULL, state->etcbuf->len) ; if (1 != sscanf(state->etcbuf->str, "%s%n", xkey->str, &n_char_read)) break ; state->etcbuf_ofs += n_char_read ; xkey->len = strlen(xkey->str) ; xkey->str[xkey->len] = '\0' ;if(DEBUG3)fprintf(stderr, "max %lu\n", (ulong) iface->map_c->max_seen) ; iface->statusx = handle_label(&xkey, &(iface->x), iface->map_c, label_cbits | label_dbits, "col") ;if(DEBUG3)fprintf(stderr, "max %lu x %lu\n", (ulong) iface->map_c->max_seen, (ulong) iface->x) ; if (iface->statusx == STATUS_IGNORE || iface->statusx == STATUS_FAIL) { /* iface->x = 141414 recentlyadded */ ;if(DEBUG3)fprintf(stderr, "max %lu\n", (ulong) iface->map_c->max_seen) ; break ; } /* ^ Consider what happens when we break here (x label not * accepted) with map_c->max_seen. Basically x label is * indepedent of y, so we never need to undo the * handle_label action. */ state->x_prev = iface->x ; } else mcxDie(1, module, "strange, really") ; } /* ************************************************************************** */ if ( !( printable = mcxStrChrAint(state->etcbuf->str+state->etcbuf_ofs, isspace, -1) ) || (uchar) *printable == '#' ) { state->etcbuf_ofs = state->etcbuf->len ; /* iface->y = 141414 recentlyadded */ ; iface->statusy = STATUS_IGNORE ; break ; } if (bits & (MCLXIO_STREAM_235_AI | MCLXIO_STREAM_235)) { if (1 != sscanf(state->etcbuf->str+state->etcbuf_ofs, "%lu%n", &(iface->y), &n_char_read)) { char* s = state->etcbuf->str+state->etcbuf_ofs ; while(isspace((uchar) s[0])) s++ ; mcxErr ( module , "unexpected string starting with <%c> on line %lu" , (int) ((uchar) s[0]) , xf->lc ) ; iface->statusy = STATUS_FAIL ; } else { ;if(DEBUG3)fprintf(stdbug, "hit at %d\n", (int) state->etcbuf_ofs); state->etcbuf_ofs += n_char_read ; if (iface->map_r->max_seen+1 < iface->y+1) /* note mixed-sign comparison */ iface->map_r->max_seen = iface->y ; } } else /* ETCANY */ { ykey = mcxTingEmpty(NULL, state->etcbuf->len) ; if (1 != sscanf(state->etcbuf->str+state->etcbuf_ofs, "%s%n", ykey->str, &n_char_read)) break ; ykey->len = strlen(ykey->str) ; ykey->str[ykey->len] = '\0' ; state->etcbuf_ofs += n_char_read ; iface->statusy = handle_label(&ykey, &(iface->y), iface->map_r, label_rbits | label_dbits, "row") ; } /* this won't scale well in terms of organisation if and when * tabs are allowed with 235 mode, because in that case, * with 235-ai and restrict-tabr and extend-tabc we will * need the stuff below duplicated in the 235 branch above. * what happens here is that we only decide now whether * the auto-increment is actually happening. It depends * on there being at least one y that was not rejected. */ ; if ( (bits & (MCLXIO_STREAM_ETC_AI | MCLXIO_STREAM_235_AI)) && (iface->statusy == STATUS_OK || iface->statusy == STATUS_NEW) && !state->n_y ) { iface->x = state->x_prev + 1 /* works first time around */ ; iface->map_c->max_seen = state->x_prev + 1 ; state->n_y++ ; state->x_prev = iface->x ; } ;if(DEBUG2)fprintf(stdbug, "etc handle label we have y %d status %s\n", (int) iface->y, MCXSTATUS(iface->statusy)) ; } while (0) ;if(DEBUG2)fprintf(stdbug, "status %s\n", MCXSTATUS(status)) ; do { if (status) /* e.g. STATUS_DONE (readline) [or STATUS_IGNORE (#)]*/ break /* below iface->statusy == STATUS_NEW should be impossible * given this clause and the code sequence earlier. */ ; if (iface->statusx == STATUS_FAIL || iface->statusx == STATUS_IGNORE) { mcxTingFree(&xkey) ; status = iface->statusx ; break ; } /* case iface->statusx == STATUS_NEW is *always* honored */ ; if (iface->statusy == STATUS_FAIL || iface->statusy == STATUS_IGNORE) { mcxTingFree(&ykey) ; status = iface->statusy ; break ; } } while (0) ; if (status == STATUS_IGNORE || status == STATUS_FAIL) mcxTingFree(&ykey) /* fixme, the action in this branch is done in other places too. cleanify design */ ; if ( iface->statusx == STATUS_IGNORE || !mcxStrChrAint(state->etcbuf->str+state->etcbuf_ofs, isspace, -1) ) state->etcbuf_ofs = state->etcbuf->len ;if(DEBUG3)fprintf ( stdbug, "read_etc %s return x(%s -> %d stat=%s) y(%s -> %d stat=%s) status %s buf %d %d c_max_seen %lu\n" , MCXSTATUS(status) , (xkey ? xkey->str : "-"), (int) iface->x, MCXSTATUS(iface->statusx) , (ykey ? ykey->str : "-"), (int) iface->y, MCXSTATUS(iface->statusy) , MCXSTATUS(status), (int) state->etcbuf->len, (int) state->etcbuf_ofs , (ulong) iface->map_c->max_seen ) ; return status ; }
void pairwise_setops ( mclx* mx1 , mclx* mx2 , mcxbits modes ) { dim t, u, n_tst = 0 ; mclv* cache = mclvInit(NULL) ; mclv* meet = mclvInit(NULL) ; mclv* join = mclvInit(NULL) ; mclv* diff = mclvInit(NULL) ; mcxbool overwrite = modes & MMM_OVERWRITE ; dim n_zero_meet = 0, n_plus_meet = 0 ; mclv* (*fn_meet)(const mclv* lft, const mclv* rgt, mclv* dst) = mcldMeet ; mclv* (*fn_minus)(const mclv* lft, const mclv* rgt, mclv* dst) = mcldMinus1 ; if (modes & MMM_MEET2) fn_meet = mcldMeet2 , fn_minus = mcldMinus /* the point of overwrite is to have * a lft == dst or rgt == dst pattern. */ ; for (t=0;t<N_COLS(mx1);t++) { for (u=0;u<N_COLS(mx2);u++) { mclv* dst = overwrite ? (modes & MMM_RIGHT ? mx1->cols+u : mx2->cols+t) : diff ; if (overwrite) mclvCopy(cache, dst) /* cache column, reinstate later */ ; if (modes & MMM_BINARY) mclvBinary(mx1->cols+t, mx2->cols+u, dst, fltLaNR) ; else fn_minus(mx1->cols+t, mx2->cols+u, dst) /* compute t / u */ ; if (overwrite) mclvCopy(diff, dst) , mclvCopy(dst, cache) /* reinstate column */ /* diff contains t / u */ ; dst = overwrite ? dst : meet /* cache column, same as above */ ; if (modes & MMM_BINARY) mclvBinary(mx1->cols+t, mx2->cols+u, dst, fltLaR) ; else fn_meet(mx1->cols+t, mx2->cols+u, dst) ; if (overwrite) mclvCopy(meet, dst) , mclvCopy(dst, cache) /* meet contains t /\ u */ ; mcldMerge(diff, meet, join) /* join should be identical to column t */ ; if (meet->n_ivps) n_plus_meet++ ; else n_zero_meet++ ; if (modes & MMM_CHECK) { mclv* dediff = mclvClone(mx1->cols+t) ; mclv* demeet = mclvClone(mx1->cols+t) ; dim nd = mclvUpdateMeet(dediff, diff, fltSubtract) ; dim nm = mclvUpdateMeet(demeet, meet, fltSubtract) ; if ( diff->n_ivps + meet->n_ivps != mx1->cols[t].n_ivps || !mcldEquate(join, mx1->cols+t, MCLD_EQT_EQUAL) || diff->n_ivps != nd || meet->n_ivps != nm ) { mclvaDump(mx1->cols+t, stdout, -1, " ", MCLVA_DUMP_HEADER_ON) ; mclvaDump(mx2->cols+u, stdout, -1, " ", MCLVA_DUMP_HEADER_ON) ; mclvaDump(meet, stdout, -1, " ", MCLVA_DUMP_HEADER_ON) ; mclvaDump(diff, stdout, -1, " ", MCLVA_DUMP_HEADER_ON) ; mcxDie(1, me, "rats") ; } mclvFree(&dediff) ; mclvFree(&demeet) ; } n_tst++ ; } } fprintf ( stdout , "meet was nonempty %.2f\n" , (double) (n_plus_meet * 1.0f / n_tst) ) ; fprintf ( stdout , "%d successful tests in %s%s %s mode (checked: %s)\n" , (int) n_tst , overwrite ? "overwrite" : "create" , overwrite ? ( modes & MMM_RIGHT ? "-right" : "-left" ) : "" , modes & MMM_BINARY ? "generic" : "update" , (modes & MMM_CHECK ? "yes" : "no") ) ; fprintf ( stdout , "meet-can: %10lu\n" "meet-zip: %10lu\n" "meet-s/l: %10lu\n" "diff-can: %10lu\n" "diff-zip: %10lu\n" "diff-s/l: %10lu\n" , (ulong) nu_meet_can , (ulong) nu_meet_zip , (ulong) nu_meet_sl , (ulong) nu_diff_can , (ulong) nu_diff_zip , (ulong) nu_diff_sl ) ; mclvFree(&cache) ; mclvFree(&meet) ; mclvFree(&join) ; mclvFree(&diff) ; }
static mclx* make_mx_from_pars ( mclxIOstreamer* streamer , stream_state* iface , void (*ivpmerge)(void* ivp1, const void* ivp2) , mcxbits bits ) { mclpAR* pars = iface->pars ; long dc_max_seen = iface->map_c->max_seen ; long dr_max_seen = iface->map_r->max_seen ; mclx* mx = NULL ; mclv* domc, *domr ; dim i ; if (bits & MCLXIO_STREAM_235ANY) { if (streamer->cmax_235 > 0 && dc_max_seen < streamer->cmax_235 - 1) dc_max_seen = streamer->cmax_235-1 ; } else if (bits & MCLXIO_STREAM_123) { if (streamer->cmax_123 > 0 && dc_max_seen < streamer->cmax_123 - 1) dc_max_seen = streamer->cmax_123-1 ; if (streamer->rmax_123 > 0 && dr_max_seen < streamer->rmax_123 - 1) dr_max_seen = streamer->rmax_123-1 ; } mcxTell("stream", "maxc=%d maxr=%d", (int) dc_max_seen, (int) dr_max_seen) ; if (iface->pars_n_used != iface->map_c->max_seen+1) mcxDie ( 1 , module , "internal discrepancy: n_pars=%lu max_seen+1=%lu" , (ulong) iface->pars_n_used , (ulong) (iface->map_c->max_seen+1) ) ; if (dc_max_seen < 0 || dr_max_seen < 0) { if (dc_max_seen < -1 || dr_max_seen < -1) { mcxErr(module, "bad apples %ld %ld", dc_max_seen, dr_max_seen) ; return NULL ; } else mcxTell(module, "no assignments yield void/empty matrix") ; } /* fixme: with extend and same tab, should still copy. * then, there are still occasions where one would * want to go the sparse route */ domc = iface->map_c->tab && (iface->bits & MCLXIO_STREAM_CTAB_RO) ? mclvClone(iface->map_c->tab->domain) : mclvCanonical(NULL, dc_max_seen+1, 1.0) ; domr = iface->map_r->tab && (iface->bits & MCLXIO_STREAM_RTAB_RO) ? mclvClone(iface->map_r->tab->domain) : mclvCanonical(NULL, dr_max_seen+1, 1.0) ; if (! (mx = mclxAllocZero(domc, domr))) { mclvFree(&domc) ; mclvFree(&domr) ; } else for (i=0;i<iface->pars_n_used;i++) /* careful with signedness */ { long d = domc->ivps[i].idx ;if(DEBUG3)fprintf(stderr, "column %d alloc %d\n", (int) d, (int) iface->pars_n_alloc); ; mclvFromPAR(mx->cols+i, pars+d, 0, ivpmerge, NULL) ; } return mx ; }
int main ( int argc , const char* argv[] ) { mcxIO *xfin = mcxIOnew("-", "r") ; mcxIO *xfout = mcxIOnew("-", "w") ; mclMatrix *mx = NULL ; mclx* cmapx = NULL, *rmapx = NULL ; const char* me = "mcxmap" ; long cshift = 0 ; long rshift = 0 ; long cmul = 1 ; long rmul = 1 ; mcxIO* xf_cannc = NULL ; mcxIO* xf_cannr = NULL ; mcxstatus status = STATUS_OK ; mcxbool invert = FALSE ; mcxbool invertr = FALSE ; mcxbool invertc = FALSE ; mcxIO* xf_map_c = NULL, *xf_map_r = NULL, *xf_map = NULL, *xf_tab = NULL ; mcxOption* opts, *opt ; mcxstatus parseStatus = STATUS_OK ; mcxLogLevel = MCX_LOG_AGGR | MCX_LOG_MODULE | MCX_LOG_IO | MCX_LOG_GAUGE | MCX_LOG_WARN ; mclxIOsetQMode("MCLXIOVERBOSITY", MCL_APP_VB_NO) ; mclx_app_init(stderr) ; mcxOptAnchorSortById(options, sizeof(options)/sizeof(mcxOptAnchor) -1) ; opts = mcxOptParse(options, (char**) argv, argc, 1, 0, &parseStatus) ; if (!opts) exit(0) ; for (opt=opts;opt->anch;opt++) { mcxOptAnchor* anch = opt->anch ; switch(anch->id) { case MY_OPT_HELP : case MY_OPT_APROPOS : mcxOptApropos(stdout, me, syntax, 0, 0, options) ; return 0 ; case MY_OPT_VERSION : app_report_version(me) ; return 0 ; case MY_OPT_IMX : mcxIOnewName(xfin, opt->val) ; break ; case MY_OPT_OUT : mcxIOnewName(xfout, opt->val) ; break ; case MY_OPT_MUL : cmul = atol(opt->val) ; rmul = cmul ; break ; case MY_OPT_CMUL : cmul = atol(opt->val) ; break ; case MY_OPT_RMUL : rmul = atol(opt->val) ; break ; case MY_OPT_SHIFT : cshift = atol(opt->val) ; rshift = atol(opt->val) ; break ; case MY_OPT_CSHIFT : cshift = atol(opt->val) ; break ; case MY_OPT_RSHIFT : rshift = atol(opt->val) ; break ; case MY_OPT_MAP : xf_map = mcxIOnew(opt->val, "r") ; invert = FALSE ; break ; case MY_OPT_CMAP : invertc = FALSE ; xf_map_c = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_RMAP : invertr = FALSE ; xf_map_r = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_MAPI : invert = TRUE ; xf_map = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_CMAPI : invertc = TRUE ; xf_map_c = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_RMAPI : invertr = TRUE ; xf_map_r = mcxIOnew(opt->val, "r") ; break ; case MY_OPT_MAKE_MAP : xf_cannc = mcxIOnew(opt->val, "w") ; xf_cannr = xf_cannc ; break ; case MY_OPT_MAKE_MAPC : xf_cannc = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_MAKE_MAPR : xf_cannr = mcxIOnew(opt->val, "w") ; break ; case MY_OPT_TAB : xf_tab = mcxIOnew(opt->val, "r") ; break ; } } /* little special case. restructure when it grows */ if (xf_tab) { mclTab* tab1, *tab2 ; if (xf_map) { mcxIOopen(xf_map, EXIT_ON_FAIL) ; cmapx = mclxRead(xf_map, EXIT_ON_FAIL) ; } else mcxDie(1, me, "-tab option requires -map option") ; tab1 = mclTabRead(xf_tab, NULL, EXIT_ON_FAIL) ; if ((tab2 = mclTabMap(tab1, cmapx))) mclTabWrite(tab2, xfout, NULL, EXIT_ON_FAIL) ; else mcxDie(1, me, "map file error (subsumption/bijection)") ; return 0 ; } mx = mclxRead(xfin, EXIT_ON_FAIL) ; if (xf_map) { mcxIOopen(xf_map, EXIT_ON_FAIL) ; cmapx = mclxRead(xf_map, EXIT_ON_FAIL) ; rmapx = cmapx ; } else { if (xf_map_c) { mcxIOopen(xf_map_c, EXIT_ON_FAIL) ; cmapx = mclxRead(xf_map_c, EXIT_ON_FAIL) ; } else if (cshift || cmul > 1) cmapx = mclxMakeMap ( mclvCopy(NULL, mx->dom_cols) , mclvMap(NULL, cmul, cshift, mx->dom_cols) ) ; else if (xf_cannc) /* fixme slightly flaky interface */ { cmapx = mclxMakeMap ( mclvCopy(NULL, mx->dom_cols) , mclvCanonical(NULL, mx->dom_cols->n_ivps, 1.0) ) ; mclxWrite(cmapx, xf_cannc, MCLXIO_VALUE_GETENV, RETURN_ON_FAIL) ; } if (xf_map_r) { mcxIOopen(xf_map_r, EXIT_ON_FAIL) ; rmapx = mclxRead(xf_map_r, EXIT_ON_FAIL) ; } else if (rshift || rmul > 1) rmapx = mclxMakeMap ( mclvCopy(NULL, mx->dom_rows) , mclvMap(NULL, rmul, rshift, mx->dom_rows) ) ; else if (xf_cannr) { rmapx = mclxMakeMap ( mclvCopy(NULL, mx->dom_rows) , mclvCanonical(NULL, mx->dom_rows->n_ivps, 1.0) ) ; if (xf_cannr != xf_cannc) mclxWrite(rmapx, xf_cannr, MCLXIO_VALUE_GETENV, RETURN_ON_FAIL) ; else if (!mclxIsGraph(mx)) mcxErr(me, "row map not written but matrix is not a graph") ; } } if (invert && cmapx && cmapx == rmapx) { mclx* cmapxi = mclxTranspose(cmapx) ; mclxFree(&cmapx) ; cmapx = rmapx = cmapxi ; } else { if ((invert || invertr) && rmapx) { mclx* rmapxi = mclxTranspose(rmapx) ; mclxFree(&rmapx) ; rmapx = rmapxi ; } if ((invert || invertc) && cmapx) { mclx* cmapxi = mclxTranspose(cmapx) ; mclxFree(&cmapx) ; cmapx = cmapxi ; } } ; status = STATUS_FAIL ; do { if (cmapx && mclxMapCols(mx, cmapx)) break ; if (rmapx && mclxMapRows(mx, rmapx)) break ; status = STATUS_OK ; } while (0) ; if (status) { mcxErr(me, "error, nothing written") ; return 1 ; } mclxWrite(mx, xfout, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; return 0 ; }
mclx* mclxIOstreamIn ( mcxIO* xf , mcxbits bits , mclpAR* transform , void (*ivpmerge)(void* ivp1, const void* ivp2) , mclxIOstreamer* streamer , mcxOnFail ON_FAIL ) { mcxstatus status = STATUS_FAIL ; const char* me = module ; mcxbool symmetric = bits & MCLXIO_STREAM_SYMMETRIC ; mcxbool mirror = bits & MCLXIO_STREAM_MIRROR ; mcxbool abc = bits & MCLXIO_STREAM_ABC ? TRUE : FALSE ; mcxbool one23 = bits & MCLXIO_STREAM_123 ? TRUE : FALSE ; mcxbool etc = bits & (MCLXIO_STREAM_ETC | MCLXIO_STREAM_ETC_AI) ? TRUE : FALSE ; mcxbool longlist = bits & (MCLXIO_STREAM_ETCANY | MCLXIO_STREAM_235ANY) ? TRUE : FALSE ; mcxTing* linebuf = mcxTingEmpty(NULL, 100) ; map_state map_c = { NULL, NULL, -1 , 0} ; map_state map_r = { NULL, NULL, -1 , 0} ; stream_state iface ; etc_state etcstate ; unsigned long n_ite = 0 ; mclx* mx = NULL ; if (!ivpmerge) ivpmerge = mclpMergeMax ; if (symmetric) iface.map_c = &map_c /* this bit of hidgery-pokery */ , iface.map_r = &map_c /* is a crucial interfacummathingy */ ; else iface.map_c = &map_c , iface.map_r = &map_r ;if(DEBUG2)fprintf(stderr, "%s abc\n", abc ? "yes" : "no") ; etcstate.etcbuf = NULL ; etcstate.etcbuf_ofs = 0 ; etcstate.etcbuf_check = 0 ; etcstate.x_prev = ULONG_MAX /* note we depend on ULONG_MAX + 1 == 0 */ ; etcstate.n_y = 0 /* fixme incomplete and distributed initialization of iface */ ; iface.pars = NULL ; iface.pars_n_alloc = 0 ; iface.pars_n_used = 0 ;if(DEBUG3)fprintf(stderr, "1 + max c %lu\n", (ulong) (iface.map_c->max_seen+1)) /* fixme: put the block below in a subroutine */ ; while (1) { if (abc + one23 + longlist > TRUE) /* OUCH */ { mcxErr(module, "multiple stream formats specified") ; break ; } if (!symmetric && streamer->tab_sym_in) { mcxErr(module, "for now disallowed, single tab, different domains") ; break ; } if ((!one23 && !abc && !longlist)) { mcxErr(module, "not enough to get going") ; break ; } /* These have maps associated with them. * Note that bitsp may be changed (by filling in * somewhat underspecified settings). * todo hierverder: etc case supported below ? */ if (abc || etc) stream_state_set_map(symmetric, &iface, streamer, &bits) ; if (xf->fp == NULL && (mcxIOopen(xf, ON_FAIL) != STATUS_OK)) { mcxErr(me, "cannot open stream <%s>", xf->fn->str) ; break ; } status = STATUS_OK ; break ; } iface.bits = bits ; if (!status) while (1) { unsigned long x = 876543210, y = 876543210 ; double value = 0 ; n_ite++ ; iface.x = 0 ; iface.y = 0 ; if (n_ite % 20000 == 0) fputc('.', stderr) /* fixme conditional to sth */ ; if (n_ite % 1000000 == 0) fprintf(stderr, " %ldM\n", (long) (n_ite / 1000000)) /* * - the read routines largely manage iface, including * map_c->max_seen and map_r->max_seen. It would be * nice to encapsulate that management in a single * place. Note the read_abc requirement that sometimes * a label may need to be deleted from a hash. The fact * that handle_label (called by read_etc and read_abc) * also manages max_seen complicate encapsulation though. * * - read_etc manages its line buffer. */ ; status = one23 ? read_123(xf, linebuf, &iface, streamer, &value, bits) : abc ? read_abc(xf, linebuf, &iface, &value) : longlist ? read_etc(xf, &iface, &etcstate, &value) : STATUS_FAIL ; x = iface.x ; y = iface.y /* considerme: etc status ignore could still expand column range. * do we change the status and deal with not incorporating the row, * or do we keep status, and change realloc/ignore logic below? */ ;if(0)fprintf(stderr, "#x now %lu status %s\n", (ulong) (iface.map_c->max_seen+1), MCXSTATUS(status)) /* etc/235 are special in that with NEW x and IGNORE y * we respect x * fixme: should not do that for auto-increment */ ; if (status == STATUS_IGNORE) /* maybe restrict mode */ { if ( longlist && iface.statusx == STATUS_NEW && iface.map_c->max_seen+1 > iface.pars_n_used /* note mixed-sign comparison */ ) { if ((status = pars_realloc(&iface, iface.map_c->max_seen+1))) break ; } continue ; } else if (status) /* FAIL or DONE */ break ; if ( iface.map_c->max_seen >= iface.pars_n_used /* note mixed-sign comparison */ && (status = pars_realloc(&iface, iface.map_c->max_seen+1)) ) break ; status = STATUS_FAIL /* fixme restructure logic, mid-re-initialization is ugly */ ; if ( bits & (MCLXIO_STREAM_LOGTRANSFORM | MCLXIO_STREAM_NEGLOGTRANSFORM) ) { if (bits & MCLXIO_STREAM_LOGTRANSFORM) value = value > 0 ? log(value) : -PVAL_MAX ; else if (bits & MCLXIO_STREAM_NEGLOGTRANSFORM) value = value > 0 ? -log(value) : PVAL_MAX ; if (bits & MCLXIO_STREAM_LOG10) value /= log(10) ; } if (transform) { mclp bufivp ; bufivp.idx = 0 ; bufivp.val = value ; value = mclpUnary(&bufivp, transform) ; } /* fixme: below we have canonical dependence, index as offset */ if (value) { if(DEBUG3)fprintf(stderr, "attempt to extend %d\n", (int) x) ; if (mclpARextend(iface.pars+x, y, value)) { mcxErr(me, "x-extend fails") ; break ; } if (mirror && mclpARextend(iface.pars+y, x, value)) { mcxErr(me, "y-extend fails") ; break ; } } status = STATUS_OK ; } if (n_ite >= 1000000 && n_ite % 5000000) fputc('\n', stderr) ; mcxTingFree(&(etcstate.etcbuf)) ; if (status == STATUS_FAIL || ferror(xf->fp)) mcxErr(me, "error occurred (status %d lc %d)", (int) status, (int) xf->lc) ; else { mx = make_mx_from_pars(streamer, &iface, ivpmerge, bits) ; status = mx ? STATUS_OK : STATUS_FAIL ; } mcxTingFree(&linebuf) ; free_pars(&iface) ; if (status == STATUS_FAIL) { if (ON_FAIL == EXIT_ON_FAIL) mcxDie(1, me, "fini") ; } /* with 123, etcai there is simply no column tab * todo: perhaps create a dummy one (integers). */ if ( !status && (abc || (bits & (MCLXIO_STREAM_ETC | MCLXIO_STREAM_ETC_AI))) ) { if (symmetric) streamer->tab_sym_out = make_tab(iface.map_c) ; else { if (!(bits & MCLXIO_STREAM_ETC_AI)) streamer->tab_col_out = make_tab(iface.map_c) ;if(0)fprintf(stderr, "%p x %p\n", (void*) iface.map_c->map, (void*) iface.map_c->tab) ;if(0)mcxHashStats(stdout, iface.map_c->map) ; streamer->tab_row_out = make_tab(iface.map_r) ; } } mcxHashFree(&(iface.map_c->map), mcxTingRelease, NULL) ; if (!symmetric) mcxHashFree(&(iface.map_r->map), mcxTingRelease, NULL) ; return mx ; }