我想使用SolveWithGuess()函数从一个很好的近似值开始求解线性方程组。但是,当我尝试以与真实解相比具有较小扰动(1.e-9*i; 0 <= i <= 20
)的初始猜测进行测试时,在共轭梯度迭代过程中收到以下错误值:
0 1.922e-09
1 3.694e-09
2 7.101e-09
3 1.365e-08
4 2.623e-08
5 5.043e-08
6 9.692e-08
7 1.863e-07
8 3.581e-07
9 6.882e-07
10 1.323e-06
请问可能是什么问题?我的测试代码如下:
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <Eigen/Eigen>
using namespace Eigen;
using namespace std;
void solve()
{
int n = 20;
typedef SparseMatrix<double, ColMajor> SM;
typedef Matrix<double, -1, 1> DV;
SM a(n,n);
DV b(n), x(n);
for (int i = 0; i < n; i++)
{
b[i] = double(i);
for (int j = 0; j < n; j++) a.insert(i, j) = 0.0;
a.coeffRef(i, n - i - 1) = 1.0;
}
for (int i = 0; i < n; i++) x[i] = double(n - i - 1) + 1.e-9 * double(i);
ConjugateGradient<SM> cg;
cg.setMaxIterations(1);
cg.compute(a);
for (int it = 0; it < 100; it++)
{
cg.compute(a);
x = cg.solveWithGuess(b,x);
cout << it << " " << scientific << setw(10) << setprecision(3) << cg.error() << endl;
}
}
答案 0 :(得分:0)
实际上存在两个问题:您的矩阵不是正定的,即,您最好使用任何其他迭代求解器。但更重要的是,如果将最大迭代次数设置为1并迭代调用solveWithGuess
,则实际上您会执行类似梯度下降的操作(即,它不保持先前的搜索方向),而这对您的行为恰恰是可怕的矩阵。
如果您实际上对迭代求解器内部发生的事情感兴趣,则需要将调试代码插入相应的_solve_impl
方法中(或相应地重新实现求解器)