python - 为什么在给定分数矩阵时 numpy 行列式不返回分数?

标签 python numpy matrix rational-number

我想对有理矩阵进行运算。我使用模块 numpyfractions

这是我的代码:

import numpy as np
from fractions import Fraction

m=np.matrix([[Fraction(1, 6), Fraction(8, 7)], [Fraction(1, 2), Fraction(3, 2)]])
print(np.linalg.det(m))
# Gives -0.321428571429

print(m[0,0]*m[1,1] - m[0,1]*m[1,0])
# Gives -9/28

由于计算行列式只需要用高斯方法进行有理运算,因此有理矩阵的行列式是有理的。

所以我的问题是:为什么 numpy 返回一个 float 而不是分数?我怎样才能得到有理行列式?

请注意,此矩阵上的其他操作会给出合理的输出(例如 m.trace())。

最佳答案

NumPy 通过 LAPACK 中的下上分解例程计算矩阵的行列式。此例程只能处理 float 。

在计算矩阵的行列式之前,linalg.det 检查其值的类型,然后通过调用名为 的函数建立应该运行的内部循环类型_commonType()。此函数会将循环设置为针对 double 值或复 double 值运行。

这是函数 linalg.det 的 Python 部分处理检查:

def det(a):
    a = asarray(a) # convert matrix to NumPy array
    _assertNoEmpty2d(a)
    _assertRankAtLeast2(a)
    _assertNdSquareness(a)
    t, result_t = _commonType(a) # input/output types established here
    signature = 'D->D' if isComplexType(t) else 'd->d' # signature 'float->float' chosen 
    return _umath_linalg.det(a, signature=signature).astype(result_t) 

在检查矩阵的形状并确定类型后,return 行将数组中的值传递给下-上分解的 LAPACK 实现,并返回一个 float 。

尝试使用我们自己的类型签名来绕过这种类型检查会引发一个错误,指出没有为对象类型定义这样的循环:

>>> np.linalg._umath_linalg.det(a, signature='O->O') # 'O' is 'object'
TypeError: No loop matching the specified signature was found for ufunc det

这意味着在使用 det 时不可能将 Fraction 类型保留为返回类型。

其他功能如trace()不要执行与 det 相同的类型检查,对象类型可能会持续存在。 trace 只是通过调用 Fraction 对象的 __add__ 方法对对角线求和,所以 Fraction 对象可以保留为返回类型。

如果您想将行列式计算为有理数,可以研究 SymPy。记录了计算行列式等矩阵运算 here .

关于python - 为什么在给定分数矩阵时 numpy 行列式不返回分数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29182051/

相关文章:

python - BeautifulSoup 和 urllib 从网站查找数据

python - 谷歌 Oauth2-redirect_uri_mismatch 400

python - 多处理 IOError : bad message length

python - numpy.einsum 大大加快了计算速度 - 但 numpy.einsum_path 没有显示加速,我错过了什么?

python - 如何删除列表中的项目及其信息?

python - 在我的 celery 应用程序中使用 django ORM 出现错误

Python:分析 CSV 文件 100,000 行 x 40 列

Python - 读取矩阵中的第n行

C 指针矩阵函数中的指针问题

java - 确定矩阵是否是魔法矩阵