我已经实现了Gauss-Newton优化过程,该过程包括通过求解线性化系统Hx = b
来计算增量。 H
matrx由H = J.transpose() * W * J
计算,b
由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秒)并且我不明白它是否是我的编码问题或通常需要这么久。
这里的一切都是特征矩阵和向量。
我在逆特征向量中使用特征库中的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
}
它位于类中的函数中,现在用于调试目的的权重矩阵被定义为可由函数访问的类变量,并在调用函数之前定义。
答案 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
是一个对角矩阵,计算将按预期进行优化。