sympy 分段函数的 lambdification 计算每个表达式
lambdification of sympy piecewise function evaluates every expression
我正在对一个 sympy 分段函数进行 lambdifying 尝试做这样的事情:
f = Piecewise((1,(p > -1e-10) & (p < 1e-10)), (1/p, True))
g = lambdify(p,f,"numpy")
同时
>>> f.subs(p,0)
1
我明白了
>>> g(0)
/usr/lib/python2.7/dist-packages/numpy/__init__.py:1: RuntimeWarning: divide by zero encountered in true_divide
"""
array(1.0)
看来,(lambdified ?)-Piecewise 在返回条件为真的表达式之前对所有表达式求值。有解决办法吗?
NumPy code printer used by lambdify 将 Piecewise
翻译成
numpy.select(conditions, expressions, default=numpy.nan)
这意味着数组 expressions
在 numpy.select
选择该数组的一个元素之前被完整计算。一些绕过它的方法是:
1) 将后端更改为math
(或mpmath
,或numpy
以外的任何内容),这将导致Piecewise
被翻译成 nested if statement。
g = lambdify(p, f, "math")
g(0) # 1, no warnings
2) 将公式改写为Max/Min/Abs/sign,可以表达一些分段函数,很容易lambdify。这并不总是可能的,但在你的情况下,
f = 0.5 * (sign(p + 1e-10) + sign(p - 1e-10)) / Max(1e-10, Abs(p)) + 0.5 * (sign(p + 1e-10) - sign(p - 1e-10))
完成任务。诀窍是当 p 不太接近 0 时 0.5 * (sign(p + 1e-10) + sign(p - 1e-10))
是 sign(p) ,当 p 太接近 0 时是 0 。类似地,如果 p 不太接近 0,则 0.5 * (sign(p + 1e-10) - sign(p - 1e-10))
为 1,当它太接近时为 0。这些因素导致公式从一种模式切换到另一种模式,并且分母中的 Max
在任何情况下都避免了被零除的错误。
3) Suppress Runtime Warnings
我正在对一个 sympy 分段函数进行 lambdifying 尝试做这样的事情:
f = Piecewise((1,(p > -1e-10) & (p < 1e-10)), (1/p, True))
g = lambdify(p,f,"numpy")
同时
>>> f.subs(p,0)
1
我明白了
>>> g(0)
/usr/lib/python2.7/dist-packages/numpy/__init__.py:1: RuntimeWarning: divide by zero encountered in true_divide
"""
array(1.0)
看来,(lambdified ?)-Piecewise 在返回条件为真的表达式之前对所有表达式求值。有解决办法吗?
NumPy code printer used by lambdify 将 Piecewise
翻译成
numpy.select(conditions, expressions, default=numpy.nan)
这意味着数组 expressions
在 numpy.select
选择该数组的一个元素之前被完整计算。一些绕过它的方法是:
1) 将后端更改为math
(或mpmath
,或numpy
以外的任何内容),这将导致Piecewise
被翻译成 nested if statement。
g = lambdify(p, f, "math")
g(0) # 1, no warnings
2) 将公式改写为Max/Min/Abs/sign,可以表达一些分段函数,很容易lambdify。这并不总是可能的,但在你的情况下,
f = 0.5 * (sign(p + 1e-10) + sign(p - 1e-10)) / Max(1e-10, Abs(p)) + 0.5 * (sign(p + 1e-10) - sign(p - 1e-10))
完成任务。诀窍是当 p 不太接近 0 时 0.5 * (sign(p + 1e-10) + sign(p - 1e-10))
是 sign(p) ,当 p 太接近 0 时是 0 。类似地,如果 p 不太接近 0,则 0.5 * (sign(p + 1e-10) - sign(p - 1e-10))
为 1,当它太接近时为 0。这些因素导致公式从一种模式切换到另一种模式,并且分母中的 Max
在任何情况下都避免了被零除的错误。
3) Suppress Runtime Warnings