如何在 python 中使用 cramer 规则计算逆?
How to calculate inverse using cramer's rule in python?
我正在尝试使用 python 中的 numpy 包生成逆矩阵。不幸的是,我没有得到预期的答案。
原始矩阵:
([17 17 5]
[21 18 21]
[2 2 19])
通过 Cramer 规则反转原始矩阵给出:
([4 9 15]
[15 17 6]
[24 0 17])
显然使用 numpy.linalg.inv()
得到
-3.19488818e-01,3.80191693e-01,-6.38977636e-03,
3.33333333e-01, -3.33333333e-01, 2.26123699e-18,
-2.84345048e-01, 2.68370607e-01, 5.43130990e-02n
我原以为原始矩阵与逆矩阵相乘会得到一个单位矩阵,但如您所见,我给出了一个充满浮点数的矩阵。
哪里有问题?
我想你可能在手动求逆矩阵时犯了一个错误。
当我执行以下操作时
import numpy as np
a = np.array([[17, 17, 5], [21, 18, 21], [2, 2, 19]], dtype=np.float)
inv = np.linalg.inv(a)
print np.dot(inv, a)
我明白了
array([[ 1.00000000e+00, 0.00000000e+00, 1.05471187e-15],
[ 1.11022302e-16, 1.00000000e+00, -7.21644966e-16],
[ 1.38235777e-17, 5.65818009e-18, 1.00000000e+00]])
这很好,请注意所有非对角线元素的机器精度都大约为零,因此看起来 numpy 在这方面做得不错!
请记住,浮点数不像实数那样工作,除非您小心谨慎,否则您可能会在计算中出现小的舍入误差。
如果你想完全做到这一点,请查看 sympy,它将能够使用精确的数学进行计算(代价是速度稍慢)。
import sympy as sp
a = sp.Matrix([[17, 17,5],[21,18,21],[2,2,19]])
inv = a.inv()
print inv
print a * inv
产生精确的倒数
Matrix([
[-100/313, 1/3, -89/313],
[ 119/313, -1/3, 84/313],
[ -2/313, 0, 17/313]])
当与原始矩阵相乘时,给出了您所期望的精确身份
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
linalg
是对的,你是错的。
它给你的矩阵确实是逆矩阵。但是,如果您使用 np.array
而不是 np.matrix
,则乘法运算符不会按预期工作,因为它计算的是分量乘积。
在那种情况下你必须做 mat.dot(inv(mat))
。
无论如何,由于舍入误差,您将得到的不是完美的单位矩阵(当我尝试它时,非对角矩阵条目的顺序是10 ** (-16)
)。
你假设的逆显然是错误的;仅当逆矩阵中的某些条目小于 1 且仅当某些条目为负时才可实现这些值。我没有看到你做错了什么,所以我举个例子。使用 Cramer's rule 你有例如对于第一个条目 (18*19 - 2*21)/(-939) = -0.319... - 正是 numpy 发现的。
我正在尝试使用 python 中的 numpy 包生成逆矩阵。不幸的是,我没有得到预期的答案。
原始矩阵:
([17 17 5]
[21 18 21]
[2 2 19])
通过 Cramer 规则反转原始矩阵给出:
([4 9 15]
[15 17 6]
[24 0 17])
显然使用 numpy.linalg.inv()
得到
-3.19488818e-01,3.80191693e-01,-6.38977636e-03,
3.33333333e-01, -3.33333333e-01, 2.26123699e-18,
-2.84345048e-01, 2.68370607e-01, 5.43130990e-02n
我原以为原始矩阵与逆矩阵相乘会得到一个单位矩阵,但如您所见,我给出了一个充满浮点数的矩阵。
哪里有问题?
我想你可能在手动求逆矩阵时犯了一个错误。
当我执行以下操作时
import numpy as np
a = np.array([[17, 17, 5], [21, 18, 21], [2, 2, 19]], dtype=np.float)
inv = np.linalg.inv(a)
print np.dot(inv, a)
我明白了
array([[ 1.00000000e+00, 0.00000000e+00, 1.05471187e-15],
[ 1.11022302e-16, 1.00000000e+00, -7.21644966e-16],
[ 1.38235777e-17, 5.65818009e-18, 1.00000000e+00]])
这很好,请注意所有非对角线元素的机器精度都大约为零,因此看起来 numpy 在这方面做得不错!
请记住,浮点数不像实数那样工作,除非您小心谨慎,否则您可能会在计算中出现小的舍入误差。
如果你想完全做到这一点,请查看 sympy,它将能够使用精确的数学进行计算(代价是速度稍慢)。
import sympy as sp
a = sp.Matrix([[17, 17,5],[21,18,21],[2,2,19]])
inv = a.inv()
print inv
print a * inv
产生精确的倒数
Matrix([
[-100/313, 1/3, -89/313],
[ 119/313, -1/3, 84/313],
[ -2/313, 0, 17/313]])
当与原始矩阵相乘时,给出了您所期望的精确身份
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
linalg
是对的,你是错的。
它给你的矩阵确实是逆矩阵。但是,如果您使用 np.array
而不是 np.matrix
,则乘法运算符不会按预期工作,因为它计算的是分量乘积。
在那种情况下你必须做 mat.dot(inv(mat))
。
无论如何,由于舍入误差,您将得到的不是完美的单位矩阵(当我尝试它时,非对角矩阵条目的顺序是10 ** (-16)
)。
你假设的逆显然是错误的;仅当逆矩阵中的某些条目小于 1 且仅当某些条目为负时才可实现这些值。我没有看到你做错了什么,所以我举个例子。使用 Cramer's rule 你有例如对于第一个条目 (18*19 - 2*21)/(-939) = -0.319... - 正是 numpy 发现的。