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 mclv* get_closure ( mclx* mx /* caller must have invoked mclgUnionvReset before */ , const mclv* nbls ) { mclv* nbls_closure = mclvCopy(NULL, nbls), *wave1 = mclvCopy(NULL, nbls_closure), *wave2 = NULL ; mclgUnionvInitList(mx, nbls_closure) ; while (wave1->n_ivps) { wave2 = mclgUnionv(mx, wave1, NULL, SCRATCH_UPDATE, NULL) ; mcldMerge(nbls_closure, wave2, nbls_closure) ; mclvFree(&wave1) ; wave1 = wave2 ; } mclgUnionvResetList(mx, nbls_closure) ; mclvFree(&wave1) ; return nbls_closure ; }
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 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 ; }