void test_cross_ratio ( mclx* mx ) { dim i, j, n = 0 ; for (i=0;i<N_COLS(mx);i++) { mclv* v = mx->cols+i ; double selfv = mclvSelf(v) ; for (j=0;j<v->n_ivps;j++) { mclv* w = mclxGetVector(mx, v->ivps[j].idx, EXIT_ON_FAIL, NULL) ; double arc = v->ivps[j].val ; double selfw= mclvSelf(w) ; double cra = mclvIdxVal(w, v->vid, NULL) ; double s = MCX_MIN(selfv, selfw) ; if (s > arc || s > cra) fprintf ( stdout , "%u\t%u\t%g\t%g\t%g\t%g\n" , (unsigned) v->vid , (unsigned) w->vid , arc , cra , selfv , selfw ) ; n++ ; } } fprintf(stderr, "tested %u entries\n", (unsigned) n) ; }
static ofs get_cls_id ( long idx , const mclx* cl , const mclx* cltp , long* cls_size ) { mclv* tocl = mclxGetVector(cltp, idx, EXIT_ON_FAIL, NULL), *cls = NULL ; ofs clid = -1 ; cls_size[0] = 0 ; if (tocl) { clid = tocl->ivps[0].idx ; cls = mclxGetVector(cl, clid, EXIT_ON_FAIL, NULL) ; cls_size[0] = cls->n_ivps ; } return clid ; }
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) ; }
mcxstatus fire_node_next ( const mclx* mx , mclv* seen , mclv *todo , dim start ) { mclv* next = mclvInit(NULL) ; dim i ; mcxstatus s = STATUS_OK ;if(0)fprintf(stderr, "\tnext layer has %d nodes\n", (int) todo->n_ivps) ; for (i=0; i<todo->n_ivps;i++) { mclv* ls = mclxGetVector(mx, todo->ivps[i].idx, RETURN_ON_FAIL, NULL) ; if (ls) { mcldMerge(next, ls, next) ; if (mclvGetIvp(ls, start, NULL)) { s = STATUS_FAIL ; break ; } } } mcldMerge(seen, todo, seen) /* add todo to seen */ ; mcldMinus(next, seen, next) /* remove seen from next */ ; mclvCopy(todo, next) /* copy next to todo */ ; mclvFree(&next) ; return s ; }
static int calc_depth ( mclx* m_transient ) { mclx* m_inverse = mclxTranspose(m_transient) ; dim c, depth = 0 ; if(0)puts("") ; for (c=0; c<N_COLS(m_inverse); c++) { dim this_depth = 0 ; if (!m_inverse->cols[c].n_ivps) /* no incoming nodes */ { mclv* next = mclxGetVector(m_transient, m_inverse->cols[c].vid, RETURN_ON_FAIL, NULL) ; if (!next) continue ; mclgUnionvInitList(m_transient, next) ; do { mclv* next2 = mclgUnionv(m_transient, next, NULL, SCRATCH_UPDATE, NULL) ; if (0 && next->ivps) fprintf(stdout, "chain %d ->\n", (int) m_inverse->cols[c].vid) , mclvaDump(next, stdout, -1, " ", 0) ; if (this_depth) /* otherwise starting vector in matrix */ mclvFree(&next) ; next = next2 ; this_depth++ ; } while (next->n_ivps) ; mclvFree(&next) /* did loop at least once, so not the starting vector */ ; mclgUnionvReset(m_transient) ; } if (this_depth > depth) depth = this_depth ; } mclxFree(&m_inverse) ; return depth ; }
void walk_dag ( mclx* mx , mclv* v , int level ) { dim i ; v->val = 2.0 ; for (i=0;i<v->n_ivps;i++) { mclv* v = mclxGetVector(mx, v->ivps[i].idx, EXIT_ON_FAIL, NULL) ; v->val = 2.0 ; dump_label(tab, v, level) ; } ; }
void dag_diff_select ( mclx* mx , mclTab* tab , mcxIO* xfdiff , double child_diff_lq , double parent_diff_gq ) { dim i ; mclx* dag = mclxAllocClone(mx) ; for (i=0;i<N_COLS(mx); i++) { mclv* v = mx->cols+i ; dim j ; for (j=0;j<v->n_ivps;j++) { dim idx = v->ivps[j].idx ; double valv = v->ivps[j].val ; mclv* t = mclxGetVector(mx, idx, EXIT_ON_FAIL, NULL) ; mclp* p = mclvGetIvp(t, v->vid, NULL) ; double valt = p ? p->val : 0.0 ; double delta = valv - valt ; double lg = valv, sm = valt ; double child_diff, parent_diff ; int v_is_child = 0 ; if (delta < 0) delta = -delta , lg=valt, sm=valv , v_is_child = 1 ; child_diff = sm ; parent_diff = lg ;if(0 && i==111) fprintf(stderr, "nb %d delta %g\n", (int) idx, delta) ; if (child_diff > child_diff_lq || parent_diff < parent_diff_gq) NOTHING ; else { if (v_is_child) mclvInsertIdx(dag->cols+i, idx, delta) ; else mclvInsertIdx(dag->cols+(t-mx->cols), v->vid, delta) ; } } } ; mclxWrite(dag, xfdiff, MCLXIO_VALUE_GETENV, EXIT_ON_FAIL) ; mclxFree(&dag) ; }
static void set_cl_to_projection ( mclMatrix* cl , mclMatrix* el_on_cl ) { dim i, j ; for (i=0;i<N_COLS(cl);i++) { mclv* clvec = cl->cols+i ; long clid = clvec->vid ; mclv* elclvec = NULL ; mclp* valivp = NULL ; for (j=0;j<clvec->n_ivps;j++) { long elid = clvec->ivps[j].idx ; elclvec = mclxGetVector(el_on_cl, elid, EXIT_ON_FAIL, elclvec) ; valivp = mclvGetIvp(elclvec, clid, NULL) ; if (!valivp && clvec->n_ivps > 1) mcxErr("clmCastActors", "match error: el %ld cl %ld", elid, clid) ; clvec->ivps[j].val = valivp ? MCX_MAX(0.01, valivp->val) : 0.01 ; } } }
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++ ; } }
void clmDumpNodeScores ( const char* name , mclx* mx , mclx* cl , mcxenum mode ) { dim d, e ; clmVScore sc ; if (mode == CLM_NODE_SELF) { for (d=0;d<N_COLS(cl);d++) { ofs o = -1 ; dim clsize = cl->cols[d].n_ivps ; for (e=0;e<clsize;e++) { long idx = cl->cols[d].ivps[e].idx ; o = mclxGetVectorOffset(mx, idx, EXIT_ON_FAIL, o) ; mx->cols[o].val = mclvSum(mx->cols+o) /* fixme stupid dependency. */ ; clmVScanDomain(mx->cols+o, cl->cols+d, &sc) ; clm_dump_line (name, &sc, idx, cl->cols[d].vid, mx->cols[o].n_ivps, clsize, 0) ; } } /* fixme: sum_e not set, pbb due to missing clmCastActors */ } else if (mode == CLM_NODE_INCIDENT) { mclx *el_to_cl = NULL ; mclx *el_on_cl = NULL ; mclx *cl_on_cl = NULL ; mclx *cl_on_el = NULL ; clmCastActors (&mx, &cl, &el_to_cl, &el_on_cl, &cl_on_cl, &cl_on_el, 0.95) ; mclxFree(&cl_on_cl) ; mclxFree(&cl_on_el) ; for (d=0;d<N_COLS(mx);d++) { long nid = mx->cols[d].vid ; long nsize = mx->cols[d].n_ivps ; mclv* clidvec = mclxGetVector(el_on_cl, nid, RETURN_ON_FAIL, NULL) ; mclv* clself = mclxGetVector(el_to_cl, nid, RETURN_ON_FAIL, NULL) ; dim f ; if (!clself) mcxErr ("clmDumpNodeScores panic", "node <%ld> does not belong", nid) ; for (f=0;f<clidvec->n_ivps;f++) { long cid = clidvec->ivps[f].idx ; mclv* clvec = mclxGetVector(cl, cid, RETURN_ON_FAIL, NULL) /* ^ overdoing: cid == clvec->vid */ ; int alien ; if (!clvec) { mcxErr ( "clmDumpNodeScores panic" , "cluster <%ld> node <%ld> mishap" , cid , nid ) ; continue ; } clmVScanDomain(mx->cols+d, clvec, &sc) ; alien = clself && clvec->vid == clself->ivps[0].idx ? 0 : 1 ; clm_dump_line (name, &sc, nid, clvec->vid, nsize, clvec->n_ivps, alien) ; } } mclxFree(&el_on_cl) ; mclxFree(&el_to_cl) ; } }
static dim clm_clm_prune ( mclx* mx , mclx* cl , dim prune_sz , mclx** cl_adjustedpp , dim* n_sink , dim* n_source ) { dim d, n_adjusted = 0 ; mclx* cl_adj = mclxCopy(cl) ; mclv* cid_affected = mclvClone(cl->dom_cols) ; const char* me = "clmAssimilate" ; double bar_affected = 1.5 ; mclx *el_to_cl = NULL ; mclx *el_on_cl = NULL ; mclx *cl_on_cl = NULL ; mclx *cl_on_el = NULL ; *n_sink = 0 ; *n_source = 0 ; mclvMakeConstant(cid_affected, 1.0) ; mclxColumnsRealign(cl_adj, mclvSizeCmp) ; *cl_adjustedpp = NULL ; clmCastActors (&mx, &cl_adj, &el_to_cl, &el_on_cl, &cl_on_cl, &cl_on_el, 0.95) ; mclxFree(&cl_on_el) ; for (d=0;d<N_COLS(cl_on_cl);d++) { mclv* clthis = cl_adj->cols+d ; mclv* cllist = cl_on_cl->cols+d ; mclp* pself = mclvGetIvp(cllist, clthis->vid, NULL) ; double self_val = -1.0 ; if (pself) self_val = pself->val , pself->val *= 1.001 /* to push it up in case of equal weights */ ;if(0)fprintf(stderr, "test size %d\n", (int) clthis->n_ivps) ; if (prune_sz && clthis->n_ivps > prune_sz) continue ; while (1) { mclv* clthat ; dim e ; if (cllist->n_ivps < 2) break ; mclvSort(cllist, mclpValRevCmp) /* now get biggest mass provided that cluster * ranks higher (has at least as many entries) * * fixme/todo: we probably have a slight order * dependency for some fringe cases. If provable * then either solve or document it. */ ; for (e=0;e<cllist->n_ivps;e++) if (cllist->ivps[e].idx >= clthis->vid) break /* found none or itself */ ; if (e == cllist->n_ivps || cllist->ivps[e].idx == clthis->vid) break ; if /* Should Not Happen */ (!(clthat = mclxGetVector(cl_adj, cllist->ivps[e].idx, RETURN_ON_FAIL, NULL) ) ) break /* works for special case prune_sz == 0 */ /* if (clthat->n_ivps + clthis->n_ivps > prune_sz) */ /* ^iced. inconsistent behaviour as k grows. */ ; { mcxLog ( MCX_LOG_LIST , me , "source %ld|%lu|%.3f absorbed by %ld|%lu|%.3f" , clthis->vid, (ulong) clthis->n_ivps, self_val , clthat->vid, (ulong) clthat->n_ivps, cllist->ivps[0].val ) ; n_adjusted += clthis->n_ivps ; (*n_sink)++ /* note: we could from our precomputed cl_on_cl * obtain that A is absorbed in B, B is absorbed in C. * below we see that A will be merged with B, * and the result will then be merged with C. * This depends on the fact that cl_adj is ordered * on increasing cluster size. */ ; mcldMerge(cl_adj->cols+d, clthat, clthat) ; mclvResize(cl_adj->cols+d, 0) ; mclvInsertIdx(cid_affected, clthat->vid, 2.0) ; } break ; } mclvSort(cllist, mclpIdxCmp) ; } mclxFree(&cl_on_cl) ; mclxFree(&el_on_cl) ; mclxFree(&el_to_cl) ; mclxMakeCharacteristic(cl) ; mclvUnary(cid_affected, fltxGT, &bar_affected) ; *n_source = cid_affected->n_ivps ; mclvFree(&cid_affected) ; mclxColumnsRealign(cl_adj, mclvSizeRevCmp) ; if (!n_adjusted) { mclxFree(&cl_adj) ; return 0 ; } mclxUnary(cl_adj, fltxCopy, NULL) ; mclxMakeCharacteristic(cl_adj) ; *cl_adjustedpp = cl_adj ; return n_adjusted ; }
static dim clm_clm_adjust ( mclx* mx , mclx* cl , dim cls_size_max , mclx** cl_adjustedpp , mclv** cid_affectedpp , mclv** nid_affectedpp ) { dim i, j, n_adjusted = 0 ; mclx* cl_adj = mclxCopy(cl) ; mclv* cid_affected = mclvClone(cl->dom_cols) ; mclv* nid_affected = mclvClone(mx->dom_cols) ; double bar_affected = 1.5 ; const char* e1 = getenv("MCL_ADJ_FMAX") ; const char* e2 = getenv("MCL_ADJ_EMASS") ; double f1 = e1 ? atof(e1) : 2 ; double f2 = e2 ? atof(e2) : 3 ; mcxbool loggit = mcxLogGet( MCX_LOG_CELL | MCX_LOG_INFO ) ; clmVScore sc ; mclx *el_to_cl = NULL ; mclx *el_on_cl = NULL ; mclx *cl_on_cl = NULL ; mclx *cl_on_el = NULL ; *cl_adjustedpp = NULL ; *cid_affectedpp = NULL ; *nid_affectedpp = NULL ; clmCastActors (&mx, &cl, &el_to_cl, &el_on_cl, &cl_on_cl, &cl_on_el, 0.95) ; mclxFree(&cl_on_cl) ; mclxFree(&cl_on_el) ; mclvMakeConstant(cid_affected, 1.0) ; mclvMakeConstant(nid_affected, 1.0) ; for (i=0;i<N_COLS(cl_adj);i++) cl_adj->cols[i].val = 0.5 /* Proceed with smallest clusters first. * Caller has to take care of mclxColumnsRealign */ ; for (i=0;i<N_COLS(cl);i++) { mclv* clself = cl->cols+i /* Only consider nodes in clusters of * size <= cls_size_max */ ; if (cls_size_max && clself->n_ivps > cls_size_max) break /* Clusters that have been marked for inclusion * cannot play. */ ; if (cl_adj->cols[i].val > 1) continue ; for (j=0;j<clself->n_ivps;j++) { long nid = clself->ivps[j].idx ; long nos = mclvGetIvpOffset(mx->dom_cols, nid, -1) ; mclv* clidvec = mclxGetVector(el_on_cl, nid, RETURN_ON_FAIL, NULL) ; double eff_alien_bsf = 0.0, eff_alien_max_bsf = 0.0 /* best so far*/ ; double eff_self = 0.0, eff_self_max = 0.0 ; long cid_alien = -1, cid_self = -1 ; clmVScore sc_self = { 0 }, sc_alien = { 0 } ; dim f ; if (nos < 0 || !clidvec) { mcxErr ("clmDumpNodeScores panic", "node <%ld> does not belong", nid) ; continue ; } clmVScanDomain(mx->cols+nos, clself, &sc) ; clmVScoreCoverage(&sc, &eff_self, &eff_self_max) ; cid_self = clself->vid ; sc_self = sc ; if (loggit) mcxLog2 ( us , "node %ld in cluster %ld eff %.3f,%.3f sum %.3f" , nid , cid_self , eff_self , eff_self_max , sc.sum_i ) ; for (f=0;f<clidvec->n_ivps;f++) { long cid = clidvec->ivps[f].idx ; mclv* clvec = mclxGetVector(cl, cid, RETURN_ON_FAIL, NULL) /* ^ overdoing: cid == clvec->vid */ ; double eff, eff_max ; if (!clvec) { mcxErr ( "clmAdjust panic" , "cluster <%ld> node <%ld> mishap" , cid , nid ) ; continue ; } /* fixme: document or remove first condition * */ if ((0 && clvec->n_ivps <= clself->n_ivps) || clvec->vid == cid_self) continue ; clmVScanDomain(mx->cols+nos, clvec, &sc) ; clmVScoreCoverage(&sc, &eff, &eff_max) #if 0 # define PIVOT eff > eff_alien_bsf #else # define PIVOT eff_max > eff_alien_max_bsf #endif ; if ( PIVOT || sc.sum_i >= 0.5 ) eff_alien_bsf = eff , eff_alien_max_bsf = eff_max , cid_alien = clvec->vid , sc_alien = sc ; if (sc.sum_i >= 0.5) break ; } if (loggit) mcxLog2 ( us , " -> best alien %ld eff %.3f,%.3f sum %.3f" , cid_alien , eff_alien_bsf , eff_alien_max_bsf , sc_alien.sum_i ) /* below: use sum_i as mass fraction * (clmAdjust framework uses stochastic * matrix) */ ; if ( cid_alien >= 0 && cid_self >= 0 && f1 * sc_alien.max_i >= sc_self.max_i && ( ( eff_alien_bsf > eff_self && sc_alien.sum_i > sc_self.sum_i ) || ( pow(sc_alien.sum_i, f2) >= sc_self.sum_i && pow(eff_self, f2) <= eff_alien_bsf ) ) /* So, if max is reasonable * and efficiency is better and mass is better * or if mass is ridiculously better -> move * Somewhat intricate and contrived, yes. */ ) { mclv* acceptor = mclxGetVector(cl_adj, cid_alien, RETURN_ON_FAIL, NULL) ; mclv* donor = mclxGetVector(cl_adj, cid_self, RETURN_ON_FAIL, NULL) ; if (!donor || !acceptor || acceptor == donor) continue ; mclvInsertIdx(donor, nid, 0.0) ; mclvInsertIdx(acceptor, nid, 1.0) ; acceptor->val = 1.5 ; if (mcxLogGet(MCX_LOG_LIST)) { mclv* nb = mx->cols+nos ; double mxv = mclvMaxValue(nb) ; double avg = nb->n_ivps ? mclvSum(nb) / nb->n_ivps : -1.0 ; mcxLog ( MCX_LOG_LIST , us , "mov %ld (%ld %.2f %.2f)" " %ld (cv=%.2f cm=%.2f s=%.2f m=%.2f #=%lu)" " to %ld (cv=%.2f cm=%.2f s=%.2f m=%.2f #=%lu)" , nid , (long) nb->n_ivps, mxv, avg , cid_self , eff_self, eff_self_max, sc_self.sum_i, sc_self.max_i , (ulong) (sc_self.n_meet + sc_self.n_ddif) , cid_alien , eff_alien_bsf, eff_alien_max_bsf, sc_alien.sum_i, sc_alien.max_i , (ulong) (sc_alien.n_meet + sc_alien.n_ddif) ) ; } n_adjusted++ ; mclvInsertIdx(cid_affected, cid_alien, 2.0) ; mclvInsertIdx(cid_affected, cid_self, 2.0) ; mclvInsertIdx(nid_affected, nid, 2.0) ; } } } mclxFree(&el_on_cl) ; mclxFree(&el_to_cl) ; for (i=0;i<N_COLS(cl_adj);i++) cl_adj->cols[i].val = 0.0 ; mclxMakeCharacteristic(cl) ; if (!n_adjusted) { mclxFree(&cl_adj) ; mclvFree(&cid_affected) ; mclvFree(&nid_affected) ; return 0 ; } mclxUnary(cl_adj, fltxCopy, NULL) ; mclxMakeCharacteristic(cl_adj) /* FIRST REMOVE ENTRIES set to zero (sssst now .. */ /* ...) and THEN make it characteristic again */ ; mclvUnary(cid_affected, fltxGT, &bar_affected) ; mclvUnary(nid_affected, fltxGT, &bar_affected) ; *cl_adjustedpp = cl_adj ; *cid_affectedpp = cid_affected ; *nid_affectedpp = nid_affected ; return n_adjusted ; }