/**
  *  dr=sum_j v_j dv_j; ddr=sum_j dv_j^2
  *  v_j = bar_j - bar_{p(j)} where p(j) is j's parent. 
  *
  *  output: newleaf_v, newleaf_dep_factor, focus_dbar, 
  *          vdv_sum, dv2_dum, dr, ddr
 **/
void AzReg_Tsrbase::update()
{
  /* vdv_sum, dv2_sum: don't include new leaf nodes */
  /* dr, ddr:           include new leaf nodes */

  dr = ddr = 0; 

  if (forNewLeaf) {
    checkLeaf("update"); 

    /*---  new leaf  ---*/
    newleaf_v = get_newleaf_v(); 
    double dv = get_newleaf_dv(); 
    int newleaf_depth = get_newleaf_depth(); 
    newleaf_dep_factor = reg_depth->apply(1, newleaf_depth); 
    dr += newleaf_v*dv*newleaf_dep_factor; 
    ddr += dv*dv*newleaf_dep_factor; 

    /*---  new leaf's sibling (v is the same)  ---*/
    dv = get_newleaf_sib_dv(); 
    dr += newleaf_v*dv*newleaf_dep_factor; 
    ddr += dv*dv*newleaf_dep_factor; 

    focus_dbar = av_dbar.point(focus_nx)->get(focus_nx); 
  }

  vdv_sum = 0;  
  int nx; 
  if (v_v.rowNum() > 0) {
    /*---  for efficiency don't use get_v and get_dv  ---*/
    const double *v_arr = v_v.point(); 
    if (av_dv.size() <= 0) {
      throw new AzException("AzReg_Tsrbase::update", "no dv?"); 
    }
    const double *dv_arr = av_dv.point(focus_nx)->point(); 

    for (nx = 0; nx < tree->nodeNum(); ++nx) {
      double v = v_arr[nx]; 
      double dv = dv_arr[nx]; 
      int depth = tree->node(nx)->depth; 
      vdv_sum += reg_depth->apply(v * dv, depth); 
    } 
  }  
  else {
    for (nx = 0; nx < tree->nodeNum(); ++nx) {
      double v = get_v(nx); 
      double dv = get_dv(nx); 
      int depth = tree->node(nx)->depth; 
      vdv_sum += reg_depth->apply(v * dv, depth); 
    } 
  }
  dv2_sum = get_dv2_sum(); 

  dr += vdv_sum; 
  ddr += dv2_sum; 
}
/*--------------------------------------------------------*/
double AzReg_Tsrbase::penalty()
const
{
  double r = 0; 
  int nx; 
  for (nx = 0; nx < tree->nodeNum(); ++nx) {
    double v = get_v(nx); 
    r += reg_depth->apply(v*v/2, tree->node(nx)->depth); 
  }

  if (forNewLeaf) {
    checkLeaf("penalty"); 
    double v = get_newleaf_v(); 
    double rr = 2*reg_depth->apply(v*v/2, get_newleaf_depth()); /* 2* for siblings */
    r += rr; 
  }

  return r; 
}
Esempio n. 3
0
/*--------------------------------------------------------*/
double AzReg_TsrSib::penalty_diff(const double leaf_w_delta[2])
const
{
  checkLeaf("penalty_diff"); 

  double diff = 0; 

  /*---  on the existing nodes  ---*/
  double delsum = leaf_w_delta[0] + leaf_w_delta[1]; 
  diff += vdv_sum * delsum; 
  diff += (dv2_sum * (delsum*delsum) * 0.5); 

  /*---  on the new leaf nodes  ---*/
  double leaf_v = (leaf_w_delta[0] - leaf_w_delta[1])/2; 
#if 0 
  diff += newleaf_dep_factor*leaf_v*leaf_v/2*2; /* "*2" for two leaves */
#else
  diff += newleaf_dep_factor*leaf_v*leaf_v; /* "/2" and "*2" (for two leaves) cancel out */
#endif 

  return diff; 
}
Esempio n. 4
0
/**
  *  dr=sum_j v_j dv_j; ddr=sum_j dv_j^2
  *  v_j = bar_j - bar_{p(j)} where p(j) is j's parent. 
  * 
  *  output: vdv_sum, dv2_sum, dr, ddr, and newleaf_dep_factor
 **/
