Python 带分数的线性系统数值解法

Python 带分数的线性系统数值解法,python,numpy,linear-algebra,fractions,Python,Numpy,Linear Algebra,Fractions,我有一个矩阵A和一个右手边向量y,用分数表示。分数对象: import random, fractions, numpy as np A = np.zeros((3, 3), dtype=fractions.Fraction) y = np.zeros((3, 1), dtype=fractions.Fraction) for i in range(3): for j in range(3): A[i, j] = fractions.Fraction(np.random

我有一个矩阵
A
和一个右手边向量
y
,用
分数表示。分数
对象:

import random, fractions, numpy as np

A = np.zeros((3, 3), dtype=fractions.Fraction)
y = np.zeros((3, 1), dtype=fractions.Fraction)
for i in range(3):
    for j in range(3):
        A[i, j] = fractions.Fraction(np.random.randint(0, 4), np.random.randint(1, 6))
    y[i] = fractions.Fraction(np.random.randint(0, 4), np.random.randint(1, 6))
我想使用
numpy
中提供的函数来求解系统
A*x=y
,并得到以分数对象表示的结果,但不幸的是,basic
x=np.linalg.solve(A,y)
以标准浮点值返回结果:

>>> np.linalg.solve(A, y)

array([[-1.5245283 ],
       [ 2.36603774],
       [ 0.56352201]])
有没有一种方法可以得到分数对象的精确结果


编辑

我想做的只是numpy的内置功能不可行(从版本1.10开始-见疯狂物理学家的答案)。我们可以做的是实现他/她自己的基于高斯消去法的线性解算器,它依赖于和、减、乘和除,所有这些都是定义良好的,并且完全使用分数对象执行(只要分子和分母适合数据类型,我认为数据类型任意长)


如果你真的对此感兴趣,只需自己实现一个解算器,这将是简单而快速的(遵循在线教程之一)。我不太感兴趣,所以我将坚持使用浮点结果。

根据python邮件列表上的说明,似乎不可能使用纯numpy反转有理数矩阵。建议您可以将Symphy用于大小不超过4x4的有理数矩阵。如果你因为某种原因与NUMPY联系在一起,你可以考虑使用和使用一个3x3矩阵的逆矩阵“手动”。关于如何实现这一点的分步教程可以在上找到,也可以在上找到大量其他关于矩阵求逆的教程。

IMHO,没有希望了。在许多情况下都有效的解决方案:

y = np.zeros(3, dtype=fractions.Fraction)
....
X= np.linalg.solve(A,y)
s=[fractions.Fraction.from_float(x).limit_denominator(6**9) for x in X]
print(s,y==dot(A,s))

它利用解几乎是一个小分子和小分母的分数的性质,找到它

你的矩阵总是3x3还是只是偶然的?如果它总是3x3,在最坏的情况下,你可以手工编码矩阵逆。实际上,当我试图运行行
np.linalg.solve(A,y)
时,我得到了一个错误。你是怎么做到的?Numpy给出以下错误:
TypeError:找不到与ufunc solve的指定签名和强制转换匹配的循环。我在scipy中尝试了类似的代码,它给出了
ValueError:不支持对象数组
。矩阵很小,但大小是可变的。表示不大于10x10。我也知道它是非单数形式的。我使用的是python 3.4.3和numpy 1.9.2,上面的代码运行得很好。我在这两个版本上都尝试了python 3.5.0、python 2.7.10和numpy 1.10.1和scipy 0.16.1。每次都是同样的错误。也许是升级破坏了演员阵容?实际上,从系统的大小和实际分母,你可以分析找到结果的最大分母,并使用它来代替6**9。但我认为最好的方法仍然是实现LU分解,如果您需要的话,您可以自己进行前向替换。但是,是的,在阅读了《疯狂物理学家》发布的参考资料后,我同意用numpy内置的解算器做任何事情都没有希望。它并不优雅,但对我来说效果很好,谢谢