Skip to content

Commit

Permalink
Merge pull request #119 from cstew2/eigen-adaptor-rows-or-columns
Browse files Browse the repository at this point in the history
Add optional argument for Eigen matrix layout
  • Loading branch information
jlblancoc authored Mar 23, 2020
2 parents e2fc752 + 6122069 commit 40fa96b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
8 changes: 8 additions & 0 deletions examples/matrix_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ void kdtree_demo(const size_t nSamples, const size_t dim) {
// typedef KDTreeEigenMatrixAdaptor<
// Eigen::Matrix<num_t,Dynamic,Dynamic>,nanoflann::metric_L1> my_kd_tree_t;

// Dimensionality set at compile-time: Explicit selection of the distance
// metric: L2
// Row Major matrix layout
// Eigen::Matrix<num_t, Dynamic, Dynamic> mat(dim, nSamples);
// typedef KDTreeEigenMatrixAdaptor<
// Eigen::Matrix<num_t,Dynamic,Dynamic>,nanoflann::metric_L2, true>
// my_kd_tree_t;

my_kd_tree_t mat_index(dim, std::cref(mat), 10 /* max leaf */);
mat_index.index->buildIndex();

Expand Down
25 changes: 17 additions & 8 deletions include/nanoflann.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1933,8 +1933,8 @@ class KDTreeSingleIndexDynamicAdaptor {
};

/** An L2-metric KD-tree adaptor for working with data directly stored in an
* Eigen Matrix, without duplicating the data storage. Each row in the matrix
* represents a point in the state space.
* Eigen Matrix, without duplicating the data storage. You can select whether a
* row or column in the matrix represents a point in the state space.
*
* Example of usage:
* \code
Expand All @@ -1948,11 +1948,14 @@ class KDTreeSingleIndexDynamicAdaptor {
* \tparam DIM If set to >0, it specifies a compile-time fixed dimensionality
* for the points in the data set, allowing more compiler optimizations. \tparam
* Distance The distance metric to use: nanoflann::metric_L1,
* nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc.
* nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam row_major
* If set to true the rows of the matrix are used as the points, if set to false
* the columns of the matrix are used as the points.
*/
template <class MatrixType, int DIM = -1, class Distance = nanoflann::metric_L2>
template <class MatrixType, int DIM = -1, class Distance = nanoflann::metric_L2,
bool row_major = true>
struct KDTreeEigenMatrixAdaptor {
typedef KDTreeEigenMatrixAdaptor<MatrixType, DIM, Distance> self_t;
typedef KDTreeEigenMatrixAdaptor<MatrixType, DIM, Distance, row_major> self_t;
typedef typename MatrixType::Scalar num_t;
typedef typename MatrixType::Index IndexType;
typedef
Expand All @@ -1969,7 +1972,7 @@ struct KDTreeEigenMatrixAdaptor {
const std::reference_wrapper<const MatrixType> &mat,
const int leaf_max_size = 10)
: m_data_matrix(mat) {
const auto dims = mat.get().cols();
const auto dims = row_major ? mat.get().cols() : mat.get().rows();
if (size_t(dims) != dimensionality)
throw std::runtime_error(
"Error: 'dimensionality' must match column count in data matrix");
Expand Down Expand Up @@ -2012,12 +2015,18 @@ struct KDTreeEigenMatrixAdaptor {

// Must return the number of data points
inline size_t kdtree_get_point_count() const {
return m_data_matrix.get().rows();
if(row_major)
return m_data_matrix.get().rows();
else
return m_data_matrix.get().cols();
}

// Returns the dim'th component of the idx'th point in the class:
inline num_t kdtree_get_pt(const IndexType idx, size_t dim) const {
return m_data_matrix.get().coeff(idx, IndexType(dim));
if(row_major)
return m_data_matrix.get().coeff(idx, IndexType(dim));
else
return m_data_matrix.get().coeff(IndexType(dim), idx);
}

// Optional bounding-box computation: return false to default to a standard
Expand Down

0 comments on commit 40fa96b

Please sign in to comment.