1.1.5. 求解

参考 Solvers

import warnings
from sympy import *

warnings.filterwarnings('ignore')
x, y, z = symbols('x y z')
init_printing(use_latex='mathjax')

等式

Eq(x, y)
\[\displaystyle x = y\]

解方程:

solveset(Eq(x**2, 1), x)
\[\displaystyle \left\{-1, 1\right\}\]
solveset(Eq(x**2 - 1, 0), x)
\[\displaystyle \left\{-1, 1\right\}\]
solveset(x**2 - 1, x)
\[\displaystyle \left\{-1, 1\right\}\]

如果您希望求解的方程已经等于 0,这将特别有用。您可以使用 solveset(expr, x) 而不是键入 solveset(Eq(expr, 0), x)

代数求解方程

求解代数方程的主要函数是 solvesetsolveset 的语法是 solveset(equation, variable=None, domain=S.Complexes) 其中方程可以是 Eq 实例或假定为零的表达式的形式。

请注意,还有另一个称为 solve 的函数,它也可用于求解方程。语法是 solve(equations, variables) 但是,建议使用 solveset 代替。

当求解单个方程时,solveset 的输出是一个 FiniteSet 或一个 IntervalImageSet

solveset(x**2 - x, x)
\[\displaystyle \left\{0, 1\right\}\]
solveset(x - x, x, domain=S.Reals)
\[\displaystyle \mathbb{R}\]
solveset(sin(x) - 1, x, domain=S.Reals)
\[\displaystyle \left\{2 n \pi + \frac{\pi}{2}\; \middle|\; n \in \mathbb{Z}\right\}\]

如果没有解,则返回 EmptySet,如果无法找到解,则返回 ConditionSet

solveset(exp(x), x)     # No solution exists
\[\displaystyle \emptyset\]
solveset(cos(x) - x, x)  # Not able to find solution
\[\displaystyle \left\{x\; \middle|\; x \in \mathbb{C} \wedge - x + \cos{\left(x \right)} = 0 \right\}\]

solveset 模块中,线性方程组使用 linsolve 求解。将来我们将能够直接从 solveset 中使用 linsolve。以下是 linsolve 的语法示例。

  • 方程列表形式:

linsolve([x + y + z - 1, x + y + 2*z - 3 ], (x, y, z))
\[\displaystyle \left\{\left( - y - 1, \ y, \ 2\right)\right\}\]
  • 增广矩阵形式:

linsolve(Matrix(([1, 1, 1, 1], [1, 1, 2, 3])), (x, y, z))
\[\displaystyle \left\{\left( - y - 1, \ y, \ 2\right)\right\}\]
  • \(Ax = b\) 形式:

M = Matrix(((1, 1, 1, 1), (1, 1, 2, 3)))
system = A, b = M[:, :-1], M[:, -1]
linsolve(system, x, y, z)
\[\displaystyle \left\{\left( - y - 1, \ y, \ 2\right)\right\}\]

solveset 模块中,非线性方程组使用 nonlinsolve 求解。 以下是 nonlinsolve 的示例。

  • 当只有实数的解时:

a, b, c, d = symbols('a, b, c, d', real=True)
nonlinsolve([a**2 + a, a - b], [a, b])
\[\displaystyle \left\{\left( -1, \ -1\right), \left( 0, \ 0\right)\right\}\]
nonlinsolve([x*y - 1, x - 2], x, y)
\[\displaystyle \left\{\left( 2, \ \frac{1}{2}\right)\right\}\]
  • 当只有复数的解时:

 nonlinsolve([x**2 + 1, y**2 + 1], [x, y])
\[\displaystyle \left\{\left( - i, \ - i\right), \left( - i, \ i\right), \left( i, \ - i\right), \left( i, \ i\right)\right\}\]
  • 当实解和复解都存在时

