本征矩阵乘法非常慢

Cat*_*IAS 5 c++ optimization matrix eigen

我已经实现了高斯-牛顿优化过程,该过程涉及通过求解线性化系统来计算增量Hx = b。该HMATRX由下式计算H = J.transpose() * W * Jb由下式计算b = J.transpose() * (W * e),其中e是误差矢量。雅可比行列式是一个n×6矩阵,其中n以千为单位,并且在迭代过程中保持不变,并且W是一个n×n对角线权重矩阵,该矩阵将在迭代过程中发生变化(某些对角线元素将设置为零)。但是我遇到了速度问题。

当我不添加权重矩阵W,即H = J.transpose()*J和时b = J.transpose()*e,我的高斯-牛顿过程可以在0.02秒内非常快地运行30次迭代。但是,当我添加在W迭代循环之外定义的矩阵时,它变得如此之慢(30次迭代需要0.3〜0.7秒),并且我不知道这是我的编码问题还是通常花费了这么长时间。

这里的所有内容都是本征矩阵和向量。

我根据反方差向量在Eigen库中W使用.asDiagonal()函数定义了矩阵。然后将其用于Had 的计算中b。然后它变得非常缓慢。我希望得到一些有关这种巨大放缓的潜在原因的提示。

编辑:

只有两个矩阵。雅各布派肯定是密集的。权重矩阵是通过来自vec.asDiagonal()密集库的函数从矢量生成的,因此我认为它也是密集的。

代码非常简单,导致时间变化的唯一区别是权重矩阵的增加。这是一个代码片段:

for (int iter=0; iter<max_iter; ++iter) {
    // obtain error vector
    error = ...  
    // calculate H and b - the fast one
    Eigen::MatrixXf H = J.transpose() * J;
    Eigen::VectorXf b = J.transpose() * error;
    // calculate H and b - the slow one
    Eigen::MatrixXf H = J.transpose() * weight_ * J;
    Eigen::VectorXf b = J.transpose() * (weight_ * error);
    // obtain delta and update state
    del = H.ldlt().solve(b);
    T <- T(del)   // this is pseudo code, meaning update T with del
}
Run Code Online (Sandbox Code Playgroud)

它在类的函数中,并且出于调试目的,权重矩阵现在定义为可以由函数访问的类变量,并且在调用函数之前已定义。

Avi*_*urg 0

因为矩阵乘法只是对角线乘法,所以您可以将其更改为使用系数乘法,如下所示:

MatrixXd m;
VectorXd w;
w.setLinSpaced(5, 2, 6);

m.setOnes(5,5);

std::cout << (m.array().rowwise() * w.array().transpose()).matrix() << "\n";
Run Code Online (Sandbox Code Playgroud)

同样,矩阵向量积可以写为:

(w.array() * error.array()).matrix()
Run Code Online (Sandbox Code Playgroud)

这避免了矩阵中的零元素。没有 MCVE 供我以此为基础,YMMV...