所以我写了一个迭代求解稀疏超定线性系统的算法。这意味着我的代码如下所示:
construct_A_matrix();
construct_B_matrix();
while(someCondition){
x=solveSystem(A,B) //solve Ax=B. This system is overdetermined
//since A has more rows than cols.
update_A_matrix(x) //update A based on x
update_B_matrix(x) //update B based on x
iterationsCounter++
}
useX();
在solveSystem中,我使用了eigen的SimplicialLDLT和Conjugate Gradient解算器(我将它们用于调试目的,如果代码工作,我将只使用其中一个)。我用来解决系统的代码是:
for Conjugate Gradient
using SpMatrix = Eigen::SparseMatrix<double>;
Eigen::ConjugateGradient<SpMatrix, Eigen::Lower | Eigen::Upper>
solver;
SpMatrix At = A.transpose();
SpMatrix AtA = At * A;
solver.compute(AtA);
EigenMatrix newVertexPositions = solver.solve(At * B);
std::cout << "estimated error: " << solver.error() << std::endl;
double residual=(A.transpose() * (A * x) - A.transpose() * B).norm()/(A.transpose() * B).norm();
和SimplicialLDLT
using SpMatrix = Eigen::SparseMatrix<double>;
Eigen::SimplicialLDLT<SpMatrix> solver;
SpMatrix At = A.transpose();
SpMatrix AtA = At * A;
solver.compute(AtA);
if (solver.info() != Eigen::Success)
std::cout << "Decomposition failed!" << std::endl;
EigenMatrix AtB = At * B;
EigenMatrix x = solver.solve(AtB);
if (solver.info() != Eigen::Success)
std::cout << "Solving failed!" << std::endl;
//simplicialLDLT has no error() function
double residual=(A.transpose() * (A * x) - A.transpose() * B).norm() /(A.transpose() * B).norm();
经过上述循环的一些迭代后,求解器的残差/误差上升,我得到的解是错误的。
SimplicialLDLT产生的结果比Conjugate Gradient更好,但一段时间后仍然是错误的。这可以在下面以图形方式看到。正如您所看到的,SimplicialLDLT的残差增长晚于共轭梯度
。所以这是我的问题,我想弄清楚为什么会发生这种情况。我注意到,当A和B的值上升时,残差会增加.update_A_matrix和update_B_matrix逐渐增加矩阵的值A和迭代计数器一起增加。
Here你可以为每个求解器找到一个文件夹,在这个文件夹中你会找到市场格式的矩阵A,B和x,用于上述while块的最后一次迭代。还有一个信息文件,您可以在其中找到上述循环的每次迭代,A和B的最大值和最小值以及残差值。您可以使用以下代码加载A,B和X:
#include <Eigen/Sparse> //system solving and Eigen::SparseMatrix
#include <ctime> //measure time to execute
#include <unsupported/Eigen/SparseExtra> //loadMarket
using SpMatrix = Eigen::SparseMatrix<double>;
using Matrix = Eigen::MatrixXd;
int main() {
SpMatrix A, B;
Matrix X;
Eigen::loadMarket(A, "/AMatrixDirectory/A.mtx");
Eigen::loadMarket(B, "/BMatrixDirectory/B.mtx");
Eigen::loadMarket(B, "/BMatrixDirectory/X.mtx");
}
或在python中:
import scipy.io as sio
A=sio.mmread('/AMatrixDirectory/A.mtx')
B=sio.mmread('/AMatrixDirectory/B.mtx')
X=sio.mmread('/AMatrixDirectory/B.mtx')
我很想知道:
答案 0 :(得分:0)
你说你有一个稀疏的超定系统但是使用的方法甚至不适合它。当稀疏时,通常使用套索方法,即L1正则化。该地区已经做了大量的工作。当您采用正规方程时,您可以设置条件数。这是两种类型regularization.的教程。还有一种称为压缩感知的东西。