请考虑以下代码.
const int N = 100;
const float alpha = 0.9;
Eigen::MatrixXf myVec = Eigen::MatrixXf::Random(N,1);
Eigen::MatrixXf symmetricMatrix(N, N);
for(int i=0; i<N; i++)
for(int j=0; j<=i; j++)
symmetricMatrix(i,j) = symmetricMatrix(j,i) = i+j;
symmetricMatrix *= alpha;
symmetricMatrix += ((1-alpha)*myVec*myVec.adjoint());
Run Code Online (Sandbox Code Playgroud)
它基本上实现了指数平均.我知道最后一行可以通过以下方式进行优化.
symmetricMatrix_copy.selfadjointView<Eigen::Upper>().rankUpdate(myVec, 1-alpha);
Run Code Online (Sandbox Code Playgroud)
我想知道我是否能以有效的方式结合最后两行.总之,我想计算 A = alpha*A+(1-alpha)*(x*x').
最重要的是,如果保证它是一个向量,您应该声明myVec为。Eigen::VectorXf并确保您使用-O3 -march=native -DNDEBUG.
您可以尝试这些替代方案(我正在使用A和v来节省打字),哪一个最快可能取决于您的问题大小和 CPU:
A.noalias() = alpha * A + (1.0f-alpha)*v*v.adjoint();
A.noalias() = alpha * A + (1.0f-alpha)*v.lazyProduct(v.adjoint());
A.noalias() = alpha * A + ((1.0f-alpha)*v).lazyProduct(v.adjoint());
A.noalias() = alpha * A + v.lazyProduct((1.0f-alpha)*v.adjoint());
A.triangularView<Eigen::Upper>() = alpha * A + (1.0f-alpha)*v*v.adjoint();
// or any `lazyProduct` as above.
Run Code Online (Sandbox Code Playgroud)
不幸的是,目前无法合并.noalias()。.triangularView()
您还可以考虑计算:
A.selfadjointView<Eigen::Upper>().rankUpdate(v, (1.0f-alpha)/alpha);
Run Code Online (Sandbox Code Playgroud)
每次N迭代都会缩放你的A矩阵pow(alpha, N)
| 归档时间: |
|
| 查看次数: |
99 次 |
| 最近记录: |