【问题标题】:Get a value from solution set returned as finiteset by Sympy从 Sympy 返回为有限集的解决方案集中获取一个值
【发布时间】:2016-11-19 23:14:13
【问题描述】:

我正在 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、列表、元组、索引命令,但总是返回错误。 "Finiteset 对象没有属性 'command'"

【问题讨论】:

    标签: python sympy


    【解决方案1】:

    我在这个链接http://docs.sympy.org/latest/tutorial/manipulation.html找到了sympy库方式

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

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

    【讨论】:

      【解决方案2】:

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

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

      然后您可以使用标准索引提取元素 - 在本例中为 a[0]。但是,如果您有多种解决方案,您可以选择您想要的一种。

      【讨论】:

      • FiniteSet 是无序的。可能无法知道哪个是“您想要的”。
      【解决方案3】:

      很奇怪。没有说明如何使用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】:

        您可以使用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。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

              【解决方案7】:

              我知道这是一个旧线程,但如果您不想将有限集转换为列表,请使用以下方法:

              from sympy import *
              x, y = symbols('x y')
              z = solveset(x-y-1,x).args[0]  # returns 1st element of finiteset
              sum = z.subs(y,10)
              
              print(sum)
              print(type(sum))
              

              结果是:

              11
              <class 'sympy.core.numbers.Integer'>
              

              【讨论】:

                猜你喜欢
                • 2020-02-16
                • 1970-01-01
                • 2023-01-12
                • 1970-01-01
                • 2011-05-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-05-17
                相关资源
                最近更新 更多