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

时间:2017-05-19 19:07:45

标签: c++ parallel-processing eigen

我有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);           
}

1 个答案:

答案 0 :(得分:0)

  

我想对矩阵的每一列应用函数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 << "Before\n";
    std::cout << myMatrix << "\n";

    auto myMatrixColwise = myMatrix.colwise();

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

    std::cout << "After\n";
    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);
相关问题