Eigen

时间:2017-07-06 01:13:20

标签: c++ matrix optimization eigen

我已经实现了Gauss-Newton优化过程,该过程包括通过求解线性化系统Hx = b来计算增量。 H matrx由H = J.transpose() * W * J计算,bb = J.transpose() * (W * e)计算,其中e是误差向量。这里的雅可比矩阵是一个n乘6的矩阵,其中n是千,并且在迭代中保持不变,W是一个n乘n的对角线权重矩阵,它将在迭代中改变(一些对角线元素将设置为零) )。但是我遇到了速度问题。

当我没有添加权重矩阵W,即H = J.transpose()*Jb = J.transpose()*e时,我的高斯 - 牛顿过程可以在0.02秒内非常快地运行30次迭代。然而,当我添加在迭代循环外定义的W矩阵时,它变得如此慢(30次迭代时为0.3~0.7秒)并且我不明白它是否是我的编码问题或通常需要这么久。

这里的一切都是特征矩阵和向量。

我在逆特征向量中使用特征库中的W函数定义了我的.asDiagonal()矩阵。然后在H广告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
}

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

2 个答案:

答案 0 :(得分:0)

因为矩阵乘法只是对角线,你可以改变它以使用系数乘法,如下所示:

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

m.setOnes(5,5);

std::cout << (m.array().rowwise() * w.array().transpose()).matrix() << "\n";

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

(w.array() * error.array()).matrix()

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

答案 1 :(得分:0)

我想weight_被声明为密集MatrixXf?如果是,请在w.asDiagonal()处使用weight_替换它,或者将后者作为asDiagonal表达式的别名:

auto weight = w.asDiagonal();

这样,Eigen将知道weight是一个对角矩阵,计算将按预期进行优化。