Python Sympyライブラリでスクリプトを作成し、solveset()関数とlinsolve()関数によって返された結果にアクセスしようとしています。私の問題は、これらの関数によって返されたオブジェクトが有限セット型であることですいくつかの結果を自動的に選択して、他の方程式に再入力したいのですが、任意のボディが役立ちますか?
>>> a1, a2 = symbols('a1, a2')
>>> eq2_1 = Eq(-3*a1/10 - 3*a2/20 + 1/12)
>>> eq2_2 = Eq(-3*a1/20 - 13*a2/105 + 1/20)
>>> lista = [eq2_1,eq2_2]
>>> str(lista)
[-3*a1/10 - 3*a2/20 + 1/12, -3*a1/20 - 13*a2/105 + 1/20]
次に、linsolve()メソッドで解決します。
>>> a = linsolve(lista,a1,a2)
>>> a
{(71/369, 7/41)}
結果は正しいですが、これらの結果を変数に入れることができません。
Oは、dics、lists、tuples、indexingコマンドを試しましたが、常にエラーを返しました。 "Finitesetオブジェクトには属性 'command'がありません。"
私はこのリンクでsympyライブラリの方法を見つけました http://docs.sympy.org/latest/tutorial/manipulation.html
関数または結果オブジェクトで.args属性を使用します。機能がある場合:
>>>func = Eq(u(x),−x+sin(x))
>>>func
u(x) = -x + sin(x)
>>>func.args[0]
u(x)
>>>func.args[1]
-x+sin(x)
有限集合型の結果についても同様です。
もう少し一般的な解決策は、単にFiniteSet
を標準のpython list
に変換することです。
>>> a=list(linsolve(lista,a1,a2))
>>> a
[(71/369, 7/41)]
次に、標準のインデックスを使用して要素を抽出できます—この場合はa[0]
。しかし、複数のソリューションを入手した場合、必要なソリューションを引き出すことができます。
iter
を使用してセットに基づくイテレータを取得し、次にnext
を使用してそのセットの1つの要素を返すことができます(要素が1つだけ必要な場合)。
例:
from sympy import *
var('x y')
sol = linsolve([x+y-2, 2*x-3*y], x, y)
(x0, y0) = next(iter(sol))
ここで、x0は6/5、y0は4/5です。
変だ。 linsolve
の結果の使用方法はどこにも説明されていません。
specs でも、要素を個別にチェックすることなく、結果セット全体をテストするだけです。
方程式系が少なくとも1つの解を許容することがわかっている場合は、割り当ての前に末尾のコンマを付けて sequence unpacking を使用できます。
>>> from sympy import linsolve, symbols, solve, Rational
>>> a1, a2 = symbols('a1 a2')
>>> equations = [-3*a1/10 - 3*a2/20 + Rational(1, 12), -3*a1/20 - 13*a2/105 + Rational(1, 20)]
>>> equations
[-3*a1/10 - 3*a2/20 + 1/12, -3*a1/20 - 13*a2/105 + 1/20]
>>> linsolve(equations, a1, a2)
{(71/369, 7/41)}
>>> solution, = linsolve(equations, a1, a2)
>>> solution
(71/369, 7/41)
この構文は、無限の解がある場合にも機能します。
>>> solution, = linsolve([a1, a1], a1, a2)
>>> solution
(0, a2)
しかし、解決策がない場合は失敗します。
>>> solution, = linsolve([a1 - 1, a1 - 2], a1, a2)
ValueError: not enough values to unpack (expected 1, got 0)
これは望ましい振る舞いかもしれません。
別の可能性は、ソリューションを単純に反復することです:
>>> for solution in linsolve(equations, a1, a2):
... print(solution)
...
(71/369, 7/41)
解決策がない場合は何も起こりません。
>>> for solution in linsolve([a1 - 1, a1 - 2], a1, a2):
... print(solution)
...
solve
の代わりにlinsolve
を使用することもできます。ただし、プロジェクトでは 非推奨 ですが、異なるタイプを出力できるためです。
>>> solve(equations, a1, a2)
{a1: 71/369, a2: 7/41}
>>> solve([a1 - 1, a1 - 2], a1, a2)
[]
Tuple
を引数の解凍と組み合わせて使用できます。
var('x y z')
eqs = [ x + y + z - 1, x + y + 2*z - 3 ]
sol = linsolve( eqs, x, y, z )
(x0, y0, z0) = Tuple(*sol)
これでソリューションを確認できます:
eqs[0].subs( [(x, x0), (y, y0), (z, z0)] )
eqs[1].subs( [(x, x0), (y, y0), (z, z0)] )