How do I replace floats with rationals in a sympy expression?

不问归期 提交于 2020-05-14 18:06:08

问题


I have an expression from a sympy calculation:

sqrt(pi)*(0.333333333333333*a + 0.333333333333333*b - 2.66666666666667*c**2)

where a,b,c are symbols, and would like to parse it so that the floats are replaced with rationals like in

sqrt(pi)*(1/3*a + 1/3*b - 8/3*c**2)

I know how to do one by hand,

In[24] Rational(str(0.333333333333333)).limit_denominator(1000)

Out[24]: 1/3

but do not quite know how to go about parsing the atoms and picking only the ones that are floats, and substituting back the rational number approximation.

What is the smartest way of doing these substitutions in the expression?


回答1:


Use nsimplify:

>>> print(nsimplify(sqrt(pi)*(0.333333333333333*a + 0.333333333333333*b - 2.66666666666667*c**2)))
sqrt(pi)*(a/3 + b/3 - 8*c**2/3)



回答2:


After a bit of fiddling, I think I have found a way to do it, but I am not sure that it will cover all the corner cases. At any rate here it is. Any suggestions for improvement?

import sympy
def rationalize_coeffs(expr):
    for i in expr.atoms(sympy.Float):
        r = sympy.Rational(str(i)).limit_denominator(1000)
        expr = expr.subs(i, r)
    return expr    

if __name__=='__main__':
    # given a sympy expression expr
    x,y,z = sympy.symbols('x y z')
    # expr_orig = 2/57.*x + 3./4.*y + 3./4.*z
    expr = 0.0350877192982456*x + 0.75*y + 0.75*z

    print rationalize_coeffs(expr)


来源:https://stackoverflow.com/questions/21005132/how-do-i-replace-floats-with-rationals-in-a-sympy-expression

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!