代数求解方程组¶
使用 SymPy 代数求解方程组,无论线性或非线性。例如,求解 \(x^2 + y = 2z, y = -4z\) 关于 x 和 y (假设 z 是一个常数或参数) 将得到 \(\{(x = -\sqrt{6z}, y = -4z),\) \({(x = \sqrt{6z}, y = -4z)\}}\).
备选方案¶
代数求解方程组的示例¶
无论你的方程是线性还是非线性,你都可以使用solve()
代数解线性方程组¶
>>> from sympy import solve
>>> from sympy.abc import x, y, z
>>> solve([x + y - 2*z, y + 4*z], [x, y], dict=True)
[{x: 6*z, y: -4*z}]
代数解非线性方程组¶
>>> from sympy import solve
>>> from sympy.abc import x, y, z
>>> solve([x**2 + y - 2*z, y + 4*z], x, y, dict=True)
[{x: -sqrt(6)*sqrt(z), y: -4*z}, {x: sqrt(6)*sqrt(z), y: -4*z}]
指导¶
请参考 在函数调用中包含要解的变量 和 确保从 solve() 返回的一致格式.
下面有两种方法可以包含解的结果:字典 或 集合。字典更容易用程序查询,因此,如果您需要使用代码提取解,我们建议您使用字典方法。
解并使用字典中的结果¶
将解作为字典输入¶
您可以针对某些变量(例如,\(x\) 和 \(y\))解方程组,并将另一个符号作为常数或参数(例如,\(z\))。您可以将要解的变量指定为多个独立的参数,或作为列表(或元组)。
>>> from sympy import solve
>>> from sympy.abc import x, y, z
>>> equations = [x**2 + y - 2*z, y + 4*z]
>>> solutions = solve(equations, x, y, dict=True)
>>> solutions
[{x: -sqrt(6)*sqrt(z), y: -4*z}, {x: sqrt(6)*sqrt(z), y: -4*z}]
使用字典中给出的解¶
然后,您可以通过索引(在括号中指定)解的编号,然后是符号来提取解。例如 solutions[0][x]
给出了第一个解中 x
的结果。
>>> solutions[0][x]
-sqrt(6)*sqrt(z)
>>> solutions[0][y]
-4*z
将解结果放入集合中¶
要获取符号列表和解的集合,请使用 set=True
而不是 dict=True
。
from sympy import solve
from sympy.abc import x, y, z
solve([x**2 + y - 2*z, y + 4*z], [x, y], set=True)
([x, y], {(-sqrt(6)*sqrt(z), -4*z), (sqrt(6)*sqrt(z), -4*z)})
可以加快 solve()
的选项¶
请参考 可以加快 solve() 的选项.
并非所有方程组都能解¶
无解的方程组¶
有些方程组无解。例如,以下两个方程组无解,因为它们简化为 1 == 0
,因此 SymPy 返回一个空列表。
>>> from sympy import solve
>>> from sympy.abc import x, y
>>> solve([x + y - 1, x + y], [x, y], dict=True)
[]
from sympy import solve
from sympy.abc import x, y, z
solve([x + y - (z + 1), x + y - z)], [x, y], dict=True)
[]
以下方程组简化为 \(z = 2z\),因此它没有一般解,但如果 \(z=0\),它可以得到满足。请注意,solve()
不会假定 \(z=0\),即使它是使方程组一致的唯一 \(z\) 值,因为 \(z\) 是一个参数而不是一个未知数。也就是说,solve()
不会将 \(z\) 视为未知数,因为它不在指定为未知数的符号列表中 ([x, y]
),并且所有此类符号都被视为具有任意值的参数。符号是作为变量还是参数处理,完全取决于它是否在 solve()
中指定为要解的符号。使用 symbols()
(或从 abc
导入)创建符号时,没有这种区别。
>>> from sympy import solve
>>> from sympy.abc import x, y, z
>>> solve([x + y - z, x + y - 2*z], [x, y], dict=True)
[]
以下方程组是 超定 的,这意味着方程数(三个)比要解的未知数(两个,即 \(x\) 和 \(y\))多。它无解。
>>> from sympy import solve
>>> from sympy.abc import x, y, z
>>> solve([x + y - z, x - (z + 1), 2*x - y], [x, y], dict=True)
[]
请注意,有些超定系统确实有解(例如,如果一个方程是其他方程的线性组合),在这种情况下,SymPy 可以解超定系统。
无闭式解的方程组¶
有些方程组无法用代数方法解,例如包含 超越方程 的方程组。
>>> from sympy import cos, solve
>>> from sympy.abc import x, y, z
>>> solve([x - y, cos(x) - y], [x, y], dict=True)
Traceback (most recent call last):
...
NotImplementedError: could not solve -y + cos(y)
>>> from sympy import cos, nsolve
>>> from sympy.abc import x, y, z
>>> nsolve([x - y, cos(x) - y], [x, y], [1,1])
Matrix([
[0.739085133215161],
[0.739085133215161]])
具有闭式解,但 SymPy 无法解的方程¶
您的方程也可能存在代数解,但 SymPy 未实现适当的算法。如果 SymPy 在您知道存在闭式解的情况下返回一个空集或列表(表示 SymPy 中存在错误),请在 邮件列表 上发布问题,或在 SymPy 的 GitHub 页面 上创建问题。在问题解决之前,您可以使用 可考虑的替代方法 中列出的其他方法。
报告错误¶
如果您发现 solve()
存在错误,请在 SymPy 邮件列表 上发布问题。在问题解决之前,您可以使用 可考虑的替代方法 中列出的其他方法。