size_t random_index (const VectorXf & likes) { float total = likes.sum(); ASSERT_LT(0, total); while (true) { float t = random_unif(0, total); for (int i = 0, I = likes.size(); i < I; ++i) { t -= likes(i); if (t < 0) return i; } } }
float Sphere::fit_eval ( const VectorXf &fitpar, const void *user_data) { /* * Calculate the cost function value * Optimize for the radius inside here */ const fitUserNew& user = (fitUserNew)user_data; const VectorXf& r0 = fitpar; float F; MatrixXf diff = user->rr.rowwise() - r0.transpose(); VectorXf one = diff.rowwise().norm(); float sum = one.sum(); float sum2 = one.dot(one); F = sum2 - sum*sum/user->rr.rows(); if(user->report) std::cout << "r0: " << 1000*r0[0] << ", r1: " << 1000*r0[1] << ", r2: " << 1000*r0[2] << "; R: " << 1000*sum/user->rr.rows() << "; fval: "<<F<<std::endl; return F; }
void WCTree::growTree() { // -- If we don't need any more splits, we're done. if(pwcs_.size() < max_wcs_ || level_ == recursion_limit_) { makeLeaf(); return; } // -- Fill X_ with the center points. for(size_t i=0; i<pwcs_.size(); ++i) { X_.col(i) = pwcs_[i]->center_; } // -- Subtract off the mean. VectorXf mean = X_.rowwise().sum() / X_.cols(); for(size_t i=0; i<pwcs_.size(); ++i) { X_.col(i) -= mean; } // -- If all of the weak classifiers had the same center, this is also a leaf. if(X_.sum() == 0) { makeLeaf(); return; } // -- Power method to find the eigenvector of XX', i.e. 1st principal component. MatrixXf Xt = X_.transpose(); bool done = false; while(!done) { a_ = getRandomVector(X_.rows()); a_.normalize(); VectorXf prev = a_; while(true) { prev = a_; a_ = X_ * (Xt * a_); assert(a_.sum() != 0); if(a_.sum() == 0) { break; } a_.normalize(); if((a_ - prev).norm() < thresh_) { done = true; break; } } } // -- Compute b_ to be the mean value of a_'xt for xt in pwcs_. VectorXf bs = VectorXf::Zero(pwcs_.size()); for(size_t i=0; i<pwcs_.size(); ++i) { bs(i) = a_.dot(pwcs_[i]->center_); } b_ = bs.sum() / bs.rows(); // -- Add the newly computed a_ and b_ into the full list of constraints for the left and right children. // The right child region is all x for a_'x >= b_, or -a_'x <= -b_ // The left child region is all x for a_'x <= b_ vector<VectorXf> region_a_left = region_a_; vector<VectorXf> region_a_right = region_a_; vector<float> region_b_left = region_b_; vector<float> region_b_right = region_b_; region_a_left.push_back(a_); region_b_left.push_back(b_); region_a_right.push_back(-a_); region_b_right.push_back(-b_); // -- Compute which weak classifiers in the region go on which side of the split. vector<WeakClassifier*> left, right, left_consider, right_consider; left.reserve(pwcs_.size() + consider_.size()); right.reserve(pwcs_.size() + consider_.size()); left_consider.reserve(pwcs_.size() + consider_.size()); right_consider.reserve(pwcs_.size() + consider_.size()); for(size_t i=0; i<pwcs_.size(); ++i) { double dist = bs(i) - b_; //computeDistanceToSplit(pwcs_[i]->center_); double dist2 = dist*dist; if(dist == 0) { right.push_back(pwcs_[i]); left.push_back(pwcs_[i]); } else if(dist > 0) { right.push_back(pwcs_[i]); if(dist2 <= pwcs_[i]->theta_) { left_consider.push_back(pwcs_[i]); } } else { left.push_back(pwcs_[i]); if(dist2 <= pwcs_[i]->theta_) { right_consider.push_back(pwcs_[i]); } } } // -- If all the weak classifiers are very close to each other, they can end up not being split by the // boundary. If this happens, then call this a leaf and be done with it. if(left.empty() || right.empty()) { makeLeaf(); return; } // -- See which weak classifiers that leak into this region might also leak into the child regions. for(size_t i=0; i<consider_.size(); ++i) { if(USE_QP) { int lc2=0, rc2=0; // -- Use QP solver to find which wcs belong in the consider list. clock_t start = clock(); double dist_left = computePointToPolytopeDistanceSquared(region_a_left, region_b_left, consider_[i]->center_); double dist_right = computePointToPolytopeDistanceSquared(region_a_right, region_b_right, consider_[i]->center_); // cout << "Took " << (double) (clock() - start) / (double) CLOCKS_PER_SEC * (double) 1000 << " ms to do 2 QP solves." << endl; // -- Add to consider lists. if(dist_left <= consider_[i]->theta_) { left_consider.push_back(consider_[i]); lc2++; } if(dist_right <= consider_[i]->theta_) { right_consider.push_back(consider_[i]); rc2++; } } else { // -- Old version. int rc=0, lc=0; double dist = computeDistanceToSplit(consider_[i]->center_); double dist2 = dist*dist; if(dist == 0) { rc++; lc++; right_consider.push_back(pwcs_[i]); left_consider.push_back(pwcs_[i]); } else if(dist > 0) { rc++; right_consider.push_back(consider_[i]); if(dist2 <= consider_[i]->theta_) { lc++; left_consider.push_back(consider_[i]); } } else { lc++; left_consider.push_back(consider_[i]); if(dist2 <= consider_[i]->theta_) { rc++; right_consider.push_back(consider_[i]); } } } } // -- Create the split. double left_removed = pwcs_.size() + consider_.size() - left.size() - left_consider.size(); double right_removed = pwcs_.size() + consider_.size() - right.size() - right_consider.size(); // cout << "Split removed an average of " << (left_removed + right_removed)/2.0 << " wcs." << endl; lchild_ = new WCTree(left, left_consider, recursion_limit_, level_+1, region_a_left, region_b_left); rchild_ = new WCTree(right, right_consider, recursion_limit_, level_+1, region_a_right, region_b_right); }
void normalize_l1 (VectorXf & x, float tot) { x *= tot / x.sum(); }