4

我的程序试图求解一个线性方程组。为了做到这一点,它组装了 matrixcoeff_matrix和 vector 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 正确地求解了后面的三个方程,但也给出了a和的解b

我想要实现的是,只有只有一个解的方程才能被求解,其余的方程(这里的第一个方程)将保留在系统中。

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

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

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

4

3 回答 3

6

我认为您想要的是奇异值分解 (SVD),它将为您提供您想要的确切信息。SVD之后,“只有一个解的方程将被解”,解是伪逆的。它还将为您提供零空间(无限解的来源)和左零空间(不一致的来源,即无解)。

于 2012-07-10T15:36:00.787 回答
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对应于单个解的行是0s 而对应于非确定解的行是1s。我可以使用 Eigen 的默认阈值在所有示例中重现这一点。

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

于 2012-07-10T17:49:12.097 回答
1

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

这里是什么是行列式以及如何计算它的链接:http ://en.wikipedia.org/wiki/Determinant

请注意,高斯消除也应该起作用:http ://en.wikipedia.org/wiki/Gaussian_elimination 使用这种方法,如果有无限数量的解决方案,您最终会得到 0 行。

编辑

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

  1. 你有比方程更多的变量:那么你要么没有解,要么有无数个解。
  2. 你有比变量更多的方程:在这种情况下,找到一个非空行列式的平方子矩阵。求解该矩阵并检查解。如果解决方案不适合,则意味着您没有解决方案。如果解决方案合适,则意味着额外的方程线性依赖于提取的方程。

在这两种情况下,在检查矩阵的维度之前,删除只有 0 的行和列。

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

于 2012-07-10T14:24:20.197 回答