2014-01-08 58 views
5

我具有由sympy計算的表達式:如何用sympy表達式中的有理數替換浮點數?

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

其中a,b,c是符號,並想解析它使得浮標有理數替換像

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 

但不太知道如何去解析原子和採摘只有那些花車的,,替代回到有理數近似值。

在表達式中做這些替換的最明智的方法是什麼?

回答

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

謝謝asmeurer,簡單得多。我已經接受你的答案。 – 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

相關問題