代码之家  ›  专栏  ›  技术社区  ›  Soo

指数平均法

  •  6
  • Soo  · 技术社区  · 6 年前

    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());
    

    它基本上实现了指数平均。 我知道最后一行可以通过以下方式进行优化。

    symmetricMatrix_copy.selfadjointView<Eigen::Upper>().rankUpdate(myVec, 1-alpha);
    

    我想知道我是否能把最后两行有效地结合起来。 简而言之,我想计算 A = alpha*A+(1-alpha)*(x*x') .

    1 回复  |  直到 6 年前
        1
  •  1
  •   chtz    6 年前

    最重要的是,你应该申报 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.
    

    不幸的是, .noalias() .triangularView()

    您还可以考虑计算:

    A.selfadjointView<Eigen::Upper>().rankUpdate(v, (1.0f-alpha)/alpha);
    

    N A 矩阵依据 pow(alpha, N)