MATLAB为Eigen找到()/ Numpy非零习语

时间:2013-04-27 07:01:58

标签: c++ matlab eigen

这可能是一个非常愚蠢的问题,但我花了很多时间在文档上寻找它,但没有用。

在MATLAB中,find()函数为我提供了一个非零元素索引的数组。 Numpy的np.nonzero函数做了类似的事情。

如何在C ++ Eigen库中执行此操作?我有一个布尔数组

typedef <bool, 10, 1> foobar = MatrixA < MatrixB;
到目前为止。谢谢!

3 个答案:

答案 0 :(得分:8)

不确定这是否是您问题的一部分,但要构建适当的元素不等式结果,您必须首先将矩阵转换为数组:

MatrixXd A,B;
...
Matrix<bool,Dynamic,Dynamic> C = A.array()<B.array();

现在CAB的大小相同,而C(i,j)= A(i,j)&lt; B(I,J)。

要查找真实条目的所有索引(假设列主要顺序),您可以使用此紧凑的c ++ 11例程 - 如libigl&#39; 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());

现在IC.nonZeros(),包含C中真实条目的索引。这两行基本上实现了find

答案 1 :(得分:2)

期望Eigen具有find()函数是合理的。不幸的是,Eigen没有一个,甚至一个小于矩阵的运算符。幸运的是,问题并不太难。这是问题的一个解决方案。我使用vector来存储元素的Column Major索引&gt;如果您愿意,可以使用VectorXf。在B-A上使用它(B-A> 0与评估B> A相同)。我正在使用stl for_each()函数。

#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(&GT));
    cout<<P<<endl;
    for(int i=0;i<GT.size();++i)cout<<GT[i]<<" ";
    cout<<GT.size()<<endl;
    return 0;
}

答案 2 :(得分:1)

这可能适用于您和其他检查此问题的人。为了根据另一个矩阵A上的条件设置矩阵m的元素,可以使用以下表示法:

m = (A.array() != 0).select(1, m);

此命令将矩阵m中具有非零对应元素的元素替换为一个元素。