Round Floats表达式中

时间:2017-05-05 12:15:04

标签: sympy

我遇到了以下问题:

我有一个sympy表达式的同情矩阵,每个单元格看起来像下面的例子,称之为ex1

In: ex1

Out: -mu_0_0 + t*((0.8*mu_0_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_4)**2 + (0.8*mu_1_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_3)**2 + (0.8*mu_3_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_2)**2 + (0.8*mu_6_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_1)**2 + (0.4*mu_10_0 + 0.4*mu_10_1 - 0.4)*Max(0, alpha_0_1_0)**2) + (-t + 1)*(0.498558013279766*mu_0_1 + 0.0238962672572783*mu_10_0 + 0.0238962672572783*mu_10_1 + 0.18596764210715*mu_1_1 + 0.0201673973158616*mu_3_1 + 0.0475144127826656*mu_6_1 - 0.023896267257278) + Max(0, -alpha_0_0_0)**2  

矩阵后来被贬低。但是,在那之前,我想摆脱2.22044604925031e-16和漂浮物;这些是来自代码其他部分的artifcats,应该是0.

我想从这些中清除矩阵单元格中的表达式,但无法弄清楚如何。

应用于ex1.round()时,

ex1崩溃了我的python,它似乎不适用于简单表达式,例如

In: sympy.sympify(0.01*t).round(1)  
TypeError: can't convert expression to float

如果我通过N尝试,如

In: sympy.N(eq, n=3)

我明白了:

RecursionError: maximum recursion depth exceeded

(我甚至不确定这会起作用,因为据我所知,这会将浮动数减少到n位有效数字?)

有没有办法以我想要的方式清理这些表达式?

提前致谢!

我将保留表达式结构,以防有任何帮助:

sympy.srepr(ex1)  

"Add(Mul(Integer(-1), Symbol('mu_0_0')), Mul(Symbol('t'), Add(Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_0_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_4')), Integer(2))), Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_1_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_3')), Integer(2))), Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_3_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_2')), Integer(2))), Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_6_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_1')), Integer(2))), Mul(Add(Mul(Float('0.40000000000000002', prec=15), Symbol('mu_10_0')), Mul(Float('0.40000000000000002', prec=15), Symbol('mu_10_1')), Float('-0.3999999999999998', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_0')), Integer(2))))), Mul(Add(Mul(Integer(-1), Symbol('t')), Integer(1)), Add(Mul(Float('0.49855801327976634', prec=15), Symbol('mu_0_1')), Mul(Float('0.02389626725727826', prec=15), Symbol('mu_10_0')), Mul(Float('0.02389626725727826', prec=15), Symbol('mu_10_1')), Mul(Float('0.18596764210714989', prec=15), Symbol('mu_1_1')), Mul(Float('0.020167397315861646', prec=15), Symbol('mu_3_1')), Mul(Float('0.047514412782665633', prec=15), Symbol('mu_6_1')), Float('-0.023896267257278034', prec=15))), Pow(Max(Integer(0), Mul(Integer(-1), Symbol('alpha_0_0_0'))), Integer(2)))"

1 个答案:

答案 0 :(得分:8)

可以使用preorder_traversal遍历表达式树,并用浮点值替换浮点数。在下面的示例中,浮点数在小数点后舍入为1位数。

from sympy import *
x, y = symbols('x y')
ex1 = 3.1415*(2.00003*x + 3e-12) + x*(y + 0.0003*x - 4e-13)**2 + 1.234567
ex2 = ex1
for a in preorder_traversal(ex1):
    if isinstance(a, Float):
        ex2 = ex2.subs(a, round(a, 1))
print(ex1)  # original
print(ex2)  # rounded

输出(用于比较的原始表达式):

x*(0.0003*x + y - 4.0e-13)**2 + 6.283094245*x + 1.23456700000942
x*y**2 + 6.3*x + 1.2