按类型解决输出

由于 solve() 函数的输出可能看起来非常杂乱,因为它似乎可以任意返回六种不同类型的输出之一(除了引发错误之外)。这样做的原因是历史性的,并且偏向于人类交互而非程序化使用。输出的类型将取决于方程的类型(以及它们的输入方式)和提供的符号数量(以及它们的提供方式)。

>>> from sympy import sqrt, exp, solve, Symbol, Eq
>>> from sympy.abc import x, y, z, a, b

函数 solve() 尝试找到尽可能多的符号的所有值,使得每个给定的表达式等于零。可以通过使用 dictset 关键字来控制输出的格式:

>>> solve(x - 1, dict=True)
[{x: 1}]
>>> solve([x**2 - y, x + y - 6], set=True)
([x, y], {(-3, 9), (2, 4)})

以下讨论提供了在不使用这些关键字时所获得输出的解释。

空列表

当没有解决方案时,返回一个空列表。

>>> solve(sqrt(x) + 1)  # or solve(sqrt(x) + 1, dict=True)
[]
>>> solve(sqrt(x) + 1, set=True)
([x], set())

值列表

当待解符号在上下文中明确时,会给出一系列值,因为a) 方程是单变量的,或者b) 指定了单个符号为感兴趣的符号。

>>> solve(x**2 - 4)
[-2, 2]
>>> solve(x - y - 1, x)
[y + 1]

单一字典

当方程以列表形式传递并且所有方程在给定符号中都是线性时,结果是一个字典,其中键为符号,值为这些符号的解。注意:如果对于指定的符号存在未定系数解,则对于单个方程(未以列表形式传递)会自动生成这样的系统。如果不是预期的结果,则将表达式放在列表中传递。

>>> solve([x + y - 2, x - y + 2], x, y)
{x: 0, y: 2}
>>> eq = a*x - 2*x + b - 5
>>> solve(eq, {a, b})  # undetermined coefficients
{a: 2, b: 5}
>>> solve([eq], {a, b})  # algebraic
{a: -b/x + (2*x + 5)/x}

元组列表

列表中的每个元组按给定顺序为符号提供一个解。当a) 方程列表中至少包含一个非线性方程或b) 符号列表按定义良好的顺序给出时,使用此格式。(这也是在使用标志``set=True``时返回的集合中元组的格式。)

>>> solve(x - 1, x, y)  # more than one symbol
[(1, y)]
>>> solve([x**2], x)  # list with nonlinear equation
[(0,)]
>>> solve([x**2 - 1], x)
[(-1,), (1,)]
>>> solve([x**2 - y, x - 3], x, y)  # nonlinear and multiple symbols
[(3, 9)]

字典列表

当表达式不是单变量或在列表中有非线性表达式 并且 符号的顺序会因为以下原因而变得模糊时,将返回字典列表:a) 没有传递符号或 b) 符号以集合形式传递。(这也是选择 dict=True 时的格式。)

>>> solve(x - y)
[{x: y}]
>>> solve([exp(x) - 1, x*(x - 1)])
[{x: 0}]
>>> system = [x + y - z, x**2 - y + z, exp(z) + 1/x + 1/y - 2]
>>> sol = solve(system[:2]); sol
[{x: -1, y: z + 1}, {x: 0, y: z}]

字典仅包含与键不同的值。在上面的最后一个例子中,字典中没有 z 的键,因为只有 两个 方程不足以确定其值。然而,这些解可以用来从第三个方程中消除这些变量,从而得到一个单一变量的关系,可以通过(可能是数值的)求解来获得完整的解,其优点是只需要猜测一个值而不是三个。

>>> from sympy import nsolve
>>> [system[-1].subs(s) for s in sol]
[exp(z) - 3 + 1/(z + 1), exp(z) + zoo + 1/z]
>>> z_eq = _[0]
>>> zsol = nsolve(z_eq, 1); zsol
0.906425478894557
>>> sol0 = {k: v.subs(z, zsol) for k, v in sol[0].items()}
>>> sol0[z] = zsol; sol0
{x: -1, y: 1.90642547889456, z: 0.906425478894557}

布尔或关系

当给定一个非 Equality 的关系表达式作为求解表达式时,将返回一个布尔表达式。可能会返回一个单独的 \(Equality\) 或更复杂的关系表达式。这里使用 solve() 等同于将方程集和符号传递给 reduce_inequalities`(并且 ``dict`()setcheck 标志被忽略)。

>>> solve([x**2 > 4, x > 0])
(2 < x) & (x < oo)
>>> from sympy import Unequality as Ne
>>> solve([x**2 - 4, Ne(x, -2)])
Eq(x, 2)

任何返回的 \(Equality\) 都可以转换为字典:

>>> {_.lhs: _.rhs}
{x: 2}