Python Sympy-将表达式中的所有数值合理化?(如Mathematica的合理化[])

Python Sympy-将表达式中的所有数值合理化?(如Mathematica的合理化[]),python,fractions,sympy,Python,Fractions,Sympy,是否有一种简单的方法(尝试)使给定增量内表达式中的所有数值合理化,就像Mathematica中的rationalize[] Mathematica中的一个例子: In[25]:= Rationalize[0.5 x^2 - 3.333333 x, 10^-4] Out[25]= x^2/2-(10 x)/3 >>> Fraction.from_float(3.33333333) Fraction(7505999371444827, 2251799813685248) 我看到

是否有一种简单的方法(尝试)使给定增量内表达式中的所有数值合理化,就像Mathematica中的
rationalize[]

Mathematica中的一个例子:

In[25]:= Rationalize[0.5 x^2 - 3.333333 x, 10^-4]
Out[25]= x^2/2-(10 x)/3
>>> Fraction.from_float(3.33333333)
Fraction(7505999371444827, 2251799813685248)

我看到了
nsimplify()
函数,但这似乎有些过分。

您可以使用
分数。从\u float

>>> from fractions import Fraction
>>> Fraction.from_float(0.5)
Fraction(1, 2)
尽管它看起来不如Mathematica聪明:

In[25]:= Rationalize[0.5 x^2 - 3.333333 x, 10^-4]
Out[25]= x^2/2-(10 x)/3
>>> Fraction.from_float(3.33333333)
Fraction(7505999371444827, 2251799813685248)
实际上,它只是简单地将浮点转换为其精确的有理表达式(因此不能完全像浮点那样写入的数字不会被“正确”转换)

通过限制分母,您可以获得更多“人类可读性”:

>>> Fraction.from_float(3.333333333).limit_denominator(10)
Fraction(10, 3)
即使要理解应该设置哪一个限制以获得“正确”分数更为困难,而且由于浮点表示,可能仍然无法获得它

如果您必须继续使用
sympy
,我认为您无法避免使用
nsemplify
, 似乎正是为了这样的目的而写的


编辑:从python2.7+中,您可以简单地调用
分数(0.5)
,而不是使用
from\u float
方法。

我不知道
nsimplify
是如何过度杀戮的
nsimplify
完全按照您的要求执行,因为您可以向它传递一个SymPy表达式,它将使表达式中的术语合理化

>>> print nsimplify(0.5*x**2 - 3.333333*x, tolerance=0.001, rational=True)
x**2/2 - 3333333*x/1000000

(tolerance关键字似乎不起作用,我想这是一个bug)。

由于您使用的是Symphy,您还可以从mpmath模块访问
pslq
函数;这将使您能够找到有理数与1之间最相关的线性关系:

>>> from mpmath import pslq, mpf
>>> from sympy import sympify
>>> l = pslq([ mpf('.3333333333333333333333', 1])
>>> -l[1]/sympify(l[0])
1/3

啊,我想rational标志确实让它少了些杀伤力。我查看了源代码,我认为没有使用公差,因为
sympy.simplify.nsimplify()
调用
sympy.simplify.\u real\u to\u rational()
,如果rational标志为true,但不传递任何公差参数。也许我会玩弄这个来得到我想要的。非常感谢。如果你感兴趣的话,我为宽容开了一个话题:太棒了!我已经补充了我认为可能是你的问题的原因。我想对它进行更多的研究,但遗憾的是,在工作中,它的优先级还不高。嗯,我没有意识到Python将其作为一个内置模块——谢谢!我想我将使用Asmeur指出的
nsimplify()
,并使用您指出的
limit\u denominator()
功能实现一个简单的公差功能。上述示例的限制仅为
10**4