[code lang="cpp"]
include <iostream>
include <string>
include <vector>
include <map>
include <flann/flann.hpp>
include <flann/io/hdf5.h>
std::vector<flann::flann_algorithm_t> indexFlannAlgorithm = { flann::FLANN_INDEX_LINEAR, flann::FLANN_INDEX_KDTREE, flann::FLANN_INDEX_KMEANS, flann::FLANN_INDEX_COMPOSITE, flann::FLANN_INDEX_KDTREE, flann::FLANN_INDEX_HIERARCHICAL, // flann::FLANN_INDEX_LSH, flann::FLANN_INDEX_AUTOTUNED };
std::map<flann::flann_algorithm_t, std::string> flannAlgorithm = { std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_LINEAR, &quot;linear&quot;), std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_KDTREE, &quot;randomized kd-tree&quot;), std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_KMEANS, &quot;k-means&quot;), std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_COMPOSITE, &quot;composite&quot;), std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_KDTREE_SINGLE, &quot;single kd-tree&quot;), std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_HIERARCHICAL, &quot;hierarchical&quot;), std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_LSH, &quot;LSH&quot;), std::pair<flann::flann_algorithm_t, std::string>(flann::FLANN_INDEX_AUTOTUNED, &quot;autotuned&quot;) };
void printMatrix( const flann::Matrix<float>&amp; mat, const std::string str ) { std::cout << str << std::endl; std::cout << &quot;dim(data): &quot; << mat.cols << std::endl; std::cout << &quot;#data: &quot; << mat.rows << std::endl; }
void loadData( flann::Matrix<float>&amp; dataset, flann::Matrix<float>&amp; query ) { flann::load_from_file(dataset, &quot;../data/dataset.hdf5&quot;, &quot;dataset&quot;); flann::load_from_file(query, &quot;../data/dataset.hdf5&quot;, &quot;query&quot;); }
void setSearchResults( const size_t numQuery, const size_t numKnn, flann::Matrix<size_t>&amp; resultIndex, flann::Matrix<float>&amp; resultDistance ) { resultIndex = flann::Matrix<size_t>(new size_t[numQuerynumKnn], numQuery, numKnn); resultDistance = flann::Matrix<float>(new float[numQuerynumKnn], numQuery, numKnn); }
flann::SearchParams getSearchParams( const flann::flann_algorithm_t indexType ) { switch (indexType) { case flann::FLANN_INDEX_KDTREE: return flann::SearchParams(256); case flann::FLANN_INDEX_KMEANS: return flann::SearchParams(128); case flann::FLANN_INDEX_COMPOSITE: return flann::SearchParams(); case flann::FLANN_INDEX_KDTREE_SINGLE: return flann::SearchParams(-1); case flann::FLANN_INDEX_HIERARCHICAL: return flann::SearchParams(2000); case flann::FLANN_INDEX_LSH: return flann::SearchParams(-1); case flann::FLANN_INDEX_AUTOTUNED: return flann::SearchParams(-2); default: return flann::SearchParams(0); } }
flann::IndexParams getIndexParams( const flann::flann_algorithm_t indexType ) { switch (indexType) { case flann::FLANN_INDEX_KDTREE: return flann::KDTreeIndexParams(); case flann::FLANN_INDEX_KMEANS: return flann::KMeansIndexParams(); case flann::FLANN_INDEX_COMPOSITE: return flann::CompositeIndexParams(); case flann::FLANN_INDEX_KDTREE_SINGLE: return flann::KDTreeSingleIndexParams(); case flann::FLANN_INDEX_HIERARCHICAL: return flann::HierarchicalClusteringIndexParams(); case flann::FLANN_INDEX_LSH: return flann::LshIndexParams(); case flann::FLANN_INDEX_AUTOTUNED: return flann::AutotunedIndexParams(); default: return flann::LinearIndexParams(); } }
void testKnnSearch( const flann::flann_algorithm_t indexType, const size_t numKnn, flann::Matrix<float>&amp; dataset, flann::Matrix<float>&amp; query, flann::Matrix<size_t>&amp; resultIndex, flann::Matrix<float>&amp; resultDistance ) { std::cout << flannAlgorithm[indexType] << std::endl; clock_t t0, t1; flann::IndexParams indexParams = getIndexParams(indexType); flann::SearchParams searchParams = getSearchParams(indexType); flann::Index<flann::L2<float> > index(dataset, indexParams); t0 = clock(); index.buildIndex(); t1 = clock(); std::cout << &quot; buildIndex: &quot; << static_cast<double>(t1-t0)/CLOCKS_PER_SEC << &quot; sec.&quot; << std::endl;
t0 = clock();
index.knnSearch(query, resultIndex, resultDistance, numKnn, searchParams);
t1 = clock();
std::cout << &amp;quot; knnSearch: &amp;quot; << static_cast<double>(t1-t0)/CLOCKS_PER_SEC << &amp;quot; sec.&amp;quot; << std::endl;
// for(int n = 0; n < query.rows; ++n) for(int n = 0; n < 2; ++n) { std::cout << &quot; &quot; << n << &quot;-th query: &quot;; for(int k = 0; k < numKnn; ++k) { std::cout << &quot;(&quot; << resultIndex[n][k] << &quot;, &quot; << resultDistance[n][k] << &quot;), &quot;; } std::cout << std::endl; } }
int main () { int numKnn = 6; flann::Matrix<float> dataset; flann::Matrix<float> query; loadData(dataset, query); printMatrix(dataset, &quot;Reference&quot;); printMatrix(query, &quot;Query&quot;);
// std::vector< std::vector<int> > indices; // std::vector<std::vector<float> > dists;
flann::Matrix<size_t> resultIndex;
flann::Matrix<float> resultDistance;
setSearchResults(query.rows, numKnn, resultIndex, resultDistance);
for(int n = 0; n < indexFlannAlgorithm.size(); ++n)
{
testKnnSearch(
indexFlannAlgorithm[n], numKnn,
dataset, query, resultIndex, resultDistance
);
}
// flann::save_to_file(resultIndex, &quot;result.hdf5&quot;, &quot;result&quot;);
delete [] dataset.ptr();
delete [] query.ptr();
delete [] resultIndex.ptr();
delete [] resultDistance.ptr();
return 0;
} [/code]