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(); } }
/* ------------------------------------------------------------------------ @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 () */
/* ------------------------------------------------------------------------ @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() */
/* ------------------------------------------------------------------------ @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() */