In sympy 0.7.6, I had no troubles with the following code for both the modules='sympy' and the modules='numpy' options. Now with sympy v0.1, the evaluation with modules='numpy' raise a ZeroDivisionError:
在第0.7.6节中,对于modules ='sympy'和modules ='numpy'选项,我对以下代码没有任何麻烦。现在使用sympy v0.1,使用modules ='numpy'进行评估会引发ZeroDivisionError:
import sympy
x, y = sympy.symbols(['x', 'y'])
expr = sympy.Piecewise((1/x, y < -1), (x, y <= 1), (1/x, True))
f_sympy = sympy.lambdify([x, y], expr, modules='sympy')
f_numpy = sympy.lambdify([x, y], expr, modules='numpy')
print f_sympy(0, 1) # performs well
print f_numpy(0, 1) # issue: ZeroDivisionError
Seems like the piecewise functions evaluate before the condition with modules='numpy'.
看起来像在使用modules ='numpy'的条件之前评估的分段函数。
My questions are:
我的问题是:
Is this behavior normal?
这种行为是否正常?
If so, why, and how to define a piecewise expression and evaluate it as fast as with numpy module without the sympy.lambdify procedure?
如果是这样,为什么,以及如何定义分段表达式并使用numpy模块快速评估它而没有sympy.lambdify过程?
EDIT:
编辑:
Found that in my case the solution is theano:
发现在我的情况下解决方案是theano:
import sympy
x, y = sympy.symbols(['x', 'y'])
f = sympy.Piecewise((1/x, y < -1), (x, y <= 1), (1/x, True))
from sympy.printing.theanocode import theano_function
f_theano = theano_function([x, y], [f])
print f_theano(0, 1) # OK, return 0
1 个解决方案
#1
2
I deleted my other answer (in case you already saw it). There is a much simpler solution.
我删除了我的其他答案(如果你已经看过了)。有一个更简单的解决方案。
The ZeroDivisionError comes because the lambdified expression produces, roughly, lambda x, y: select([less(y, -1),less_equal(y, 1),True], [1/x,x,1/x], default=nan)
. The problem is that passing in x = 0 results in 1/0
being evaluated by Python, which raises the error.
ZeroDivisionError之所以出现是因为lambdified表达式大致产生了lambda x,y:select([less(y,-1),less_equal(y,1),True],[1 / x,x,1 / x],默认值=南)。问题是传入x = 0会导致Python评估1/0,从而引发错误。
But NumPy is just fine with dividing by zero. It will issue a warning, but otherwise works fine (it gives inf
), and in this example there is no problem, because the inf
is not actually used.
但NumPy除以零就可以了。它会发出警告,但在其他方面工作正常(它给inf),在这个例子中没有问题,因为实际上没有使用inf。
So the solution is to wrap the input to lambdify
as numpy arrays, that is, instead of
所以解决方案是将输入包装为lambdify作为numpy数组,即代替
f_numpy(0, 1)
use
使用
f_numpy(array(0), array(1))
There is a SymPy issue discussing this if you are interested.
如果您有兴趣,有一个SymPy问题正在讨论这个问题。
#1
2
I deleted my other answer (in case you already saw it). There is a much simpler solution.
我删除了我的其他答案(如果你已经看过了)。有一个更简单的解决方案。
The ZeroDivisionError comes because the lambdified expression produces, roughly, lambda x, y: select([less(y, -1),less_equal(y, 1),True], [1/x,x,1/x], default=nan)
. The problem is that passing in x = 0 results in 1/0
being evaluated by Python, which raises the error.
ZeroDivisionError之所以出现是因为lambdified表达式大致产生了lambda x,y:select([less(y,-1),less_equal(y,1),True],[1 / x,x,1 / x],默认值=南)。问题是传入x = 0会导致Python评估1/0,从而引发错误。
But NumPy is just fine with dividing by zero. It will issue a warning, but otherwise works fine (it gives inf
), and in this example there is no problem, because the inf
is not actually used.
但NumPy除以零就可以了。它会发出警告,但在其他方面工作正常(它给inf),在这个例子中没有问题,因为实际上没有使用inf。
So the solution is to wrap the input to lambdify
as numpy arrays, that is, instead of
所以解决方案是将输入包装为lambdify作为numpy数组,即代替
f_numpy(0, 1)
use
使用
f_numpy(array(0), array(1))
There is a SymPy issue discussing this if you are interested.
如果您有兴趣,有一个SymPy问题正在讨论这个问题。