2016-03-23 14 views
3

一般的な部分式置換をしようとしています。Sympy:ワイルド記号を使用した置換

x*ycという形式の表現を正確に置き換えます。

xyは、式の中の任意の記号にすることができます。

以下のコードでは、これを達成するためにWildを使用していますが、明らかにサブ表現の代わりに野生一致シンボルのみを使用することはできません。isinstance=[sp.Symbol]を使用しても。

import sympy as sp 
a, b, c = sp.symbols('a b c') 

f= a*b - b 

x = sp.Wild('x', isinstance=[sp.Symbol]) 
y = sp.Wild('y', isinstance=[sp.Symbol]) 

expr = f.replace(x*y, c) 

これは、次のような結果につながる、

print expr 
c 

予想の答えは、しかしです:c - b

ヘルプははるかに高く評価されます!

ありがとうございます!

答えて

3

isinstanceWildのための本当の引数ではありません。

あなたが探している議論はpropertiesです。文書化されていないように見えますが、引数は一致した式に当てはまる関数のリストを取ります。

In [7]: f= a*b - b 

In [14]: y = sp.Wild('y', properties=[lambda x: isinstance(x, Symbol)]) 

In [15]: x = sp.Wild('x', properties=[lambda x: isinstance(x, Symbol)]) 

In [16]: f.replace(x*y, c) 
Out[16]: -b + c 
+0

完璧!よく働く! :) – Curious

1

はこれを試してみてください:

syms = sorted(set(a for a in f.atoms() if type(a) == sp.Symbol), key=str) 
f.subs((s1*s2, c) for s1, s2 in it.combinations(syms, 2)) 

この例では大丈夫に動作するようです:

import itertools as it 

a, b, c, d = sp.symbols('a b c d') 
f = 3*a**2*b*c**b+b*c**2+25+(a+b+c*a/4)/(a*c+3**(b*c))-8 

syms = sorted(set(a for a in f.atoms() if type(a) == sp.Symbol), key=str) 
repls = [(s1*s2, d) for s1,s2 in it.combinations(syms, 2)] 
print('variables:  ' + str(syms)) 
print('replacements: ' + str(repls)) 

expr = f.subs(repls) 
print('Before: ' + str(f)) 
print('After: ' + str(expr)) 
+0

場合によっては、 'fs(...、同時= True)'にする必要があります。 – Norman

+0

最高のパフォーマンスを得るには 'subs'の代わりに' xreplace'を使います。 – asmeurer

関連する問題