代数求解方程组¶
使用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}]
指导¶
参见 Include the Variable to be Solved for in the Function Call 和 确保从 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页面上开启一个问题。在问题解决之前,你可以使用Alternatives to Consider中列出的其他方法。
报告一个错误¶
如果你在使用 solve()
时发现了一个错误,请在 SymPy 邮件列表 上发布这个问题。在问题解决之前,你可以使用 Alternatives to Consider 中列出的其他方法。