从Sympy返回的有限集返回的解决方案集中获取值

时间:2016-07-17 05:33:00

标签: python sympy

我在Python Sympy库中创建一个脚本,并尝试访问solveset()和linsolve()函数返回的结果。我的问题是这些函数返回的对象是有限集类型,我想自动选择一些结果,以便在其他方程中重新输入它。       任何人都可以帮助我吗?

示例:I create a list of equations with two unknown variables:

>>> 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,list,tuples,indexing命令,但总是返回错误。 “Finiteset对象没有属性'命令'”

6 个答案:

答案 0 :(得分:11)

我在此链接http://docs.sympy.org/latest/tutorial/manipulation.html

中找到了sympy library方式

在函数或结果对象中使用.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)

同样适用于有限集类型的结果。

答案 1 :(得分:4)

您可以使用iter根据集合获取迭代器,然后使用next返回该集合中的一个元素(如果您只需要一个元素)。

示例:

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。

答案 2 :(得分:2)

稍微更通用的解决方案是简单地将FiniteSet转换为标准python list

>>> a=list(linsolve(lista,a1,a2))
>>> a
[(71/369, 7/41)]

然后,您可以使用标准索引提取元素 - 在本例中为a[0]。但是如果你得到多个解决方案,你可以拿出你想要的解决方案。

答案 3 :(得分:2)

怪异。在任何地方都没有说明如何使用linsolve的结果。

即使specs仅测试整个结果集,也不单独检查元素。

序列解包

如果您知道等式系统允许至少一个解决方案,则可以在分配之前使用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)
... 

解决而不是linsolve

您也可以使用solve代替linsolve,即使它是项目的not recommended,因为它可以输出不同的类型:

>>> solve(equations, a1, a2)
{a1: 71/369, a2: 7/41}
>>> solve([a1 - 1, a1 - 2], a1, a2)
[]

答案 4 :(得分:1)

FiniteSet具有一个返回元组的args()方法。

https://github.com/sympy/sympy/issues/19689

答案 5 :(得分:0)

您可以将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)] )