Tom*_*ize 4 python rational-number numpy matrix
我想对有理矩阵进行操作.我用的是模块numpy
和fractions
.
这是我的代码:
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
Run Code Online (Sandbox Code Playgroud)
由于计算行列式只需要用高斯方法进行合理运算,因此有理矩阵的行列式是合理的.
所以我的问题是:为什么numpy会返回一个浮点而不是一个Fraction?我怎样才能得到理性的决定因素?
请注意,此矩阵上的其他操作可提供合理的输出(例如m.trace()
).
NumPy通过LAPACK中的较低上分解例程来计算矩阵的行列式.此例程只能处理浮点数.
在计算矩阵的行列式之前,linalg.det
检查它具有的值的类型,然后建立应该使用对名为的函数的调用运行的内部循环的类型_commonType()
.此函数将循环设置为double或complex-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)
Run Code Online (Sandbox Code Playgroud)
在对矩阵的形状进行检查并确定类型之后,该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
Run Code Online (Sandbox Code Playgroud)
这意味着Fraction
在使用时不能将类型保留为返回类型det
.
其他功能,如trace()
不进行相同的类型检查det
和对象类型可能会持续存在.trace
简单地通过调用Fraction
对象的__add__
方法来对齐对角线,因此Fraction
可以将对象保留为返回类型.
如果要将行列式计算为有理数,可以调查SymPy.此处记录了诸如计算行列式之类的矩阵运算.