2014-01-08 2 views
5

У меня есть выражение из SymPy расчета:Как заменить float на рациональные выражения в выражении sympy?

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

где а, Ь, с символами, и хотел бы разобрать его так, чтобы поплавки заменяются рациональными числами, как в

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

Я знаю, как сделать один вручную,

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

Out[24]: 1/3 

, но не знают, как идти о разборе атомов и выбрать только те, которые являются поплавками, и substituti ng назад приближение рационального числа.

Каков самый умный способ выполнения этих замещений в выражении?

ответ

6

Использование 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) 
+0

Спасибо, прошу прощения, намного проще. Я принял ваш ответ. – acortis

1

После немного возиться, я думаю, что нашел способ сделать это, но я не уверен, что он покроет все угловые случаи. Во всяком случае, это так. Любые предложения по улучшению?

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, str(r.p)+'/'+str(r.q)) 
    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) 
+0

Не использовать строки. И в любом случае 'r' уже является рациональным числом, поэтому' expr.subs (i, r) 'должно делать то, что вы хотите. – asmeurer

Смежные вопросы