Exemplo n.º 1
0
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
;  }
Exemplo n.º 2
0
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
           ;
}
Exemplo n.º 3
0
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)
;  }
Exemplo n.º 4
0
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
;  }