c++ - 加权外积的向量化

标签 c++ vectorization eigen

我希望加快近似加权协方差的计算。

具体来说,我有一个 Eigen::VectorXd(N) w 和一个 Eigen::MatrixXd(M,N) 点。我想计算 w(i)*points.col(i)*(points.col(i).transpose()) 的总和。

我正在使用 for 循环,但想看看我是否可以走得更快:

Eigen::VectorXd w = Eigen::VectorXd(N) ;
Eigen::MatrixXd points = Eigen::MatrixXd(M,N) ;
Eigen::MatrixXd tempMatrix = Eigen::MatrixXd(M,M) ;
for (int i=0; i < N ; i++){
    tempMatrix += w(i)*points.col(i)*(points.col(i).transpose());
}

期待看到可以做什么!

最佳答案

以下应该有效:

Eigen::MatrixXd tempMatrix; // not necessary to pre-allocate
// assigning the product allocates tempMatrix if needed
// noalias() tells Eigen that no factor on the right aliases with tempMatrix
tempMatrix.noalias() = points * w.asDiagonal() * points.adjoint();

或直接:

Eigen::MatrixXd tempMatrix = points * w.asDiagonal() * points.adjoint();

如果 M 真的很大,只计算一侧并复制它(如果需要)会明显更快:

Eigen::MatrixXd tempMatrix(M,M);
tempMatrix.triangularView<Eigen::Upper>() = points * w.asDiagonal() * points.adjoint();
tempMatrix.triangularView<Eigen::StrictlyLower>() = tempMatrix.adjoint();

请注意,对于非复标量,.adjoint() 等同于 .transpose(),但对于前者,如果 指向MatrixXcd 代替的结果(w 必须仍然是实数,如果结果必须是自伴随的)。

另外,请注意以下(来自您的原始代码)不会将所有条目设置为零:

Eigen::MatrixXd tempMatrix = Eigen::MatrixXd(M,M);

如果你想要这个,你需要写:

Eigen::MatrixXd tempMatrix = Eigen::MatrixXd::Zero(M,M);

关于c++ - 加权外积的向量化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58141704/

相关文章:

c++ - 在 vector 图上使用 initializer_list

matlab - 比较两个不等长的向量得到一个逻辑数组

C++:int x[+30] 是有效的声明吗?

c++ - 无法从 '_int64' 转换为 'Data *'

c++ - 我需要帮助创建一个评分系统,但它总是给我一个错误,注释掉的整数是给我带来麻烦的部分

python - 使用 CountVectorizer 对不带空格的 unicode 句子进行正则表达式

python - 有没有办法创建一个pandas数据帧,其行是整数,这些整数会增加直到每行达到某个值?

c++ - 在 Eigen 中将矩阵的一行设置为 0

c++ - C++最佳实践中的矩阵创建破坏?

c++ - 如何在 C++ 中将特征张量乘以另一个特征张量的标量和?