5

很有可能这是一个非常愚蠢的问题,但我花了相当多的时间在文档上寻找它,但无济于事。

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

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

typedef <bool, 10, 1> foobar = MatrixA < MatrixB;

至今。谢谢!

4

3 回答 3

8

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

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

现在C的大小与AandB和 C(i,j) = A(i,j) < B(i,j) 相同。

要查找真实条目的所有索引(假设列主要顺序),您可以使用这个紧凑的 c++11 例程——如 libigl 的转换表所述:

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());

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

于 2015-02-02T15:33:46.347 回答
2

期望 Eigen 有一个 find() 函数是合理的。不幸的是,Eigen 没有一个,甚至没有一个小于矩阵的运算符。幸运的是,这个问题并不太难。这是该问题的一种解决方案。我正在使用向量来存储元素 > 0 的列主索引。如果您愿意,可以使用 VectorXf。在 B - A 上使用它(BA > 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;
}
于 2013-07-01T14:54:25.560 回答
1

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

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

此命令将矩阵 m 中在 A 中具有非零对应元素的那些元素替换为 1。

于 2016-01-29T18:03:14.353 回答