2016-08-04 10 views
2

私はSympyを使ってユーザーが提供するシンボリック式を評価していますが、除算演算子は他の算術演算子と同じように動作しません。オーバーライドされた演算子を持つオブジェクトの式を評価するとき、除算ではなく、加算、減算、および乗算の予想される結果が得られます。以下のコードは、私の問題を示していますsympyでシンボリック式をlambdifyingするときの除算演算子を無効にする

import sympy 
import numpy 

class NewMath(int): 

    def __add__(self, other): 
     print "Adding!" 
     return 

    def __sub__(self, other): 
     print "Subtracting!" 
     return 

    def __mul__(self, other): 
     print "Multiplying!" 
     return 

    def __div__(self, other): 
     print "Dividing!" 
     return 

three = NewMath(3) 
four = NewMath(4) 

three + four 
three - four 
three * four 
three/four 

# Override sympys default math 
func_map = {'+':NewMath.__add__, 
      '/':NewMath.__div__} 

lambda_args = [sympy.Symbol(arg) for arg in ['three', 'four']] 

print "Now sympy math:" 
lambda_addition = sympy.lambdify(lambda_args, sympy.Symbol('three') + sympy.Symbol('four'), modules=func_map) 
lambda_addition(three, four) 

lambda_subtraction = sympy.lambdify(lambda_args, sympy.Symbol('three') - sympy.Symbol('four'), modules=func_map) 
lambda_subtraction(three, four) 

lambda_multiplucation = sympy.lambdify(lambda_args, sympy.Symbol('three') * sympy.Symbol('four'), modules=func_map) 
lambda_multiplucation(three, four) 

lambda_division = sympy.lambdify(lambda_args, sympy.Symbol('three')/sympy.Symbol('four'), modules=func_map) 
lambda_division(three, four) 

出力:私はSympy Docsを読み、/オペレータが共通の落とし穴であるが、それを見てきました

Adding! 
Subtracting! 
Multiplying! 
Dividing! 
Now sympy math: 
Adding! 
Subtracting! 
Multiplying! 
0.75 

は、ドキュメントは、ちょうどその部門を示しているように見えます整数除算にデフォルト設定されますが、/が上書きできないことを示すものは表示されません。私の例では、modules引数を使用して、私のカスタム演算子で除算を手作業で置き換えようとしたが、役に立たなかった。

私はまた、division in sympy is really just a power of -1 and multiplicationを見たことがありますが、これは私の原因が絶望的であることを意味しますか?

私はpython 2.7とsympy 1.0を使用しています

+0

あなたのコードに 'from __future__ import division'がある場合(これはPython 2のためにお勧めします)、' __div__'ではなく '__truediv__'をオーバーライドする必要があります。 – asmeurer

+1

あなたの 'func_map'は何もしていません。関数マップは、Pythonの名前を他のPythonの名前にマッピングするためにのみ機能します(つまり、lambdified関数が実行される名前空間の変数を定義します)。 '+'と '/'は名前ではなく演算子であるため、これは機能しません。 – asmeurer

答えて

-1

あなたの原因は確かに完全に希望ではありません。ここにあなたを始めるためのいくつかのオプションがあります。

最初に、__div__ __truediv__と__floordiv__の違いを理解しているようですが、まだ作成していなければ、hereはいくつかのpython 2.7ドキュメントです。

python 2.7では、__div__を上書きすることは、a/bが* b ^( - 1)として評価されていることを発見したsympyのドキュメントを除いて、あなたが望むようにするべきだと思われます。これを回避するには、指数演算子をオーバーライドすることもできます。

python3環境でコードを実行しようとしましたが、printのすべてのインスタンスをカッコで囲み、divのすべてのインスタンスをtruedivに置き換えました。

これは本当に完全な答えではありませんが、私はコメントを投稿できませんので、これはあなたが得るものです!

関連する問題