2014-09-30 8 views
2

나노 플라워 radiusSearch 기능의 매개 변수 search_radius에 대해 의문의 여지가 있습니다. 내 코드는 다음과 같습니다Nanoflann 반경 검색

#include <iostream> 
#include <vector> 
#include <map> 

#include "nanoflann.hpp" 
#include "Eigen/Dense" 

int main() 
{ 
    Eigen::MatrixXf mat(7, 2); 
    mat(0,0) = 0.0; mat(0,1) = 0.0; 
    mat(1,0) = 0.1; mat(1,1) = 0.0; 
    mat(2,0) = -0.1; mat(2,1) = 0.0; 
    mat(3,0) = 0.2; mat(3,1) = 0.0; 
    mat(4,0) = -0.2; mat(4,1) = 0.0; 
    mat(5,0) = 0.5; mat(5,1) = 0.0; 
    mat(6,0) = -0.5; mat(6,1) = 0.0; 

    std::vector<float> query_pt(2); 
    query_pt[0] = 0.0; 
    query_pt[1] = 0.0; 

    typedef nanoflann::KDTreeEigenMatrixAdaptor<Eigen::MatrixXf> KDTree; 

    KDTree index(2, mat, 10); 
    index.index->buildIndex(); 

    { // Find nearest neighbors in radius 
     const float search_radius = 0.1f; 
     std::vector<std::pair<size_t, float> > matches; 

     nanoflann::SearchParams params; 

     const size_t nMatches = index.index->radiusSearch(&query_pt[0], search_radius, matches, params); 

     std::cout << "RadiusSearch(): radius = " << search_radius << " -> " 
        << nMatches << " matches" << std::endl; 
     for(size_t i = 0; i < nMatches; i++) 
      std::cout << "Idx[" << i << "] = " << matches[i].first 
         << " dist[" << i << "] = " << matches[i].second << std::endl; 
     std::cout << std::endl; 
    } 
} 

내가 원하는 것은 내가 매트릭스 그러나 놀랍게도 처음 세 요소는 처음 5를 반환 기대했던, 0.1의 반경 내에서 포인트를 가지고, 그래서 집단. 거리를 확인하는 것은 그것이 실제 거리가 아니라 거리 제곱 (오른쪽?) 인 것처럼 보입니다. 그래서 나는 예상했던 것을 얻기 위해 반경을 제곱했으나 불행히도 첫 번째 점만 리턴합니다.

는 그래서 0.02에 0.1^2 = 0.01로부터 약간 반경을 증가 마지막 I가 원하는 지점을 얻었다.

이제 이웃 경계에 포함되는 점들이 포함되어서는 안된다는 것이 문제입니다. nanoflann에서이 조건을 어디에서 변경할 수 있습니까?

답변

4

KDTreeEigenMatrixAdaptorstarts like this의 전체 정의 :

template <class MatrixType, int DIM = -1, 
      class Distance = nanoflann::metric_L2, 
      typename IndexType = size_t> 
struct KDTreeEigenMatrixAdaptor 
{ 
//... 

그래서, 예 :

제곱 유클리드 거리 펑 (일반 버전 : 기본 메트릭은 제곱 유클리드 거리의 L2_Adaptor 구조체, and documented as follows입니다 , 고차원 데이터 세트에 최적화 됨).

두 번째 문제는 두 가지 측면이 있습니다. 첫 번째는 부동 소수점 수에 관해서는 평등에 의존하지 말아야한다는 것입니다 (필수 참조 자 : David Goldberg, What every computer scientist should know about floating-point arithmetic, ACM Computing Surveys, 1991).

둘째, 원칙적으로 당신이 옳습니다. nanoflann은 검색 방법에서 사용되는 CountRadiusResultSet 클래스의 구현을 찾을 수있는 소스 코드 인 FLANN을 기반으로합니다.

: 다음 기준 예 (Matthew T. Dickerson, David Eppstein, Algorithms for Proximity Problems in Higher Dimensions, Computational Geometry, 1996)에 관해서는,이 문제에 대한 공통 정의는 "이하"관련 보인다 반면

void addPoint(DistanceType dist, size_t index) 
{ 
    if (dist<radius) { 
     count++; 
    } 
} 

: 주요 방법은 다음의 구현이 문제 1.(고정 반경 가까운 이웃 검색) R 거리와 거리에 n 개의 별개 점이있는 유한 집합 S가 주어집니다. 각 점 p ∈ S에 대해 p에서 q까지의 거리가 이되도록보다 작거나 같은 점 (p, q), q ∈ S의 모든 쌍을보고하십시오.

하지만 그게 수학의 및 부동 소수점 연산 문제를 효과적으로 엄격한 방식으로 평등에 대해 생각 억제 컴퓨터 과학

(내게로 마지막 강조).

CountRadiusResultSet 클래스의 사용법이 FLANN 내부의 radiusSearch 메소드 구현에 하드 코딩되어 있기 때문에 여기에서 유일한 선택은 반경을 늘리는 것입니다.

+0

아주 자세히 설명해 주셔서 감사합니다. 부동 소수점 산술에 대한 저서를 꼭 읽어야합니다. 또 하나의 질문은 L2_Norm이 sqrt (도트 (v, v))로 정의되지 않은 것입니다 ... 그들은 나노 플라 만의 점 (v, v)으로 유지했을 것입니다. 맞습니까? – BRabbit27

+0

@ BRabbit27 예, 그 이름은 오해의 소지가 있습니다. – BartoszKP