As the title mentions my goal is to use std::nth_element on a Armadillo-Matrix which contains a set of N points in d dimensions, i.e. a Nxd matrix. The rows represent a d-dimensional point. The comparison of two rows should be done along a fixed dimension, i.e.
row(i) < row(j) iff A(i, s) < A(j,s) (comparing the s-entry of each row).
My idea was now to use the column-iterators provided by Armadillo and overload the std::swap function to be used with two column-iterators and my desired swap:
void swap(arma::mat::col_iterator& lhs, arma::mat::col_iterator& rhs)
{
lhs->M->swap_rows(lhs->current_row, rhs->current_row);
}
Here I use the swap_rows methods build in arma::mat. The call to std::nth_element looks like this:
// Setting indices to indicate which submatrix should be sorted:
arma::uword first = nodes[currentNodeIndex].indexFirstElem;
arma::uword last = nodes[currentNodeIndex].indexLastElem + 1;
arma::uword nth = (last - first) / 2;
// Calling std::nth_element:
std::nth_element(points.begin_col(first), points.begin_col(nth), points.begin_col(last));
Now the problem is that I get compiler-errors when overloading swap in the above manner:
kd_tree.cpp: In function ‘void swap(double*&, double*&)’:
kd_tree.cpp:25:7: error: request for member ‘M’ in ‘* lhs’, which is of non-class type ‘double’
25 | lhs->M->swap_rows(lhs->current_row, rhs->current_row);
| ^
kd_tree.cpp:25:25: error: request for member ‘current_row’ in ‘* lhs’, which is of non-class type ‘double’
25 | lhs->M->swap_rows(lhs->current_row, rhs->current_row);
| ^~~~~~~~~~~
kd_tree.cpp:25:43: error: request for member ‘current_row’ in ‘* rhs’, which is of non-class type ‘double’
25 | lhs->M->swap_rows(lhs->current_row, rhs->current_row);
I guess the errors tell me that the column-iterator is not able to access the matrix M on which it operates? Also it seems like I cannot access the current_row where my iterator is at.
I tried looking at the armadillo-documentation but there was no further information on the actual interface of said iterator apart from its existence and how to initialize it with begin()
. Also looking through the actual code of armadillo did not help me as I haven't found the definition of arma:mat::col_iterator
.
So my question is what do the above errors tell me and how can I fix this? Also if you happen to know a better approach to the described problem that would be highly appreciated as well. :)
Beforehand I tried writing a custom random-access-operator for the rows of arma::mat but this failed as I could not overload value_type& operator*() { return A.row(i); }
as A.row(i)
seems to return a temporary arma::vec object or something.
Edit: I should mention that I tried implementing my own iterator using this code snippet and adjusting it to my needs. The swap-function above is also inspired by this code-snippet.