2016-03-28 7 views
3

私は物理問題のジェネリックソルバー/ジェネレータを構築するために、Sympyと一緒に遊んでいます。 1つの要素は、kwargsをとり、それに応じて方程式を再配置し、値を代入する関数に向かうことです。 SOのおかげで、私はそれに必要なものを見つけることができました。forループのSympyソルバのバグ?

しかし.....私はsympy.solveをforループに入れて、これらの式を生成してみました。

import sympy 
R, U, I, eq = sympy.symbols('R U I eq') 
eq = R - U/I 
for x in 'RUI': 
    print(x) 
    print(sympy.solve(eq, x)) 

出力は?

R 
[U/I] 
U 
[I*R] 
I 
[] 

私はsympy.solve(eq, I)を行うたびしかし、それは動作し[U/R]を返します。

今、私は、虚数単位とブロック内に変数隠蔽を使ってsympyを使用していると推測していますが、forループ(および等式)内のシンボル宣言を転送しても、同じ問題。

私は最後にこれがひどく必要なのかどうかはわかりませんが、これはあまり意味がありません。

答えて

2

これはバグよりも文書化されていない機能によく似ています。ループfor x in 'RUI'for x in ['R', 'U', 'I']に相当します。つまり、xは1文字の文字列であり、sympyシンボルではありません。ループ内にprint(type(x))を挿入してこれを確認します。 sympy.solve(eq, 'I')[]を返します。

ループfor x in [R, U, I]は、変数ごとに正しく解決されます。これはこのループを書く正しい方法です。

solveの2番目の引数として文字列を渡すときに何かを得ることは驚くべきことです。 Sympy documentationは、受け入れ可能な引数の中に文字列をリストしません。どうやら、それはsympyオブジェクトに文字列を強制しようとすると、常に正しく意味を推測していません:sympy.solve(eq, 'R')で動作しなくsympy.solve(eq, 'I')

+0

だから、基本的に「バグ」は「I」ではなく、「R」と「U」にありますか?それは、文字列が虚数単位に使用される 'I'でない限り、sympyが記号的に文字列をシンボルとして受け取るという意味で理にかなっています。 –

1

の問題は、彼らが呼ぶので、入力として文字列でその一部sympy機能「偶然」の仕事がありますsympifyを入力します。しかし、sympify('I')はSymbol( 'I')ではなく、虚数単位(sqrt(-1))を与えます。

あなたは常に明示的に

R, U, I = symbols("R U I") 

のようなあなたのシンボルを定義し、文字列の代わりにこれらを使用する必要があります。

symPyで文字列を使用しないようにする理由については、https://github.com/sympy/sympy/wiki/Idioms-and-Antipatterns#strings-as-inputを参照してください。