如何就地修改一维阵列的每个元素?

qua*_*ant 4 c++ arrays eigen

我有一个Eigen::Array<double,Dynamic,Dynamic>双精度的1D特征数组(),我想修改数组中的每个元素.但是,我不确定如何做到这一点.我在考虑这个:

Eigen::Array<double,Eigen::Dynamic,Eigen::Dynamic> arr1D;
// ...

// Threshold function:
arr1D.unaryExpr([](double& elem)
{
    elem = elem < 0.0 ? 0.0 : 1.0;
}
);
Run Code Online (Sandbox Code Playgroud)

但这看起来有点像黑客,因为Eigen Reference的例子只给出了例子.unaryExpr它与函数一起使用的,它返回一个值(然后整个方法只返回一个不同的数组).就我而言,我希望避免创建新阵列的需要.

我是Eigen的新手,所以我想我可能会在这里遗漏一些东西,我很感激输入.

编辑:我知道我可以简单地用上面的代替arr1D = arr1D >= 0.0,但请注意,这只是一个例子

Evg*_*yuk 7

.unaryExpr将"view"返回给定函数转换的原始数据.它不会对原始数据进行转换.

您无法更改传递给转换函数的参数.您的代码只是因为您没有触发适当代码的模板实例化而编译的.如果将结果赋值给那么它无法编译:

#include <Eigen/Dense>

int main()
{
    using namespace Eigen;

    ArrayXd x, y;
    y = x.unaryExpr([](double& elem)
    {
        elem = elem < 0.0 ? 0.0 : 1.0;
    }); // ERROR: cannot convert const double to double&
}
Run Code Online (Sandbox Code Playgroud)

错误的确切位置在Eigen内部:

EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
{
  return derived().functor()( derived().nestedExpression().coeff(index) );
  //     ^^^^^^^^^^^^^^^^^^^ - your lambda
}
Run Code Online (Sandbox Code Playgroud)

我认为最简单的就地方法Eigen是:

ArrayXd x = ArrayXd::Random(100);
x = x.unaryExpr([](double elem) // changed type of parameter
{
    return elem < 0.0 ? 0.0 : 1.0; // return instead of assignment
});
Run Code Online (Sandbox Code Playgroud)

unaryExpr 不返回全新的数组/矩阵 - 但它返回特殊的临时对象,就像它一样.