从欠定系统中删除不可解的方程

时间:2012-07-10 13:12:21

标签: c++ linear-algebra eigen

我的程序试图解决线性方程组。为了做到这一点,它组装了矩阵coeff_matrix和向量value_vector,并使用Eigen来解决它们:

Eigen::VectorXd sol_vector = coeff_matrix
        .colPivHouseholderQr().solve(value_vector);

问题在于系统可能过度和不足。在前一种情况下,Eigen提供正确或不正确的解决方案,并使用coeff_matrix * sol_vector - value_vector检查解决方案。

但是,请考虑以下方程组:

a + b - c     =  0
        c - d =  0
        c     = 11
      - c + d =  0

在这种特殊情况下,Eigen正确地解决了后三个方程,但也为ab提供了解。

我想要实现的是,只有只有一个解决方案的方程式才能得到解决,剩下的方程式(这里的第一个方程式)将保留在系统中。

换句话说,我正在寻找一种方法来找出当时在给定的方程组中可以求解哪些方程,哪种方法不能,因为将有多种方案。

你能否提出任何实现这一目标的好方法?

编辑:请注意,在大多数情况下,矩阵不是方形的。我在这里添加了一行,只是为了注意过度确定也可能发生。

3 个答案:

答案 0 :(得分:6)

我认为您想要的是singular value decomposition (SVD),它会为您提供您想要的内容。在SVD之后,“只有一个解的方程将被解决”,并且解是伪逆的。它还会给你零空间(无限解来自)和左空空间(不一致来自,即没有解决方案)。

答案 1 :(得分:2)

基于SVD评论,我能够做到这样的事情:

Eigen::FullPivLU<Eigen::MatrixXd> lu = coeff_matrix.fullPivLu();

Eigen::VectorXd sol_vector = lu.solve(value_vector);
Eigen::VectorXd null_vector = lu.kernel().rowwise().sum();

AFAICS,与单个解决方案对应的null_vector行为0 s,而与非确定解决方案对应的行为1 s。我可以在我的所有示例中使用默认阈值Eigen重现这一点。

但是,我不确定我是在做正确的事还是只是注意到随机模式。

答案 2 :(得分:1)

您需要的是计算系统的行列式。如果行列式为0,那么您将拥有无限数量的解。如果行列式非常小,则解决方案存在,但我不相信计算机找到的解决方案(这将导致数值不稳定)。

以下是决定因素及其计算方法的链接:http://en.wikipedia.org/wiki/Determinant

请注意,高斯消除也应该有效:http://en.wikipedia.org/wiki/Gaussian_elimination 使用此方法,如果存在无限数量的解,则最终会得到0行。

修改

如果矩阵不是正方形,则首先需要提取方阵。有两种情况:

  1. 你有比方程更多的变量:那么你要么没有解决方案,要么无数个。
  2. 你有更多的方程而不是变量:在这种情况下,找到一个非零行列式的方形子矩阵。解决此矩阵并检查解决方案。如果解决方案不合适,则意味着您没有解决方案。如果解适合,则意味着额外的方程线性依赖于提取方程。
  3. 在这两种情况下,在检查矩阵的维度之前,删除只有0的行和列。

    对于高斯消除,它应该直接与非平方矩阵一起工作。但是,这次,您应该检查非空行的数量(即具有一些非0值的行)是否等于变量的数量。如果不是那么你有无数的解决方案,如果还有更多,你就没有任何解决方案。