如何在 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=FALSE
或 tol = 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
这个link有我矩阵的dput输出结构。
https://pastebin.com/TsUzuF4L
Error in solve() : system is computationally singular: reciprocal condition number = 4.35295e-21 in R
我想知道在 R 中是否有任何通用方法可以确保矩阵可逆?有什么功能吗?
我添加了 tol=FALSE
或 tol = 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