如何将函数逐列应用于特征矩阵?

How to apply a function column-wise to an Eigen Matrix?

本文关键字:特征 应用于 函数      更新时间:2023-10-16

我有一个Eigen::MatrixXd(n,m).我想将F(one_column)函数应用于矩阵的每一列。如何在不使用循环的情况下做到这一点?

我目前的实现:

for (int i = 0; i < m 1; i++)  // How to Parallel this process?
{       
Eigen::VectorXd one_column = SigmaPoints.col(i);
F(one_column);           
}

我想将函数 F(one_column) 应用于矩阵的每一列。如何在不使用循环的情况下做到这一点?

您可以使用 c++ 算法函数 + lambda。例如,如果您想要的只是调用一个将每列作为参数传递的函数,那么您可以使用......std::for_each

const auto myMatrixColwise = myMatrix.colwise();
std::for_each(myMatrixColwise.begin(), myMatrixColwise.end(), [](const auto &column){
F(column);
});

我的函数 F 对该列中的每个元素执行更新

在这种情况下,您应该改用 std::transform:

auto myMatrixColwise = myMatrix.colwise();
std::transform(myMatrixColwise.begin(), myMatrixColwise.end(), myMatrixColwise.begin(), [](const auto &column){
return F(column);
});

更具体地说:

#include <iostream>
#include <algorithm>
#include <Eigen/Core>
Eigen::Vector3d F(const Eigen::Vector3d &column)
{
Eigen::Vector3d abc;
abc << 1.0, 2.0, 3.0;
return column + abc;
}
int main()
{
Eigen::Matrix<double, 3, 4> myMatrix;
myMatrix << 1.0, 10.0, 100.0, 1000.0,
2.0, 20.0, 200.0, 2000.0,
3.0, 30.0, 300.0, 3000.0;
std::cout << "Beforen";
std::cout << myMatrix << "n";
auto myMatrixColwise = myMatrix.colwise();
std::transform(myMatrixColwise.begin(), myMatrixColwise.end(), myMatrixColwise.begin(), [](const auto &column) {
return F(column);
});
std::cout << "Aftern";
std::cout << myMatrix << "n";
return 0;
}

此代码应打印:

Before
1   10  100 1000
2   20  200 2000
3   30  300 3000
After
2   11  101 1001
4   22  202 2002
6   33  303 3003

如何并行此过程?

最简单的方法是使用 C++17 并行算法替代方案:

#include <execution>
auto myMatrixColwise = myMatrix.colwise();
std::transform(std::execution::par_unseq, myMatrixColwise.begin(), myMatrixColwise.end(), myMatrixColwise.begin(), [](const auto &column){
return F(column);
});

免责声明:它不适用于所有 c++17"兼容"编译器。

我有列 1 c1 = (x1, y1, z1)。我的 F 会将 c1 更新为 c1_new = (x1 + a, y1 + b, z1 + c)

在最后一种情况下,正如@chtz所说,您可以执行以下简单操作:

SigmaPoints.colwise() += Eigen::Vector3d(a, b, c);