SymPy

时间:2018-01-31 23:33:57

标签: python sympy

我目前正试图通过在Python中使用符号计算来计算模拟滤波器的负群延迟。我目前试图解决的问题是摆脱一些非常小的虚数系数。

例如,考虑具有这种分子的分数(虚部用粗体表示):

( - 1.705768 * w ^ 18 + 14.702976409432 * w ^ 16 + 1.06581410364015e-14 * I * w ^ 15 - 28.7694094371724 * w ^ 14 - 9.94759830064144e-14 * I * w ^ 13 + 59.0191623753299 * w ^ 12 + 5.6843418860808e-14 * I * w ^ 11 + 24.7015297857594 * w ^ 10 - 1.13686837721616e-13 * I * w ^ 9 - 549.093511217598 * w ^ 8 - 5.6843418860808e-14 * I * w ^ 7 + 1345.40434657845 * w ^ 6 + 2.27373675443232e-13 * I * w ^ 5 - 1594.14046181284 * w ^ 4 - 1.13686837721616e-13 * I * w ^ 3 + 980.58940367608 * w ^ 2 - 254.8428594382)

有没有办法自动舍入这些小系数,所以它们将等于0(通常是任何可忽略不计的值)?或者至少,我可以以某种方式过滤虚构的值吗?我曾尝试使用re(given_fraction),但它无法返回任何内容。标准的舍入函数也不能处理符号表达式。

1 个答案:

答案 0 :(得分:0)

舍入部分已经在Printing the output rounded to 3 decimals in SymPy中解决,所以我不会在那里重复我的答案,而不是丢弃系数的虚部。

方法1

您可以简单地执行re(expr),其中expr是您的表达方式。但要使其发挥作用,必须知道w是一个真正的变量;否则,SymPy无法告诉(3+4*I)*w的真实部分是什么。 (除非另有说明,否则SymPy符号被认为是复杂的。)这将完成工作:

w = symbols('w', real=True)
expr = # your formula
expr = re(expr)

方法2

如果由于某种原因你无法做到上述......另一种有点侵入性的方法是放弃所有的想象部分是用0代替我:

expr = expr.xreplace({I: 0})

这假设表达式已经处于展开形式(如图所示),因此没有(3+4*I)**2,例如;否则结果将是错误的。

方法3

比2更强大的方法,但专门用于多项式:

expr = Poly([re(c) for c in Poly(expr, w).all_coeffs()], w).as_expr()

此处表达式首先变为w中的多项式(在您的示例中可能是多项式,因为它具有多项式形式)。然后取每个系数的实部,并从中重建多项式。如果需要,最后一部分as_expr()将其返回到表达式表单。

无论哪种方式,表达式的输出:

-1.705768*w**18 + 14.702976409432*w**16 - 28.7694094371724*w**14 + 59.0191623753299*w**12 + 24.7015297857594*w**10 - 549.093511217598*w**8 + 1345.40434657845*w**6 - 1594.14046181284*w**4 + 980.58940367608*w**2 - 254.8428594382