【发布时间】:2015-02-14 03:20:36
【问题描述】:
numpy 有一种反转矩阵的方法。但是我有一个包含大量整数条目的矩阵,并且该矩阵是单模的,因此逆矩阵也是一个整数矩阵。错误太大,无法使用 numpy 用 float 计算它,然后对值进行四舍五入。有没有办法用整数或任何其他库精确计算条目?
【问题讨论】:
numpy 有一种反转矩阵的方法。但是我有一个包含大量整数条目的矩阵,并且该矩阵是单模的,因此逆矩阵也是一个整数矩阵。错误太大,无法使用 numpy 用 float 计算它,然后对值进行四舍五入。有没有办法用整数或任何其他库精确计算条目?
【问题讨论】:
您可以使用sympy。
例如,这是一个 numpy 整数数组:
In [148]: m = np.array([[10, 11, 0, 0], [9, 10, 0, 0], [100, 0, 20, 3], [-10000, 200, 133, 20]])
In [149]: m
Out[149]:
array([[ 10, 11, 0, 0],
[ 9, 10, 0, 0],
[ 100, 0, 20, 3],
[-10000, 200, 133, 20]])
确切的行列式是 1,但 np.linalg.det() 和 np.linalg.inv() 都会引入浮点错误:
In [150]: np.linalg.det(m)
Out[150]: 0.99999999999887024
In [151]: np.linalg.inv(m)
Out[151]:
array([[ 1.00000000e+01, -1.10000000e+01, -6.69432763e-16,
8.92627614e-17],
[ -9.00000000e+00, 1.00000000e+01, 6.34413157e-16,
-8.43354404e-17],
[ -3.25400000e+05, 3.58000000e+05, 2.00000000e+01,
-3.00000000e+00],
[ 2.16900000e+06, -2.38630000e+06, -1.33000000e+02,
2.00000000e+01]])
从 numpy 数组创建一个 sympy Matrix 对象:
In [156]: import sympy
In [157]: M = sympy.Matrix(m)
In [158]: M
Out[158]:
Matrix([
[ 10, 11, 0, 0],
[ 9, 10, 0, 0],
[ 100, 0, 20, 3],
[-10000, 200, 133, 20]])
同情计算是准确的:
In [159]: M.det()
Out[159]: 1
In [160]: M.inv()
Out[160]:
Matrix([
[ 10, -11, 0, 0],
[ -9, 10, 0, 0],
[-325400, 358000, 20, -3],
[2169000, -2386300, -133, 20]])
要将逆转换回 numpy 数组,您可以这样做:
In [185]: Minv = M.inv()
In [186]: minv = np.asarray(Minv).astype(int)
In [187]: minv
Out[187]:
array([[ 10, -11, 0, 0],
[ -9, 10, 0, 0],
[ -325400, 358000, 20, -3],
[ 2169000, -2386300, -133, 20]])
必须使用 astype(int) 方法,因为 numpy 数组的 dtype object 没有它:
In [188]: np.asarray(Minv)
Out[188]:
array([[10, -11, 0, 0],
[-9, 10, 0, 0],
[-325400, 358000, 20, -3],
[2169000, -2386300, -133, 20]], dtype=object)
结果是一个 sympy 整数的 numpy 数组。
在转换回 numpy 时要小心:逆向中的整数可能比 64 位整数所能表示的要大。
【讨论】: