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;
}
Esempio n. 2
0
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;
        });
}
Esempio n. 4
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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]);
			}
		}
	}
}