如何在 R 中确保矩阵可逆

how to make a matrix invertible for sure, in R

这个link有我矩阵的dput输出结构。
https://pastebin.com/TsUzuF4L

Error in solve() : system is computationally singular: reciprocal condition number = 4.35295e-21 in R

我想知道在 R 中是否有任何通用方法可以确保矩阵可逆?有什么功能吗?

我添加了 tol=FALSEtol = 1e-22 属性(与错误的数字相比),但我仍然得到同样的错误。

ps。我把它带到 stackexchange 上的原因是,我的矩阵行列式不为零,但 R 给出了上面的错误并相信我的矩阵不可逆!怎么会?!

我的矩阵是 45 × 45。dput() 输出超出了我在 Stack Overflow 上的 40000 个字符的限制,但为了了解它的数字是多少,我在上面展示了它的一部分。

tl;dr 我可以通过设置 tol=0 来反转你的矩阵,但这可能不是一个好主意。

当我从 link you provided 得到你的矩阵时,我能够解决问题并反转矩阵,但我建议你应该 非常 谨慎,因为警告和错误告诉您计算在数值上不稳定 - 您可能会在不同的操作系统、不同的编译器等上得到不同的答案。除非你有验证它们的独立方法.

range(v <- eigen(M)$values)
## [1] -7.369628e-05  9.355280e+11
plot(abs(v), log="y", col = sign(v)+3, pch=16)

矩阵不是正定的(这可能很重要,具体取决于您的应用);最小的特征值比最大的小 16 个数量级...

Matrix::rankMatrix(M)
## 19, with tolerance 1e-15
Matrix::rankMatrix(M, tol =0 )
## 45 with tolerance 0

当使用默认公差计算时,您的矩阵被报告为秩亏,即只有 19 个独立 dimensions/columns(这对应于上图中大间隙上方的特征值)

我们可以计算条件数:

Matrix::condest(M)
## $est: [1] 2.732966e+18

来自 Wikipedia:

As a rule of thumb, if the condition number κ(A) = 10^k, then you may lose up to k digits of accuracy on top of what would be lost to the numerical method due to loss of precision from arithmetic methods

在这种情况下k=18(得出自己的结论)...

当我计算行列式时,我得到一个非常不同的值(但仍然非零)。

det(M)
## [1] 2.568633e+35

如果我告诉 R 通过将公差设置为 0 忽略所有这些警告标志,我可以反转矩阵。

i <- solve(M, tol=0)

根据您在做什么,您可能有兴趣计算 pseudo-inverse 考虑到矩阵的(接近)秩亏,例如使用 MASS::ginv().

由于答案很可能高度依赖于系统细节,这里是来自 sessionInfo() 的信息:

R Under development (unstable) (2021-07-30 r80684)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Pop!_OS 20.10

Matrix products: default
BLAS:   /usr/local/lib/R/lib/libRblas.so
LAPACK: /usr/local/lib/R/lib/libRlapack.so