使用特征的指数平均

Soo*_*Soo 7 eigen eigen3

请考虑以下代码.

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').

cht*_*htz 1

最重要的是,如果保证它是一个向量,您应该声明myVec为。Eigen::VectorXf并确保您使用-O3 -march=native -DNDEBUG.

您可以尝试这些替代方案(我正在使用Av来节省打字),哪一个最快可能取决于您的问题大小和 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)