2016-06-26 3 views
3

sympy 0.7.6では、両方のモジュール= 'sympy'とmodules = 'numpy'オプションの両方で次のコードに問題はありませんでした。今sympy v0.1デベロッパーで、モジュール=「numpyの」との評価がZeroDivisionErrorを上げる:piecewise関数とnumpyモジュールのsympy.lambdifyでのエラー

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 

を区分関数はモジュール=「numpyの」との条件の前に評価するように思えます。

私の質問は以下のとおりです。

は、この動作は正常ですか?

sympy.lambdifyプロシージャを使用せずに、piecewise式をnumpyモジュールと同じように定義し、高速に評価する方法とその理由は何ですか?

EDIT:

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 

答えて

2

私は(あなたはすでにそれを見た場合には)私の他の答えを削除:

は、私の場合には解決策がtheanoであることがわかりました。はるかに簡単な解決策があります。

lambdified式はおおよそlambda x, y: select([less(y, -1),less_equal(y, 1),True], [1/x,x,1/x], default=nan)を生成するため、ZeroDivisionErrorが発生します。問題は、x = 0を渡すとPythonによって評価される1/0という結果になり、エラーが発生します。

しかし、NumPyは0で割っても問題ありません。警告を出しますが、それ以外の場合はうまく動作します(inf)。この例では、実際にはinfが使用されていないため、問題はありません。

だから、解決策は、あなたが興味を持っている場合は、これを議論SymPy issueがある代わりに

f_numpy(0, 1) 

使用

f_numpy(array(0), array(1)) 

の、つまり、numpyの配列としてlambdifyへの入力をラップすることです。

+0

ありがとうございます。これは今私にとってははるかに明確です。私は 'numpy.array'ソリューションを試してみる。 今のところ、私は 'lambdarepr'と(残念ながら) 'eval'を呼び出すこの回避策を使用しています: https://gist.github.com/A-Falaize/ff2fafd5ab19f88c478f7494e340a619 これは私にとってはうまくいくが、ピジョンそのようなソリューションの欠点は何ですか? – Toht

+0

私はあなたの貧しい人の羊飼いがこの問題をどのように解決するのか分かりません。私の言うことは、あなたの関数がするすべてのことから、 'sympy.lambdify'でもありますが、' sympy.lambdify'ももっと多くなりますので、ちょうどそれを使用することをお勧めします。 – asmeurer

関連する問題