Vector2D SphSystemData2::gradientAt( size_t i, const ConstArrayAccessor1<double>& values) const { Vector2D sum; auto p = positions(); auto d = densities(); const auto& neighbors = neighborLists()[i]; Vector2D origin = p[i]; SphSpikyKernel2 kernel(_kernelRadius); const double m = mass(); for (size_t j : neighbors) { Vector2D neighborPosition = p[j]; double dist = origin.distanceTo(neighborPosition); if (dist > 0.0) { Vector2D dir = (neighborPosition - origin) / dist; sum += d[i] * m * (values[i] / square(d[i]) + values[j] / square(d[j])) * kernel.gradient(dist, dir); } } return sum; }
inline double KDERules<MetricType, KernelType, TreeType>:: Score(const size_t queryIndex, TreeType& referenceNode) { double score, maxKernel, minKernel, bound; const arma::vec& queryPoint = querySet.unsafe_col(queryIndex); const double minDistance = referenceNode.MinDistance(queryPoint); bool newCalculations = true; if (tree::TreeTraits<TreeType>::FirstPointIsCentroid && lastQueryIndex == queryIndex && traversalInfo.LastReferenceNode() != NULL && traversalInfo.LastReferenceNode()->Point(0) == referenceNode.Point(0)) { // Don't duplicate calculations. newCalculations = false; lastQueryIndex = queryIndex; lastReferenceIndex = referenceNode.Point(0); } else { // Calculations are new. maxKernel = kernel.Evaluate(minDistance); minKernel = kernel.Evaluate(referenceNode.MaxDistance(queryPoint)); bound = maxKernel - minKernel; } if (newCalculations && bound <= (absError + relError * minKernel) / referenceSet.n_cols) { // Estimate values. double kernelValue; // Calculate kernel value based on reference node centroid. if (tree::TreeTraits<TreeType>::FirstPointIsCentroid) { kernelValue = EvaluateKernel(queryIndex, referenceNode.Point(0)); } else { kde::KDEStat& referenceStat = referenceNode.Stat(); kernelValue = EvaluateKernel(queryPoint, referenceStat.Centroid()); } densities(queryIndex) += referenceNode.NumDescendants() * kernelValue; // Don't explore this tree branch. score = DBL_MAX; } else { score = minDistance; } ++scores; traversalInfo.LastReferenceNode() = &referenceNode; traversalInfo.LastScore() = score; return score; }
void SphSystemData2::updateDensities() { auto p = positions(); auto d = densities(); const double m = mass(); parallelFor( kZeroSize, numberOfParticles(), [&] (size_t i) { double sum = sumOfKernelNearby(p[i]); d[i] = m * sum; }); }
void CurvatureDetector::detect(const Graph& graph, const std::vector<Point2D>& graphPoints, std::vector< std::vector<Point2D> >& operatorA, std::vector< std::vector<double> >& signalDiff, std::vector< std::vector<unsigned int> >& indexes) const { operatorA.resize(m_scales.size()); signalDiff.resize(m_scales.size()); indexes.resize(m_scales.size()); unsigned int vertexNumber = boost::num_vertices(graph); std::vector< std::vector< double > > distances(vertexNumber, std::vector<double>(vertexNumber)); boost::johnson_all_pairs_shortest_paths(graph, distances); for(unsigned int scale = 0; scale < m_scales.size(); scale++){ double currentScale = m_scales[scale]; double normalizer = sqrt(2*M_PI)*currentScale; std::vector<double> densities(vertexNumber, 0.); operatorA[scale].resize(vertexNumber, Point2D()); signalDiff[scale].resize(vertexNumber,0.); double weights[vertexNumber][vertexNumber]; double weightNormalizer[vertexNumber]; for(unsigned int vertex1 = 0; vertex1 < vertexNumber; vertex1++){ for(unsigned int vertex2 = 0; vertex2 < vertexNumber; vertex2++){ weights[vertex1][vertex2] = normalizer * exp(-distances[vertex1][vertex2] * distances[vertex1][vertex2]/(2 * currentScale * currentScale)); densities[vertex1] += weights[vertex1][vertex2]; } } for(unsigned int vertex1 = 0; vertex1 < vertexNumber; vertex1++){ weightNormalizer[vertex1] = 0.; for(unsigned int vertex2 = 0; vertex2 < vertexNumber; vertex2++){ weights[vertex1][vertex2] /= densities[vertex1] * densities[vertex2]; weightNormalizer[vertex1] += weights[vertex1][vertex2]; } } for(unsigned int vertex1 = 0; vertex1 < vertexNumber; vertex1++){ for(unsigned int vertex2 = 0; vertex2 < vertexNumber; vertex2++){ operatorA[scale][vertex1] = operatorA[scale][vertex1] + weights[vertex1][vertex2] * graphPoints[vertex2]; } operatorA[scale][vertex1] = operatorA[scale][vertex1] * ( 1. / weightNormalizer[vertex1]); Point2D pointDifference = operatorA[scale][vertex1] - graphPoints[vertex1]; double temporary = 2 * (1/currentScale) * hypot(pointDifference.x, pointDifference.y); signalDiff[scale][vertex1] = temporary * exp(-temporary); } for(unsigned int j = 2; j < signalDiff[scale].size() - 2; j++){ if(m_peakFinder->isPeak(signalDiff[scale], j)){ indexes[scale].push_back(j); } } } }
Vector2D SphSystemData2::interpolate( const Vector2D& origin, const ConstArrayAccessor1<Vector2D>& values) const { Vector2D sum; auto d = densities(); SphStdKernel2 kernel(_kernelRadius); const double m = mass(); neighborSearcher()->forEachNearbyPoint( origin, _kernelRadius, [&] (size_t i, const Vector2D& neighborPosition) { double dist = origin.distanceTo(neighborPosition); double weight = m / d[i] * kernel(dist); sum += weight * values[i]; }); return sum; }
Vector2D SphSystemData2::laplacianAt( size_t i, const ConstArrayAccessor1<Vector2D>& values) const { Vector2D sum; auto p = positions(); auto d = densities(); const auto& neighbors = neighborLists()[i]; Vector2D origin = p[i]; SphSpikyKernel2 kernel(_kernelRadius); const double m = mass(); for (size_t j : neighbors) { Vector2D neighborPosition = p[j]; double dist = origin.distanceTo(neighborPosition); sum += m * (values[j] - values[i]) / d[j] * kernel.secondDerivative(dist); } return sum; }
inline force_inline double KDERules<MetricType, KernelType, TreeType>::BaseCase( const size_t queryIndex, const size_t referenceIndex) { // If reference and query sets are the same we don't want to compute the // estimation of a point with itself. if (sameSet && (queryIndex == referenceIndex)) return 0.0; // Avoid duplicated calculations. if ((lastQueryIndex == queryIndex) && (lastReferenceIndex == referenceIndex)) return 0.0; // Calculations. const double distance = metric.Evaluate(querySet.col(queryIndex), referenceSet.col(referenceIndex)); densities(queryIndex) += kernel.Evaluate(distance); ++baseCases; lastQueryIndex = queryIndex; lastReferenceIndex = referenceIndex; return distance; }
inline double KDERules<MetricType, KernelType, TreeType>:: Score(TreeType& queryNode, TreeType& referenceNode) { double score, maxKernel, minKernel, bound; const double minDistance = queryNode.MinDistance(referenceNode); // Calculations are not duplicated. bool newCalculations = true; if (tree::TreeTraits<TreeType>::FirstPointIsCentroid && (traversalInfo.LastQueryNode() != NULL) && (traversalInfo.LastReferenceNode() != NULL) && (traversalInfo.LastQueryNode()->Point(0) == queryNode.Point(0)) && (traversalInfo.LastReferenceNode()->Point(0) == referenceNode.Point(0))) { // Don't duplicate calculations. newCalculations = false; lastQueryIndex = queryNode.Point(0); lastReferenceIndex = referenceNode.Point(0); } else { // Calculations are new. maxKernel = kernel.Evaluate(minDistance); minKernel = kernel.Evaluate(queryNode.MaxDistance(referenceNode)); bound = maxKernel - minKernel; } // If possible, avoid some calculations because of the error tolerance. if (newCalculations && bound <= (absError + relError * minKernel) / referenceSet.n_cols) { // Auxiliary variables. double kernelValue; kde::KDEStat& referenceStat = referenceNode.Stat(); kde::KDEStat& queryStat = queryNode.Stat(); // If calculating a center is not required. if (tree::TreeTraits<TreeType>::FirstPointIsCentroid) { kernelValue = EvaluateKernel(queryNode.Point(0), referenceNode.Point(0)); } // Sadly, we have no choice but to calculate the center. else { kernelValue = EvaluateKernel(queryStat.Centroid(), referenceStat.Centroid()); } // Sum up estimations. for (size_t i = 0; i < queryNode.NumDescendants(); ++i) { densities(queryNode.Descendant(i)) += referenceNode.NumDescendants() * kernelValue; } score = DBL_MAX; } else { score = minDistance; } ++scores; traversalInfo.LastQueryNode() = &queryNode; traversalInfo.LastReferenceNode() = &referenceNode; traversalInfo.LastScore() = score; return score; }
void Tree::SplitNode( const spliteType& sType, const vector<Sample>& samples, const Mat_<double>& meanShape, const vector<int>& sample_idx, // output double& threshold, Point2d* feat, vector<int> &lcID, vector<int> &rcID ) { if (sample_idx.size() == 0) { threshold = 0; feat = new Point2d[2]; feat[0].x = 0; feat[0].y = 0; feat[1].x = 0; feat[1].y = 0; lcID.clear(); rcID.clear(); return; } RNG randomGenerator(getTickCount()); Mat_<double> candidatePixelLocations(numFeats, 4); for (int i = 0; i < candidatePixelLocations.rows; i++) { double x1 = randomGenerator.uniform(-1.0, 1.0); double x2 = randomGenerator.uniform(-1.0, 1.0); double y1 = randomGenerator.uniform(-1.0, 1.0); double y2 = randomGenerator.uniform(-1.0, 1.0); if ((x1 * x1 + y1 * y1 > 1.0) || (x2 * x2 + y2 * y2 > 1.0)) { i--; continue; } candidatePixelLocations(i, 0) = x1 * radioRadius; candidatePixelLocations(i, 1) = y1 * radioRadius; candidatePixelLocations(i, 2) = x2 * radioRadius; candidatePixelLocations(i, 3) = y2 * radioRadius; } // get pixel difference features Mat_<int> densities(numFeats, (int)sample_idx.size()); for (int i = 0; i < sample_idx.size(); i++) { Mat_<double> rotation; double scale; Mat_<double> temp = Joint::Project(samples[sample_idx[i]].current, samples[sample_idx[i]].bb); Joint::SimilarityTransform(temp, meanShape, rotation, scale); for (int j = 0; i < numFeats; i++) { double project_x1 = rotation(0, 0) * candidatePixelLocations(j, 0) + rotation(0, 1) * candidatePixelLocations(j, 1); double project_y1 = rotation(1, 0) * candidatePixelLocations(j, 0) + rotation(1, 1) * candidatePixelLocations(j, 1); project_x1 = scale * project_x1 * samples[sample_idx[i]].bb.width / 2.0; project_y1 = scale * project_y1 * samples[sample_idx[i]].bb.height / 2.0; int real_x1 = scale * project_x1 + samples[sample_idx[i]].current(landmarkID, 0); int real_y1 = scale * project_y1 + samples[sample_idx[i]].current(landmarkID, 1); real_x1 = max(0.0, min((double)real_x1, samples[sample_idx[i]].image.cols - 1.0)); real_y1 = max(0.0, min((double)real_y1, samples[sample_idx[i]].image.rows - 1.0)); double project_x2 = rotation(0, 0) * candidatePixelLocations(j, 2) + rotation(0, 1) * candidatePixelLocations(j, 3); double project_y2 = rotation(1, 0) * candidatePixelLocations(j, 2) + rotation(1, 1) * candidatePixelLocations(j, 3); project_x2 = scale * project_x2 * samples[sample_idx[i]].bb.width / 2.0; project_y2 = scale * project_y2 * samples[sample_idx[i]].bb.height / 2.0; int real_x2 = scale * project_x2 + samples[sample_idx[i]].current(landmarkID, 0); int real_y2 = scale * project_y2 + samples[sample_idx[i]].current(landmarkID, 1); real_x2 = max(0.0, min((double)real_x2, samples[sample_idx[i]].image.cols - 1.0)); real_y2 = max(0.0, min((double)real_y2, samples[sample_idx[i]].image.rows - 1.0)); densities(j, i) = ((int)(samples[sample_idx[i]].image(real_y1, real_x1)) - (int)(samples[sample_idx[i]].image(real_y2, real_x2))); } } // pick the feature Mat_<int> densities_sorted = densities.clone(); cv::sort(densities, densities_sorted, CV_SORT_ASCENDING); if (sType == CLASSIFICATION) { // classification node double min_entropy = INT_MAX; double tempThresh = 0; double pos_pos_count = 0; double neg_pos_count = 0; double pos_neg_count = 0; double neg_neg_count = 0; double entropy = 0; double min_id; for (int i = 0; i < numFeats; i++) { int ind = (int)(sample_idx.size() * randomGenerator.uniform(0.05, 0.95)); tempThresh = densities_sorted(i, ind); for (int j = 0; j < sample_idx.size(); j++) { if (densities(i, j) < tempThresh) { if (samples[sample_idx[j]].label == -1) { neg_neg_count++; } else { neg_pos_count++; } } else { if (samples[sample_idx[j]].label == 1) { pos_pos_count++; } else { pos_neg_count++; } } } double p1 = (double)pos_pos_count / (pos_pos_count + pos_neg_count); double p2 = (double)pos_neg_count / (pos_pos_count + pos_neg_count); double p3 = (double)neg_pos_count / (neg_pos_count + neg_neg_count); double p4 = (double)neg_neg_count / (neg_pos_count + neg_neg_count); entropy = p1 * log(p1) + p2 * log(p2) + p3 * log(p3) + p4 * log(p4); if (entropy < min_entropy) { threshold = tempThresh; min_id = i; } } feat[0].x = candidatePixelLocations(min_id, 0) / radioRadius; feat[0].y = candidatePixelLocations(min_id, 1) / radioRadius; feat[1].x = candidatePixelLocations(min_id, 2) / radioRadius; feat[1].y = candidatePixelLocations(min_id, 3) / radioRadius; lcID.clear(); rcID.clear(); for (int j = 0; j < sample_idx.size(); j++) { if (densities(min_id, j) < threshold) { lcID.push_back(sample_idx[j]); } else { rcID.push_back(sample_idx[j]); } } } else if (sType == REGRESSION) { Mat_<double> shape_residual((int)sample_idx.size(), 2); int posCount = 0; for (int i = 0; i < sample_idx.size(); i++) { if (samples[sample_idx[i]].label == 1) { Mat_<double> residual = Joint::GetShapeResidual(samples[sample_idx[i]], meanShape); shape_residual(i, 0) = residual(landmarkID, 0); shape_residual(i, 1) = residual(landmarkID, 1); posCount++; } } vector<double> lc1, lc2; vector<double> rc1, rc2; lc1.reserve(sample_idx.size()); lc2.reserve(sample_idx.size()); rc1.reserve(sample_idx.size()); rc2.reserve(sample_idx.size()); double varOverall = (Joint::CalculateVar(shape_residual.col(0)) + Joint::CalculateVar(shape_residual.col(1))) * posCount; double maxVarReduction = 0; double tempThresh; double varLeft = 0; double varRight = 0; double varReduction = 0; double max_id = 0; for (int i = 0; i < numFeats; i++) { lc1.clear(); lc2.clear(); rc1.clear(); rc2.clear(); int ind = (sample_idx.size() * randomGenerator.uniform(0.05, 0.95)); tempThresh = densities_sorted(i, ind); for (int j = 0; j < sample_idx.size(); j++) { if (samples[sample_idx[i]].label == 1) { if (densities(i, j) < tempThresh) { lc1.push_back(shape_residual(j, 0)); lc2.push_back(shape_residual(j, 1)); } else { rc1.push_back(shape_residual(j, 0)); rc2.push_back(shape_residual(j, 1)); } } } varLeft = (Joint::CalculateVar(lc1) + Joint::CalculateVar(lc2)) * lc1.size(); varRight = (Joint::CalculateVar(rc1) + Joint::CalculateVar(rc2)) * rc2.size(); varReduction = varOverall - varLeft - varRight; if (varReduction > maxVarReduction) { maxVarReduction = varReduction; threshold = tempThresh; max_id = i; } } feat[0].x = candidatePixelLocations(max_id, 0) / radioRadius; feat[0].y = candidatePixelLocations(max_id, 1) / radioRadius; feat[1].x = candidatePixelLocations(max_id, 2) / radioRadius; feat[1].y = candidatePixelLocations(max_id, 3) / radioRadius; lcID.clear(); rcID.clear(); for (int j = 0; j < sample_idx.size(); j++) { if (densities(max_id, j) < threshold) { lcID.push_back(sample_idx[j]); } else { rcID.push_back(sample_idx[j]); } } } }