Ejemplo n.º 1
0
    void kinect_gbuffer::update(ID3D11DeviceContext* context)
    {
        if (has_new_color_)
        {
            update_color(context);
        }

        if (has_new_depth_)
        {
            update_depth(context);
        }

        // reset state
        has_new_depth_ = has_new_color_ = false;
    }
/*
 * Extend mondrian block to include new training data
 */
void MondrianNode::extend_mondrian_block(const Sample& sample) {
    if (settings_->debug)
        cout << "### extend_mondrian_block: " << endl;

    float split_cost = 0.; /* On split_cost depends 
                             if a new split is introduced */
    /* 
     * Set new lower and upper boundary:
     *  - e_lower = max(l^x_j - x,0)
     *  - e_upper = min(x - u^x_j,0)
     */
    arma::fvec zero_vec(mondrian_block_->get_feature_dim(), arma::fill::zeros);
    arma::fvec tmp_min_block = mondrian_block_->get_min_block_dim();
    arma::fvec tmp_max_block = mondrian_block_->get_max_block_dim();

    arma::fvec e_lower = arma::max(
            zero_vec, (tmp_min_block - sample.x));
    arma::fvec e_upper = arma::max(
            zero_vec, (sample.x - tmp_max_block));
    /*
     * sample e (expo_param) from exponential distribution with rate
     * sum_d( e^l_d + e^u_d )
     */
    float expo_param = arma::sum(e_lower) + arma::sum(e_upper);

    /* Exponential distribution */
    if (!greater_zero(expo_param)) {
        split_cost = numeric_limits<float>::infinity();
    } else {
        /* Exponential distribution */
        split_cost = random.rand_exp_distribution(expo_param);
    }

    /* Check if all labels are identical */
    if (pause_mondrian()) {
        /* Try to extend a paused Mondrian (labels are not identical) */
        assert(is_leaf_);
        split_cost = numeric_limits<float>::infinity();
    }

    /*
     * Check if current point lies
     *  (1) Current point lies within Mondrian Block B^x_j
     *  (2) Current point lies outside block B^x_j
     */
    if (equal(split_cost, max_split_costs_) == true || 
            split_cost > max_split_costs_) {
        /* (1) Current point lies within Mondrian Block B^x_j */
        if (!is_leaf_) {    
            mondrian_block_->update_range_states(sample.x); 
            add_training_point_to_node(sample);
            /* 
             * Check split dimension/location to choose left or right node
             * and recurse on child 
             */
            if (sample.x[split_dim_] <= split_loc_) {
                assert(id_left_child_node_!=NULL);
                id_left_child_node_->extend_mondrian_block(sample);
            } else {
                assert(id_right_child_node_!=NULL);
                id_right_child_node_->extend_mondrian_block(sample);
            }
        } else {
            assert(is_leaf_);
            if (!check_if_same_labels(sample)) {
                sample_mondrian_block(sample);
            }
            /* Update after calling function sample_mondrian_block,
             * because of new node would take new boundary properties */
            mondrian_block_->update_range_states(sample.x);
            add_training_point_to_node(sample);
        }
    } else {
        /* (2) Current point lies outside block B^x_j */
        /* Initialize new parent node */
        int feature_dim = mondrian_block_->get_feature_dim();
        arma::fvec min_block = arma::min(mondrian_block_->get_min_block_dim(), 
                sample.x);
        arma::fvec max_block = arma::max(mondrian_block_->get_max_block_dim(),
                sample.x);
        MondrianNode* new_parent_node = new MondrianNode(num_classes_,
                feature_dim, budget_, *id_parent_node_,
                min_block, max_block, *settings_, depth_);
        /* Set "new_parent_node" as new parent of current node */
        /* Pass histogram of current node to new parent node */
        new_parent_node->init_update_posterior_node_incremental(*this, sample);
        /* 
         * Sample split dimension \delta, choosing d with probability 
         * proportional to e^l_d + d^u_d
         */
        arma::fvec feat_score = e_lower + e_upper;
        /* Problem can occur that min and max boundary value are the same
         * at a sampled split location -> solution: sample again until
         * it is different */
        int split_dim = sample_multinomial_scores(feat_score);
        /* Check if it is possible to introduce a split in current dimension */
        int max_sample_search = mondrian_block_->get_feature_dim();
        int count_sample_search = 0;
        while (count_sample_search < max_sample_search) {
            if (equal(min_block[split_dim_], max_block[split_dim_])) {
                split_dim_ = sample_multinomial_scores(min_block);
            } else {
                break;
            }
            count_sample_search += 1;
        }   
        float split_loc = 0.0;  /* Split location */
        /*
         * Sample split location \xi uniformly from interval 
         * [u^x_{j,\delta},x_\delta] if x_\delta > u^x_{j,\delta}
         * [x_delta, l^x_{j,\delta}] else
         */
        if (sample.x[split_dim] > mondrian_block_->get_max_block_dim()
                [split_dim]) {
            split_loc = random.rand_uniform_distribution(
                    mondrian_block_->get_min_block_dim()[split_dim],
                    sample.x[split_dim]);
        } else {
            split_loc = random.rand_uniform_distribution(sample.x[split_dim], 
                    mondrian_block_->get_min_block_dim()[split_dim]);
        }
        float new_budget = budget_ - split_cost;
        /* 
         * Insert a new node (j~) just above node j in the tree,
         * and a new leaf'', sibling to j 
         */
        bool is_left_node = false;
        arma::fvec new_child_block(mondrian_block_->get_feature_dim());
        if (sample.x[split_dim] > split_loc) {
            is_left_node = true;
            new_child_block = max_block;
        } else {
            new_child_block = min_block;
        }
        /* Grow Mondrian child node of the "outer Mondrian" */
        int new_depth = depth_ +1;
        MondrianNode* child_node = new MondrianNode(num_classes_,
                feature_dim, new_budget, *new_parent_node,
                new_child_block, new_child_block, *settings_, new_depth);
        /* Set child nodes of new created parent node ("new_parent_node") */
        new_parent_node->set_child_node(*child_node, (!is_left_node));
        new_parent_node->set_child_node(*this, is_left_node);
        new_parent_node->is_leaf_ = false;
        /* Set "new_parent_node" as new child node of current parent node */
        if (id_parent_node_ != NULL ) { /* root node */
            if (id_parent_node_->id_left_child_node_ == this) {
                id_parent_node_->set_child_node(*new_parent_node, true);
            } else {
                id_parent_node_->set_child_node(*new_parent_node, false);
            }
        }
        /* Set "new_parent_node" as new parent of current node */
        id_parent_node_ = new_parent_node;
        /*
         * Initialize posterior of new created child node 
         * (initialize histogram with zeros -> pointer = NULL) 
         */
        MondrianNode* tmp_node = NULL;
        child_node->init_update_posterior_node_incremental(*tmp_node, sample);

        child_node->sample_mondrian_block(sample);

        budget_ = new_budget;
        /* Update split cost of current and new parent node */ 
        new_parent_node->max_split_costs_ = split_cost;
        new_parent_node->split_loc_ = split_loc;
        new_parent_node->split_dim_ = split_dim;
        max_split_costs_ -= split_cost;
        update_depth();
    }
     
}
Ejemplo n.º 3
0
/* ------------------------------------------------------------------------
@NAME       : bt_split_list()
@INPUT      : string - string to split up; whitespace must be collapsed
                       eg. by bt_postprocess_string()
              delim  - delimiter to use; must be lowercase and should be
                       free of whitespace (code requires that delimiters
                       in string be surrounded by whitespace)
              filename - source of string (for warning messages)
              line     - 1-based line number into file (for warning messages)
              description - what substrings are (eg. "name") (for warning
                            messages); if NULL will use "substring"
@OUTPUT     : substrings (*substrings is allocated by bt_split_list() for you)
@RETURNS    : number of substrings found
@DESCRIPTION: Splits a string using a fixed delimiter, in the BibTeX way:
                * delimiters at beginning or end of string are ignored
                * delimiters in string must be surrounded by whitespace
                * case insensitive
                * delimiters at non-zero brace depth are ignored

              The list of substrings is returned as *substrings, which
              is an array of pointers into a duplicate of string.  This
              duplicate copy has been scribbled on such that there is 
              a nul byte at the end of every substring.  You should
              call bt_free_list() to free both the duplicate copy
              of string and *substrings itself.  Do *not* walk over
              the array free()'ing the substrings yourself, as this is
              invalid -- they were not malloc()'d!
@GLOBALS    : 
@CALLS      : 
@CALLERS    : anyone (exported by library)
@CREATED    : 1997/05/05, GPW
@MODIFIED   : 
-------------------------------------------------------------------------- */
bt_stringlist *
bt_split_list (char *   string,
               char *   delim,
               char *   filename,
               int      line,
               char *   description)
{
   int    depth;                        /* brace depth */
   int    i, j;                         /* offset into string and delim */
   int    inword;                       /* flag telling if prev. char == ws */
   int    string_len;
   int    delim_len;
   int    maxdiv;                       /* upper limit on no. of divisions */
   int    maxoffs;                      /* max offset of delim in string */
   int    numdiv;                       /* number of divisions */
   int *  start;                        /* start of each division */
   int *  stop;                         /* stop of each division */
   bt_stringlist *
          list;                         /* structure to return */

   if (string == NULL)
      return NULL;
   if (description == NULL)
      description = "substring";

   string_len = strlen (string);
   delim_len = strlen (delim);
   maxdiv = (string_len / delim_len) + 1;
   maxoffs = string_len - delim_len + 1;

   /* 
    * This is a bit of a band-aid solution to the "split empty string"
    * bug (formerly hit the internal_error() at the end of hte function).
    * Still need a general "detect and fix unpreprocessed string" -- 
    * admittedly a different bug/misfeature.
    */
   if (string_len == 0)
      return NULL;

   start = (int *) alloca (maxdiv * sizeof (int));
   stop = (int *) alloca (maxdiv * sizeof (int));

   list = (bt_stringlist *) malloc (sizeof (bt_stringlist));

   depth = 0;
   i = j = 0;
   inword = 1;                          /* so leading delim ignored */
   numdiv = 0;
   start[0] = 0;                        /* first substring @ start of string */

   while (i < maxoffs)
   {
      /* does current char. in string match current char. in delim? */
      if (depth == 0 && !inword && tolower (string[i]) == delim[j])
      {
         j++; i++;

         /* have we found an entire delim, followed by a space? */
         if (j == delim_len && string[i] == ' ')
         {

            stop[numdiv] = i - delim_len - 1;
            start[++numdiv] = ++i;
            j = 0;

#if DEBUG
            printf ("found complete delim; i == %d, numdiv == %d: "
                    "stop[%d] == %d, start[%d] == %d\n",
                    i, numdiv, 
                    numdiv-1, stop[numdiv-1],
                    numdiv, start[numdiv]);
#endif
         }
      }
      
      /* no match between string and delim, at non-zero depth, or in a word */
      else
      {
         update_depth (string, i, depth);
         inword = (i < string_len) && (string[i] != ' ');
         i++;
         j = 0;
      }
   }

   stop[numdiv] = string_len;           /* last substring ends just past eos */
   list->num_items = numdiv+1;


   /* 
    * OK, now we know how many divisions there are and where they are --
    * so let's split that string up for real!
    * 
    * list->items will be an array of pointers into a duplicate of
    * `string'; we duplicate `string' so we can safely scribble on it and
    * free() it later (in bt_free_list()).
    */
       
   list->items = (char **) malloc (list->num_items * sizeof (char *));
   list->string = strdup (string);

   for (i = 0; i < list->num_items; i++)
   {
      /* 
       * Possible cases:
       *   - stop < start is for empty elements, e.g. "and and" seen in
       *     input.  (`start' for empty element will be the 'a' of the
       *     second 'and', and its stop will be the ' ' *before* the
       *     second 'and'.)
       *   - stop > start is for anything else between two and's (the usual)
       *   - stop == start should never happen if the loop above is correct 
       */

      if (stop[i] > start[i])           /* the usual case */
      {
         list->string[stop[i]] = 0;
         list->items[i] = list->string+start[i];
      }
      else if (stop[i] < start[i])      /* empty element */
      {
         list->items[i] = NULL;
         general_error (BTERR_CONTENT, filename, line, 
                        description, i+1, "empty %s", description);
      }
      else                              /* should not happen! */
      {
         internal_error ("stop == start for substring %d", i);
      }
   }

   return list;
/*    return num_substrings; */

} /* bt_split_list () */
Ejemplo n.º 4
0
/* ------------------------------------------------------------------------
@NAME       : find_tokens
@INPUT      : name       - string to tokenize (should be a private copy
                           that we're free to clobber and mangle)
@OUTPUT     : comma_token- number of token immediately preceding each comma
                           (caller must allocate with at least one element
                           per comma in `name')
@RETURNS    : newly-allocated bt_stringlist structure
@DESCRIPTION: Finds tokens in a string; delimiter is space or comma at
              brace-depth zero.  Assumes whitespace has been collapsed
              and find_commas has been run on the string to remove
              whitespace around commas and any trailing commas.

              The bt_stringlist structure returned can (and should) be
              freed with bt_free_list().
@GLOBALS    : 
@CALLS      : 
@CALLERS    : bt_split_name()
@CREATED    : 1997/05/14, Greg Ward
@MODIFIED   : 
-------------------------------------------------------------------------- */
static bt_stringlist *
find_tokens (char *  name,
             int *   comma_token)
{
   int    i;                            /* index into name */
   int    num_tok;
   int    in_boundary;                  /* previous char was ' ' or ',' */
   int    cur_comma;                    /* index into comma_token */
   int    len;
   int    depth;
   bt_stringlist *
          tokens;

   i = 0;
   in_boundary = 1;                     /* so first char will start a token */
   cur_comma = 0;
   len = strlen (name);
   depth = 0;

   tokens = (bt_stringlist *) malloc (sizeof (bt_stringlist));
   /* tokens->string = name ? strdup (name) : NULL; */
   tokens->string = name;
   num_tok = 0;
   tokens->items = NULL;

   if (len == 0)                        /* empty string? */
      return tokens;                    /* return empty token list */

   tokens->items = (char **) malloc (sizeof (char *) * len);

   while (i < len)
   {
      if (depth == 0 && in_boundary)    /* at start of a new token */
      {
         tokens->items[num_tok++] = name+i;
      }

      if (depth == 0 && (name[i] == ' ' || name[i] == ','))
      {
         /* if we're at a comma, record the token preceding the comma */

         if (name[i] == ',')
         {
            comma_token[cur_comma++] = num_tok-1;
         }

         /* 
          * if already in a boundary zone, we have an empty token
          * (caused by multiple consecutive commas)
          */
         if (in_boundary)
         {
            tokens->items[num_tok-1] = NULL;
         }

         /* in any case, mark the end of one token and prepare for the 
          * start of the next
          */
         name[i] = (char) 0;
         in_boundary = 1;
      }
      else
      {
         in_boundary = 0;               /* inside a token */
      }

      update_depth (name, i, depth);
      i++;

   } /* while i */

   tokens->num_items = num_tok;
   return tokens;

} /* find_tokens() */
Ejemplo n.º 5
0
/* ------------------------------------------------------------------------
@NAME       : find_commas
@INPUT      : name       - string to search for commas
              max_commas - maximum number of commas to allow (if more than 
                           this number are seen, a warning is printed and
                           the excess commas are removed)
@OUTPUT     : 
@RETURNS    : number of commas found
@DESCRIPTION: Counts and records positions of commas at brace-depth 0.
              Modifies string in-place to remove whitespace around commas,
              excess commas, and any trailing commas; warns on excess or
              trailing commas.  Excess commas are removed by replacing them
              with space and calling bt_postprocess_string() to collapse 
              whitespace a second time; trailing commas are simply replaced
              with (char) 0 to truncate the string.

              Assumes whitespace has been collapsed (ie. no space at
              beginning or end of string, and all internal strings of
              whitespace reduced to exactly one space).
@GLOBALS    : 
@CALLS      : name_warning() (if too many commas, or commas at end)
@CALLERS    : bt_split_name()
@CREATED    : 1997/05/14, Greg Ward
@MODIFIED   : 
-------------------------------------------------------------------------- */
static int 
find_commas (name_loc * loc, char *name, int max_commas)
{
   int    i, j;
   int    depth;
   int    num_commas;
   int    len;
   boolean at_comma;
   boolean warned;

   i = j = 0;
   depth = 0;
   num_commas = 0;
   len = strlen (name);
   warned = 0;

   /* First pass to check for and blank out excess commas */

   for (i = 0; i < len; i++)
   {
      update_depth (name, i, depth);
      if (depth == 0 && name[i] == ',')
      {
         num_commas++;
         if (num_commas > max_commas)
         {
            if (! warned)
            {
               name_warning (loc, "too many commas in name (removing extras)");
               warned = TRUE;
            }
            name[i] = ' ';
         }
      }
   }

   /* 
    * If we blanked out a comma, better re-collapse whitespace.  (This is
    * a bit of a cop-out -- I could probably adjust i and j appropriately
    * in the above loop to do the collapsing for me, but my brain
    * hurt when I tried to think it through.  Some other time, perhaps.
    */

   if (warned)
      bt_postprocess_string (name, 1);

   /* Now the real comma-finding loop (only if necessary) */

   if (num_commas == 0)
      return 0;
   
   num_commas = 0;
   i = 0;
   while (i < len)
   {
      at_comma = (depth == 0 && name[i] == ',');
      if (at_comma)
      {
         while (j > 0 && name[j-1] == ' ') j--;
         num_commas++;
      }

      update_depth (name, i, depth);
      if (i != j)
         name[j] = name[i];

      i++; j++;
      if (at_comma)
      {
         while (i < len && name[i] == ' ') i++;
      }
   } /* while i */

   if (i != j) name[j] = (char) 0;
   j--;

   if (name[j] == ',') 
   {
      name_warning (loc, "comma(s) at end of name (removing)");
      while (name[j] == ',')
      {
         name[j--] = (char) 0;
         num_commas--;
      }
   }

   return num_commas;

} /* find_commas() */