Chances are this is a very stupid question but I spent a pretty absurd amount of time looking for it on the documentation, to no avail.
in MATLAB, the find() function gives me an array with the indices of nonzero elements. Numpy's np.nonzero function does something similar.
How do I do this in the C++ Eigen library? I have a Boolean array of
typedef <bool, 10, 1> foobar = MatrixA < MatrixB;
so far. Thanks!
In NumPy, there is a method for finding the eigenvalues and eigenvectors and it is linalg.eig (). The syntax of this function is below. Here “a” is the input square matrix. This function returns two values w and v. The w is the eigenvalues and v is the eigenvector. In the next section, you will learn how to find them with steps.
It is reasonable to expect Eigen to have a find () function. Unfortunately, Eigen doesn't have one, or even a less than operator for matrices. Fortunately, the problem isn't too difficult. Here is one solution to the problem. I am using vector to store the Column Major indices of elements > 0. You could use VectorXf if you prefer that.
[ ___] = eig ( ___,eigvalOption) returns the eigenvalues in the form specified by eigvalOption using any of the input or output arguments in previous syntaxes. Specify eigvalOption as 'vector' to return the eigenvalues in a column vector or as 'matrix' to return the eigenvalues in a diagonal matrix.
Linear indices are common in MATLAB programs, e.g. find () on a matrix returns them, whereas NumPy’s find behaves differently. When converting MATLAB code it might be necessary to first reshape a matrix to a linear sequence, perform some indexing operations and then reshape back.
Not sure if this is part of your question, but to construct the appropriate element-wise inequality result you must first cast your matrices to arrays:
MatrixXd A,B;
...
Matrix<bool,Dynamic,Dynamic> C = A.array()<B.array();
Now C
is the same size as A
and B
and C(i,j) = A(i,j) < B(i,j).
To find all of the indices (assuming column-major order) of the true entries, you can use this compact c++11 routine---as described by libigl's conversion table:
VectorXi I = VectorXi::LinSpaced(C.size(),0,C.size()-1);
I.conservativeResize(std::stable_partition(
I.data(), I.data()+I.size(), [&C](int i){return C(i);})-I.data());
Now I
is C.nonZeros()
long and contains indices of the true entries in C
. These two lines essentially implement find
.
It is reasonable to expect Eigen to have a find() function. Unfortunately, Eigen doesn't have one, or even a less than operator for matrices. Fortunately, the problem isn't too difficult. Here is one solution to the problem. I am using vector to store the Column Major indices of elements > 0. You could use VectorXf if you prefer that. Use this on B - A (B-A > 0 is the same as evaluating B>A). I'm using the stl for_each() function.
#include<algorithm>
#include<vector>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
class isGreater{
public:
vector<int>* GT;
isGreater(vector<int> *g){GT = g;}
void operator()(float i){static int it = 0; if(i>0)GT->push_back(it); it++;}
};
int main(int argc,char **argv){
MatrixXf P = MatrixXf::Random(4,5);
vector<int> GT;
for_each(P.data(),P.data()+P.rows()*P.cols(),isGreater(>));
cout<<P<<endl;
for(int i=0;i<GT.size();++i)cout<<GT[i]<<" ";
cout<<GT.size()<<endl;
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With