void AzReg_TsrSib::update() 
{
  /* vdv_sum, dv2_sum: don't include new leaf nodes */
  /* dr, ddr:           include new leaf nodes */

  if (focus_nx < 0) {
    throw new AzException("AzReg_TsrSib::update", "no focus node"); 
  }

  dr = ddr = 0; 

  if (forNewLeaf) {
    checkLeaf("update"); 

    /*---  new leaf nodes: v=0, dv=0.5,-0.5  ---*/
    double dv = 0.5; 
    int depth = get_newleaf_depth(); 
    newleaf_dep_factor = reg_depth->apply(1, depth); 
    ddr += dv*dv*newleaf_dep_factor*2; /* *2 for two leaves */
  }
 
  const AzSvect *v_dv = av_dv.point(focus_nx); 
  const double *v_arr = v_v.point(); 

  vdv_sum = dv2_sum = 0; 

  if (doShortCut) {
    /* 
     * Use the fact that v[s]+v[t] = 0, dv[s]+dv[t]=0 if s and t are siblings, 
     * dv only depends on the distance from the leaf, and that 
     * dv<>0 only for the ancestors and ancestors' siblings of the base leaf.  
     */
    double dv = 0.5; 
    if (forNewLeaf) {
      dv = 0.25; 
    }

    int nx = focus_nx; 
    for ( ; ; ) {
      const AzTrTreeNode *np = tree->node(nx); 
      int px = np->parent_nx; 
      int depth = np->depth; 
      double v = v_arr[nx]; 

      if (depth == 0) { /* root */
        dv *= 2; 
        double dv_dep_factor = dv*reg_depth->apply(1, depth);   
        vdv_sum += v*dv_dep_factor; 
        dv2_sum += dv*dv_dep_factor; 
        break; 
      }
      else {
        double dv_dep_factor = dv*reg_depth->apply(1, depth); 
        vdv_sum += 2*v*dv_dep_factor;   /* *2 for the sibling */
        dv2_sum += 2*dv*dv_dep_factor;  /* *2 for the sibling */
      }

      nx = px; 
      dv /= 2; 
    }
  }
  else {
    AzCursor cur; 
    for ( ; ; ) {
      double dv; 
      int nx = v_dv->next(cur, dv); 
      if (nx < 0) break; 

      double v = v_arr[nx]; 
      int depth = tree->node(nx)->depth; 
      double dv_dep_factor = dv*reg_depth->apply(1, depth); 

      vdv_sum += v * dv_dep_factor; 
      dv2_sum += dv * dv_dep_factor; 
    }
  }
  dr += vdv_sum; 
  ddr += dv2_sum; 
}
Esempio n. 5
0
// if allkeys is set, stores all found keys there
// if strongcheck is true, do full horizontal traversals for every node (slow)
void checkCoid(COid startcoid, Set<I64> *allkeys, bool strongcheck){
  Transaction *tx;
  tx = new Transaction(SC);
  LinkList<COidQueueElement> coidqueue;
  Set<COid> pastcoids;
  COidQueueElement *el, *elchild;
  COid coid;
  COid child;
  int res;
  Ptr<Valbuf> buf;
  i64 fencemin, fencemax;

  SuperValue *sv;

  el = new COidQueueElement(startcoid);
  el->fencemin = LLONG_MIN;
  el->fencemax = LLONG_MAX;
  coidqueue.pushTail(el);

  while (!coidqueue.empty()){
    el = coidqueue.popHead();
    coid = el->coid;
    fencemin = el->fencemin;
    fencemax = el->fencemax;
    delete el;

    if (pastcoids.belongs(coid)){
      printf("COid %016llx:%016llx referenced more than once\n", (long long)coid.cid, (long long)coid.oid);
      assert(0);
    } else pastcoids.insert(coid);
    
    // read coid
    res = tx->vsuperget(coid, buf, 0, 0); assert(res==0);

    if (buf->type==0){
      printf("COid %llx:%llx not a supervalue\n", (long long)coid.cid, (long long)coid.oid);
      assert(0);
      continue;
    }

    sv = buf->u.raw;

    checkNodeFence(coid, sv, fencemin, fencemax);
    checkNodeMonot(sv);
    checkHorizontal(tx, coid, 0, strongcheck);
    checkHorizontal(tx, coid, 1, strongcheck);
    
    if (sv->Attrs[DTREENODE_ATTRIB_FLAGS] & DTREENODE_FLAG_LEAF){ // this is a leaf node
      checkLeaf(coid, sv, allkeys);
    } else {  // this is an inner node
      checkInner(coid, sv);
    }

    if (!(sv->Attrs[DTREENODE_ATTRIB_FLAGS] & DTREENODE_FLAG_LEAF)){
      // add children to queue
      child.cid = coid.cid;
      for (int i=0; i < sv->Ncells; ++i){
        child.oid = sv->Cells[i].value;
        elchild = new COidQueueElement(child);

        if (sv->CellType == 0){ // intkey
          if (i==0) elchild->fencemin = fencemin;
          else elchild->fencemin = sv->Cells[i-1].nKey;
          elchild->fencemax = sv->Cells[i].nKey;
        } else {
          // checking functionality is disabled for non-intkey trees, so just set fences to 0
          elchild->fencemin = elchild->fencemax = 0;
        }
        coidqueue.pushTail(elchild);
      }
      // now add the last pointer
      child.oid = sv->Attrs[DTREENODE_ATTRIB_LASTPTR];
      elchild = new COidQueueElement(child);
      if (sv->CellType == 0){ // intkey
        if (sv->Ncells >= 1) elchild->fencemin = sv->Cells[sv->Ncells-1].nKey;
        else elchild->fencemin = fencemin;
        elchild->fencemax = fencemax;
      } else {
        elchild->fencemin = elchild->fencemax = 0;
      }
      coidqueue.pushTail(elchild);
    }
  }
  delete tx;
}