Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何就地修改一维数组的每个元素?_C++_Arrays_Eigen - Fatal编程技术网

C++ 如何就地修改一维数组的每个元素?

C++ 如何就地修改一维数组的每个元素?,c++,arrays,eigen,C++,Arrays,Eigen,我有一个双精度的一维特征数组(eigend::array),我想修改数组中的每个元素。然而,我真的不知道如何做到这一点。我正在考虑: Eigen::Array<double,Eigen::Dynamic,Eigen::Dynamic> arr1D; // ... // Threshold function: arr1D.unaryExpr([](double& elem) { elem = elem < 0.0 ? 0.0 : 1.0; } ); Eigen

我有一个双精度的一维特征数组(
eigend::array
),我想修改数组中的每个元素。然而,我真的不知道如何做到这一点。我正在考虑:

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

// Threshold function:
arr1D.unaryExpr([](double& elem)
{
    elem = elem < 0.0 ? 0.0 : 1.0;
}
);
Eigen::数组arr1D;
// ...
//阈值函数:
arr1D.unaryExpr([](双行和元素)
{
elem=elem<0.0?0.0:1.0;
}
);
但这看起来有点像黑客,因为示例只给出了
.unaryExpr
的示例,其中它与返回值的函子一起使用(然后整个方法只返回一个不同的数组)。在我的例子中,我希望避免创建新阵列的需要

我是新来的伊根,所以我想我可能错过了一些东西这里,输入是感激的


编辑:我知道我可以用
arr1D=arr1D>=0.0
简单地替换上面的内容,但请注意,这只是一个示例。
.unaryExpr
返回通过给定函数转换的原始数据的“视图”。它不进行原始数据的转换

不能更改传递给转换函数的参数。您的代码之所以被编译,只是因为您没有触发相应代码的模板实例化。如果将结果赋值,则无法编译:

#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&
}

我认为使用
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
});
ArrayXd x=ArrayXd::Random(100);
x=x.unaryExpr([](双元素)//更改了参数的类型
{
return elem<0.0?0.0:1.0;//返回而不是赋值
});

unaryExpr
不会返回完整的新数组/矩阵,但它会返回与之类似的特殊临时对象。

如果值类型相对简单,Evgeny的答案是最好的

但是,如果您想重新创建
real()
complex()
(访问
Scalar
s结构的部分),可以使用
const\u cast
将其全部破解,这就是
real/complex()
实际要做的(从v3.3开始): (注意:此代码仅在C++1y中测试,但可以简化。)


unaryExpr
是一个
const
函数,因此它不允许您在适当的位置修改值(即提供非const引用)。你试过你的代码了吗?我猜它不会编译。@它编译得很好,但似乎没有修改数组,有点奇怪。在这种情况下,实现似乎使用标量值的本地副本将其传递给函子。奇怪的是,它接受一个返回void的函数…可能。。。甚至有可能Eigen检测到“自赋值”,比如
arr1D=arr1D.unaryExpr(…)
(从技术上讲,自赋值的含义有所不同,但我想你知道我的意思)。我听说Eigen非常聪明,能够在幕后实现低级优化。(尽管我从未使用过。)您可以通过调试在lambda中打印整个数组(由ref捕获)来证明这一点。如果您看到连续的修改,它证明了Eigen选择在适当的位置评估操作。如果您看到原始内容N次,则情况正好相反,即在赋值之前,Eigen选择求值。我不确定这些优化是否适用于矩阵和数组,但它们适用于矩阵()。这很有帮助。我认为这就像是std::for_,但事实并非如此。
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
});
struct Value {
  double a{1.5};
  int b{2};
};

// Savage. Use aforemention hack from scalar_real_ref_op.
struct get_mutable_a_direct {
  double& operator()(const Value& v) const {
    return const_cast<Value&>(v).a;
  }
};
// ...
MatrixX<Value> X(2, 2);
auto X_am_direct = CwiseUnaryView<get_mutable_a_direct, MatrixX<Value>>(
    X, get_mutable_a_direct());
X_am_direct.setConstant(20);
struct get_a_flex {
  double& operator()(Value& v) const {
    return v.a;
  }
  const double& operator()(const Value& v) const {
    return v.a;
  }
};
// Less? savage.
auto X_am = unaryExprFlex(X, get_a_flex());
X_am *= 10;
cout << X_ac << endl;

// Works.
const auto& Xc = X;
auto Xc_am = unaryExprFlex(Xc, get_a_flex());
// Xc_am.setConstant(20);  // Fails as desired.
cout << Xc_am << endl;
auto X_bm = unaryExprFlex(X, [](Value& v) -> auto& { return v.b; });
cout << X_bm << endl;
X_bm.setConstant(10);
cout << X_bm << endl;