这可能是一个非常愚蠢的问题,但我花了很多时间在文档上寻找它,但没有用。
在MATLAB中,find()函数为我提供了一个非零元素索引的数组。 Numpy的np.nonzero函数做了类似的事情。
如何在C ++ Eigen库中执行此操作?我有一个布尔数组
typedef <bool, 10, 1> foobar = MatrixA < MatrixB;
到目前为止。谢谢!
答案 0 :(得分:8)
不确定这是否是您问题的一部分,但要构建适当的元素不等式结果,您必须首先将矩阵转换为数组:
MatrixXd A,B;
...
Matrix<bool,Dynamic,Dynamic> C = A.array()<B.array();
现在C
与A
和B
的大小相同,而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());
现在I
长C.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(>));
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中具有非零对应元素的元素替换为一个元素。