本文介绍了给定分数矩阵时,为什么numpy行列式不返回分数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对有理矩阵执行运算.我使用模块numpyfractions.

I want to perform operations on rational matrices. I use the modules numpy and 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

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

Since computing the determinant only require rational operations with the Gauss' method, the determinant of a rational matrix is rational.

所以我的问题是:为什么numpy返回浮点数而不是分数?如何获得一个合理的行列式?

So my questions are: why does numpy return a float and not a Fraction? How can I get a rational determinant?

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

Note that other operations on this matrix give a rational output (for instance m.trace()).

推荐答案

NumPy通过LAPACK中较低的上层分解例程来计算矩阵的行列式.此例程只能处理浮点数.

NumPy computes the determinant of the matrix by a lower upper decomposition routine in LAPACK. This routine can only handle floating point numbers.

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

Before calculating the determinant of the matrix, linalg.det checks the types of values it has and then establishes the type of internal loop that should be run using a call to a function named _commonType(). This function will set the loop to run for either double or complex-double values.

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

Here is the Python part of the function linalg.det that handles the checking:

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实现,并返回浮点数.

After running checks on the shape of the matrix and determining types, the return line passes the values in the array to the LAPACK implementation of the lower-upper decomposition and a float is returned.

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

Trying to bypass this type checking with a type signature of our own raises an error saying that no such loop is defined for object types:

>>> 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类型保留为返回类型.

This implies than it is not possible to keep the Fraction type as the return type when using det.

其他功能,例如 不会执行与det相同的类型检查,并且对象类型可能会持续存在. trace通过调用Fraction对象的__add__方法简单地将对角线求和,因此可以将Fraction对象保留为返回类型.

Other functions such as trace() do not do the same type checking as det and the object type may persist. trace simply sums the diagonal by calling the Fraction object's __add__ method, so a Fraction object can be kept as the return type.

如果要将行列式计算为有理数,则可以调查SymPy. 此处

If you want to calculate the determinant as a rational number, you could investigate SymPy. Matrix operations such as calculating determinants are documented here.

这篇关于给定分数矩阵时,为什么numpy行列式不返回分数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 00:38