2017-02-03 5 views
1

私はPythonとSympyを使用しています。PythonでSympyのブール式を評価する

x,y,z = Symbols('x,y,z') 
doc = {x : False, y : True, z: True} 
rule = Or(x, And(y,z)) 

私はrule.eval(doc)Trueを返しますSympy内の関数を探しています:

私は次がありますか?

編集: 現在、私はrule.subsrule.xreplaceを使用していますが、どちらも呼び出しあたり約0.0003秒でゆっくりと実行しています。これは実用的ではない。このIPythonがくれた後

X = tuple(doc.iterkeys()) 
f = lambdify(X, rule) 

+0

なぜ 'rule.subs(doc)'を実行できないのでしょうか? –

+0

こんにちは、あなたは正しいです、私はそれを言及していない。これは私が使っている 'rule.subs'と' rule.xreplace'ですが、どちらも期待どおりに動作しますが、奇妙なパフォーマンスがあります。コードをプロファイリングし、各実行に約0.0003秒かかることがわかりました。私はこれらの機能をたくさん使っています。私はより効率的な方法を探しています –

+0

そしてsympyを使用する必要がありますか?そうでなければ、次のようにすることができます: 'import operator as op;ルール=ラムダx、y、z:op.or_(x、op.and_(y、z));ルール(False、True、True) 'を返します。それがはるかに速いのでdictを提供しません。 –

答えて

1

最小限のコーディングでより良いパフォーマンスを取得する方法はlambdifyを使用することです

V = tuple(doc.itervalues()) 
%timeit f(*V) 
The slowest run took 7.56 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000000 loops, best of 3: 209 ns per loop 

私は警告が結論に影響を与える可能性がどのくらいかわかりませんしかし、明らかな改善があります。私が元のコードで持っていたのと同じコンピュータで:

%timeit rule.xreplace(doc) 
10000 loops, best of 3: 126 µs per loop 

サブシステムはさらに低速でした。

0

サブシステムを使用するのではなく、直接評価を使用できますか?

>>> F = Lambda((x, y, z), Or(x, And(y, z))) 
>>> F(0, 1, 1) 
True 

もしそうでない場合は、ラムダフォームを介してサブを許可するおもちゃクラスを作成できますか?これは、クラスではありませんが、アイデアを提供します:ラムダフォームを作成し、評価したラムダフォームを返すサブルーチンの方法を持っているでしょう

>>> def sub(f, d): 
...  F = Lambda(d.keys(), f) 
...  return F(*[d[k] for k in d.keys()]) 
>>> sub(Or(x,And(y,z)),{x:0,y:1,z:1}) 

クラス。