dim clmAssimilate ( mclx* mx , mclx* cl , dim prune_sz , mclx** cl_prunedpp , dim* sjd_left , dim* sjd_right ) { dim dist_this_pru = 0, dist_pru_this = 0 ; mclx* cl_pru = NULL ; const char* me = "clmAssimilate" ; dim o, m, e, n_source, n_sink ; dim sum_pruned = clm_clm_prune (mx, cl, prune_sz, &cl_pru, &n_source, &n_sink) ; *cl_prunedpp = NULL ; if (sum_pruned) { mcxLog ( MCX_LOG_AGGR , me , "funneling %lu nodes from %lu sources into %lu targets" , (ulong) sum_pruned , (ulong) n_source , (ulong) n_sink ) ; clmEnstrict(cl_pru, &o, &m, &e, 0) ; *cl_prunedpp = cl_pru ; clmSJDistance (cl, cl_pru, NULL, NULL, &dist_this_pru, &dist_pru_this) ; if (sjd_left) *sjd_left = dist_this_pru , *sjd_right = dist_pru_this ; } else if (sjd_left) *sjd_left = 0 , *sjd_right = 0 ; mcxLog ( MCX_LOG_AGGR , me , "dim %lu pruned %lu distance %lu|%lu" , (ulong) N_COLS(mx) , (ulong) sum_pruned , (ulong) dist_this_pru , (ulong) dist_pru_this ) ; return sum_pruned ; }
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 ; }
dim clmAdjust ( mclx* mx , mclx* cl , dim cls_size_max , mclx** cl_adjustedpp , mclv** ls_adjustedpp /* nodes that moved around */ , dim* sjd_left , dim* sjd_right ) { dim sum_adjusted = 0, n_ite = 0 ; dim dist_curr_adj = 0, dist_adj_curr = 0 ; mclx* cl_adj = NULL ; mclx* cl_curr = cl ; mclv* ls_adjusted = mclvInit(NULL) ; clmXScore score_curr, score_adj ; const char* me = "clmAdjust" ; *cl_adjustedpp = NULL ; *ls_adjustedpp = NULL ; while (1) { dim n_adjusted ; double cov_curr, cov_adj, frac_curr = 0.0, frac_adj = 0.0 ; mclv* cid_affected = NULL, *nid_affected = NULL ; dim o, m, e ; if (n_ite++ >= 100) break ; mclxColumnsRealign(cl_curr, mclvSizeCmp) ; if ( !(n_adjusted = clm_clm_adjust (mx, cl_curr, cls_size_max, &cl_adj, &cid_affected, &nid_affected) ) ) break ; mcxTell ( me , "assembled %lu nodes with %lu clusters affected" , (ulong) n_adjusted , (ulong) cid_affected->n_ivps ) ; clmXScanInit(&score_curr) ; clmXScanInit(&score_adj) ; clmXScanDomainSet(mx, cl_curr,cid_affected, &score_curr) ; clmXScanDomainSet(mx, cl_adj, cid_affected, &score_adj) ; clmXScoreCoverage(&score_curr, &cov_curr, NULL) ; clmXScoreCoverage(&score_adj , &cov_adj , NULL) ; if (score_curr.n_hits && score_adj.n_hits) frac_curr = score_curr.sum_i / score_curr.n_hits , frac_adj = score_adj.sum_i / score_adj.n_hits ; mcxLog ( MCX_LOG_LIST , me , "consider (%.5f|%.5f|%lu) vs (%.5f|%.5f|%lu)" , cov_adj, frac_adj, (ulong) score_adj.n_hits , cov_curr, frac_curr, (ulong) score_curr.n_hits ) /* experience tells us that mcl's funneling * worsens frac */ ; if (frac_adj <= frac_curr) { mclvFree(&cid_affected) ; mclvFree(&nid_affected) ; break ; } clmEnstrict(cl_adj, &o, &m, &e, 0) ; clmSJDistance(cl_curr, cl_adj, NULL, NULL, &dist_curr_adj, &dist_adj_curr) ; mcxLog ( MCX_LOG_AGGR , me , "distance %lu|%lu" , (ulong) dist_curr_adj, (ulong) dist_adj_curr ) ; mclvAdd(ls_adjusted, nid_affected, ls_adjusted) ; if (cl_curr != cl) mclxFree(&cl_curr) ; cl_curr = cl_adj ; sum_adjusted += n_adjusted ; mclvFree(&cid_affected) ; mclvFree(&nid_affected) ; } if (cl_curr != cl) /* fixme free logic */ { mclxColumnsRealign(cl_curr, mclvSizeRevCmp) ; *cl_adjustedpp = cl_curr ; *ls_adjustedpp = ls_adjusted ; clmSJDistance (cl, cl_curr, NULL, NULL, &dist_curr_adj, &dist_adj_curr) ; if (sjd_left) *sjd_left = dist_curr_adj , *sjd_right = dist_adj_curr ; } else { if (sjd_left) *sjd_left = 0 , *sjd_right = 0 ; mclvFree(&ls_adjusted) ; } mcxLog ( MCX_LOG_AGGR , me , "total adjusted %lu, final distance %lu|%lu" , (ulong) sum_adjusted , (ulong) dist_curr_adj , (ulong) dist_adj_curr ) ; mclxColumnsRealign(cl, mclvSizeRevCmp) ; return sum_adjusted ; }