system = [x**2 - 2*y**2 -2, x*y - 2]
vars = [x, y]
nonlinsolve(system, vars)
\[\displaystyle \left\{\left( -2, \ -1\right), \left( 2, \ 1\right), \left( - \sqrt{2} i, \ \sqrt{2} i\right), \left( \sqrt{2} i, \ - \sqrt{2} i\right)\right\}\]
system = [exp(x) - sin(y), 1/y - 3]
nonlinsolve(system, vars)
\[\displaystyle \left\{\left( \left\{2 n i \pi + \log{\left(\sin{\left(\frac{1}{3} \right)} \right)}\; \middle|\; n \in \mathbb{Z}\right\}, \ \frac{1}{3}\right)\right\}\]
  • 当系统是正维系统时(有无穷多个解):

nonlinsolve([x*y, x*y - x], [x, y])
\[\displaystyle \left\{\left( 0, \ y\right)\right\}\]
system = [a**2 + a*c, a - b]
nonlinsolve(system, [a, b])
\[\displaystyle \left\{\left( 0, \ 0\right), \left( - c, \ - c\right)\right\}\]

如果存在以 LambertW 形式存在的解,则:

solve([x**2 - y**2/exp(x)], [x, y], dict=True)
\[\displaystyle \left[ \left\{ x : 2 W\left(- \frac{y}{2}\right)\right\}, \ \left\{ x : 2 W\left(\frac{y}{2}\right)\right\}\right]\]
solve(x*exp(x) - 1, x )
\[\displaystyle \left[ W\left(1\right)\right]\]

三角方程式使用 solve

solve([sin(x + y), cos(x - y)], [x, y])
\[\displaystyle \left[ \left( - \frac{3 \pi}{4}, \ \frac{3 \pi}{4}\right), \ \left( - \frac{\pi}{4}, \ \frac{\pi}{4}\right), \ \left( \frac{\pi}{4}, \ \frac{3 \pi}{4}\right), \ \left( \frac{3 \pi}{4}, \ \frac{\pi}{4}\right)\right]\]

solveset 只报告每个解一次。要获得包含多重性的多项式的解,请使用 roots

solveset(x**3 - 6*x**2 + 9*x, x)
\[\displaystyle \left\{0, 3\right\}\]
roots(x**3 - 6*x**2 + 9*x, x)
\[\displaystyle \left\{ 0 : 1, \ 3 : 2\right\}\]

求解微分方程

要求解微分方程,请使用 dsolve。首先,通过将 cls=Function 传递给 symbols 函数来创建一个未定义的函数。

f, g = symbols('f g', cls=Function)

fg 现在是未定义的函数。我们可以调用 f(x),它将代表一个未知函数。

f(x)
\[\displaystyle f{\left(x \right)}\]

\(f(x)\) 的导数也是未计算的。

f(x).diff(x)
\[\displaystyle \frac{d}{d x} f{\left(x \right)}\]

为了表示微分方程 \(f''(x) - 2f'(x) + f(x) = \sin(x)\),我们将使用

diffeq = Eq(f(x).diff(x, x) - 2*f(x).diff(x) + f(x), sin(x))
diffeq
\[\displaystyle f{\left(x \right)} - 2 \frac{d}{d x} f{\left(x \right)} + \frac{d^{2}}{d x^{2}} f{\left(x \right)} = \sin{\left(x \right)}\]

要求解 ODE,请将它和要求解的函数传递给 dsolve

dsolve(diffeq, f(x))
\[\displaystyle f{\left(x \right)} = \left(C_{1} + C_{2} x\right) e^{x} + \frac{\cos{\left(x \right)}}{2}\]

dsolve 返回 Eq 的一个实例。这是因为一般来说,微分方程的解不能显式求解该函数。

dsolve(f(x).diff(x)*(1 - sin(f(x))) - 1, f(x))
\[\displaystyle x - f{\left(x \right)} - \cos{\left(f{\left(x \right)} \right)} = C_{1}\]

来自 dsolve 的解中的任意常数是 C1C2C3 等形式的符号。