解算器#

这个 解算器 SymPy中的模块实现求解方程的方法。

备注

For a beginner-friendly guide focused on solving common types of equations, refer to Solve Equations.

备注

solve() is an older more mature general function for solving many types of equations. solve() has many options and uses different methods internally to determine what type of equations you pass it, so if you know what type of equation you are dealing with you may want to use the newer solveset() which solves univariate equations, linsolve() which solves system of linear equations, and nonlinsolve() which solves systems of non linear equations.

代数方程#

使用 solve() 解代数方程。我们假设所有的方程都等于0,所以求解x**2==1将转换为以下代码:

>>> from sympy.solvers import solve
>>> from sympy import Symbol
>>> x = Symbol('x')
>>> solve(x**2 - 1, x)
[-1, 1]

第一个论点 solve() 是一个方程(等于零),第二个参数是我们要解方程的符号。

sympy.solvers.solvers.solve(f, *symbols, **flags)[源代码]#

代数解方程和方程组。

参数:

f :

  • 必须为零的单个表达式或多边形

  • 平等

  • 关系表达式

  • 布尔值

  • 上述一种或多种的

符号 :(要求解的对象)指定为

  • 未给定(将使用其他非数字对象)

  • 单一符号

  • 符号列表(例如。, solve(f, x, y)

  • 符号的有序iterable(例如。, solve(f, [x, y])

旗帜:

dict=True(默认值为False)

解决方案映射的返回列表(可能为空)。

set=True(默认值为False)

返回符号列表和解决方案的元组集。

排除=[](默认)

不要试图求解exclude中的任何自由符号;如果给出了表达式,则会自动提取其中的自由符号。

check=真(默认)

如果错误,不要对解决方案进行任何测试。如果您想要包含使任何分母为零的解决方案,这将非常有用。

数值=真(默认)

如果 f 只有一个符号。

最小值=真(默认值为False)

一个非常快速,最小的测试。

warn=True(默认值为False)

显示警告,如果 checksol() 无法得出结论。

简化=真(默认)

除3阶或更高阶多项式外,在返回它们之前,对它们进行简化,并且(如果检查不为假)对解和将它们替换为应为零的函数时得到的表达式使用一般简化函数。

力=真(默认值为假)

在不假设符号的情况下,使所有符号为正。

有理=真(默认)

重新计算float为Rational;如果不使用此选项,则包含float的系统可能由于poly的问题而无法解决。如果rational=None,float将被重新计算为有理数,但答案将被重新计算为float。如果标志为False,则不会对浮点执行任何操作。

手动=真(默认为假)

不要使用多边形/矩阵方法求解方程组,一次求解一个方程组,就像“手动”一样

隐式=True(默认为False)

允许 solve 根据包含该模式的其他函数返回一个模式的解;只有当模式位于某个可逆函数(如cos、exp等)的内部时,才需要这样做。

特定值=真(默认值为False)

指导 solve 试图找到一个具有尽可能多的零的线性系统的特殊解,这是非常昂贵的。

quick=True (default is False; particular must be True)

Selects a fast heuristic to find a solution with many zeros whereas a value of False uses the very slow method guaranteed to find the largest number of zeros possible.

立方体=真(默认)

Return explicit solutions when cubic expressions are encountered. When False, quartics and quintics are disabled, too.

四次函数=真(默认)

Return explicit solutions when quartic expressions are encountered. When False, quintics are disabled, too.

五次=真(默认)

当遇到五次表达式时返回显式解(如果可能)。

解释

当前支持:
  • 多项式的

  • 超验的

  • 以上各项的分段组合

  • 线性和多项式方程组

  • 包含关系表达式的系统

  • systems implied by undetermined coefficients

实例

The default output varies according to the input and might be a list (possibly empty), a dictionary, a list of dictionaries or tuples, or an expression involving relationals. For specifics regarding different forms of output that may appear, see Solve Output by Type. Let it suffice here to say that to obtain a uniform output from \(solve\) use dict=True or set=True (see below).

>>> from sympy import solve, Poly, Eq, Matrix, Symbol
>>> from sympy.abc import x, y, z, a, b

The expressions that are passed can be Expr, Equality, or Poly classes (or lists of the same); a Matrix is considered to be a list of all the elements of the matrix:

>>> solve(x - 3, x)
[3]
>>> solve(Eq(x, 3), x)
[3]
>>> solve(Poly(x - 3), x)
[3]
>>> solve(Matrix([[x, x + y]]), x, y) == solve([x, x + y], x, y)
True

If no symbols are indicated to be of interest and the equation is univariate, a list of values is returned; otherwise, the keys in a dictionary will indicate which (of all the variables used in the expression(s)) variables and solutions were found:

>>> solve(x**2 - 4)
[-2, 2]
>>> solve((x - a)*(y - b))
[{a: x}, {b: y}]
>>> solve([x - 3, y - 1])
{x: 3, y: 1}
>>> solve([x - 3, y**2 - 1])
[{x: 3, y: -1}, {x: 3, y: 1}]

If you pass symbols for which solutions are sought, the output will vary depending on the number of symbols you passed, whether you are passing a list of expressions or not, and whether a linear system was solved. Uniform output is attained by using dict=True or set=True.

>>> #### *** feel free to skip to the stars below *** ####
>>> from sympy import TableForm
>>> h = [None, ';|;'.join(['e', 's', 'solve(e, s)', 'solve(e, s, dict=True)',
... 'solve(e, s, set=True)']).split(';')]
>>> t = []
>>> for e, s in [
...         (x - y, y),
...         (x - y, [x, y]),
...         (x**2 - y, [x, y]),
...         ([x - 3, y -1], [x, y]),
...         ]:
...     how = [{}, dict(dict=True), dict(set=True)]
...     res = [solve(e, s, **f) for f in how]
...     t.append([e, '|', s, '|'] + [res[0], '|', res[1], '|', res[2]])
...
>>> # ******************************************************* #
>>> TableForm(t, headings=h, alignments="<")
e              | s      | solve(e, s)  | solve(e, s, dict=True) | solve(e, s, set=True)
---------------------------------------------------------------------------------------
x - y          | y      | [x]          | [{y: x}]               | ([y], {(x,)})
x - y          | [x, y] | [(y, y)]     | [{x: y}]               | ([x, y], {(y, y)})
x**2 - y       | [x, y] | [(x, x**2)]  | [{y: x**2}]            | ([x, y], {(x, x**2)})
[x - 3, y - 1] | [x, y] | {x: 3, y: 1} | [{x: 3, y: 1}]         | ([x, y], {(3, 1)})
  • 如果任何方程不依赖于给定的符号,它将从方程组中消除,并且可以根据不感兴趣的变量隐式给出答案:

    >>> solve([x - y, y - 3], x)
    {x: y}
    

When you pass all but one of the free symbols, an attempt is made to find a single solution based on the method of undetermined coefficients. If it succeeds, a dictionary of values is returned. If you want an algebraic solutions for one or more of the symbols, pass the expression to be solved in a list:

>>> e = a*x + b - 2*x - 3
>>> solve(e, [a, b])
{a: 2, b: 3}
>>> solve([e], [a, b])
{a: -b/x + (2*x + 3)/x}

When there is no solution for any given symbol which will make all expressions zero, the empty list is returned (or an empty set in the tuple when set=True):

>>> from sympy import sqrt
>>> solve(3, x)
[]
>>> solve(x - 3, y)
[]
>>> solve(sqrt(x) + 1, x, set=True)
([x], set())

当一个符号以外的对象作为符号给出时,它在代数上是孤立的,并且可以得到一个隐式解。这主要是为了方便您不必用符号替换对象并解决该符号的问题。只有当指定的对象可以使用subs方法替换为符号时,它才有效:

>>> from sympy import exp, Function
>>> f = Function('f')
>>> solve(f(x) - x, f(x))
[x]
>>> solve(f(x).diff(x) - f(x) - x, f(x).diff(x))
[x + f(x)]
>>> solve(f(x).diff(x) - f(x) - x, f(x))
[-x + Derivative(f(x), x)]
>>> solve(x + exp(x)**2, exp(x), set=True)
([exp(x)], {(-sqrt(-x),), (sqrt(-x),)})
>>> from sympy import Indexed, IndexedBase, Tuple
>>> A = IndexedBase('A')
>>> eqs = Tuple(A[1] + A[2] - 3, A[1] - A[2] + 1)
>>> solve(eqs, eqs.atoms(Indexed))
{A[1]: 1, A[2]: 2}
  • To solve for a function within a derivative, use dsolve().

要隐式求解符号,请使用implicit=True:

>>> solve(x + exp(x), x)
[-LambertW(1)]
>>> solve(x + exp(x), x, implicit=True)
[-exp(x)]

It is possible to solve for anything in an expression that can be replaced with a symbol using subs:

>>> solve(x + 2 + sqrt(3), x + 2)
[-sqrt(3)]
>>> solve((x + 2 + sqrt(3), x + 4 + y), y, x + 2)
{y: -2 + sqrt(3), x + 2: -sqrt(3)}
  • 在这个隐式解算中没有什么英雄式的表现,所以你可能会得到一个符号仍然在解中:

    >>> eqs = (x*y + 3*y + sqrt(3), x + 4 + y)
    >>> solve(eqs, y, x + 2)
    {y: -sqrt(3)/(x + 3), x + 2: -2*x/(x + 3) - 6/(x + 3) + sqrt(3)/(x + 3)}
    >>> solve(eqs, y*x, x)
    {x: -y - 4, x*y: -3*y - sqrt(3)}
    
  • If you attempt to solve for a number, remember that the number you have obtained does not necessarily mean that the value is equivalent to the expression obtained:

    >>> solve(sqrt(2) - 1, 1)
    [sqrt(2)]
    >>> solve(x - y + 1, 1)  # /!\ -1 is targeted, too
    [x/(y - 1)]
    >>> [_.subs(z, -1) for _ in solve((x - y + 1).subs(-1, z), 1)]
    [-x + y]
    

其他示例

solve() with check=True (default) will run through the symbol tags to eliminate unwanted solutions. If no assumptions are included, all possible solutions will be returned:

>>> x = Symbol("x")
>>> solve(x**2 - 1)
[-1, 1]

By setting the positive flag, only one solution will be returned:

>>> pos = Symbol("pos", positive=True)
>>> solve(pos**2 - 1)
[1]

当检查解决方案时,那些使任何分母为零的都会自动排除。如果不想排除此类解决方案,请使用check=False选项:

>>> from sympy import sin, limit
>>> solve(sin(x)/x)  # 0 is excluded
[pi]

If check=False, then a solution to the numerator being zero is found but the value of \(x = 0\) is a spurious solution since \(\sin(x)/x\) has the well known limit (without discontinuity) of 1 at \(x = 0\):

>>> solve(sin(x)/x, check=False)
[0, pi]

In the following case, however, the limit exists and is equal to the value of \(x = 0\) that is excluded when check=True:

>>> eq = x**2*(1/x - z**2/x)
>>> solve(eq, x)
[]
>>> solve(eq, x, check=False)
[0]
>>> limit(eq, x, 0, '-')
0
>>> limit(eq, x, 0, '+')
0

Solving Relationships

When one or more expressions passed to solve is a relational, a relational result is returned (and the dict and set flags are ignored):

>>> solve(x < 3)
(-oo < x) & (x < 3)
>>> solve([x < 3, x**2 > 4], x)
((-oo < x) & (x < -2)) | ((2 < x) & (x < 3))
>>> solve([x + y - 3, x > 3], x)
(3 < x) & (x < oo) & Eq(x, 3 - y)

Although checking of assumptions on symbols in relationals is not done, setting assumptions will affect how certain relationals might automatically simplify:

>>> solve(x**2 > 4)
((-oo < x) & (x < -2)) | ((2 < x) & (x < oo))
>>> r = Symbol('r', real=True)
>>> solve(r**2 > 4)
(2 < r) | (r < -2)

There is currently no algorithm in SymPy that allows you to use relationships to resolve more than one variable. So the following does not determine that q < 0 (and trying to solve for r and q will raise an error):

>>> from sympy import symbols
>>> r, q = symbols('r, q', real=True)
>>> solve([r + q - 3, r > 3], r)
(3 < r) & Eq(r, 3 - q)

You can directly call the routine that solve calls when it encounters a relational: reduce_inequalities(). It treats Expr like Equality.

>>> from sympy import reduce_inequalities
>>> reduce_inequalities([x**2 - 4])
Eq(x, -2) | Eq(x, 2)

If each relationship contains only one symbol of interest, the expressions can be processed for multiple symbols:

>>> reduce_inequalities([0 <= x  - 1, y < 3], [x, y])
(-oo < y) & (1 <= x) & (x < oo) & (y < 3)

But an error is raised if any relationship has more than one symbol of interest:

>>> reduce_inequalities([0 <= x*y  - 1, y < 3], [x, y])
Traceback (most recent call last):
...
NotImplementedError:
inequality has more than one symbol of interest.

Disabling High-Order Explicit Solutions

在求解多项式表达式时,您可能不需要显式的解(可能会很长)。如果表达式是单变量的, CRootOf 将返回实例:

>>> solve(x**3 - x + 1)
[-1/((-1/2 - sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)) -
(-1/2 - sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)/3,
-(-1/2 + sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)/3 -
1/((-1/2 + sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)),
-(3*sqrt(69)/2 + 27/2)**(1/3)/3 -
1/(3*sqrt(69)/2 + 27/2)**(1/3)]
>>> solve(x**3 - x + 1, cubics=False)
[CRootOf(x**3 - x + 1, 0),
 CRootOf(x**3 - x + 1, 1),
 CRootOf(x**3 - x + 1, 2)]

如果表达式是多变量的,则可能不会返回任何解:

>>> solve(x**3 - x + a, x, cubics=False)
[]

有时甚至当一个标志为False时,也会获得解,因为表达式可以被分解。在下面的例子中,可以将方程分解为线性因子和二次因子的乘积,从而获得显式解(不需要求解立方表达式):

>>> eq = x**3 + 3*x**2 + x - 1
>>> solve(eq, cubics=False)
[-1, -1 + sqrt(2), -sqrt(2) - 1]

求解含根的方程

由于SymPy使用了原理根,一些根方程的解将丢失,除非check=False:

>>> from sympy import root
>>> eq = root(x**3 - 3*x**2, 3) + 1 - x
>>> solve(eq)
[]
>>> solve(eq, check=False)
[1/3]

在上面的例子中,方程只有一个解。其他表达式将产生伪根,必须手动检查;给奇数幂根提供负参数的根也需要特殊检查:

>>> from sympy import real_root, S
>>> eq = root(x, 3) - root(x, 5) + S(1)/7
>>> solve(eq)  # this gives 2 solutions but misses a 3rd
[CRootOf(7*x**5 - 7*x**3 + 1, 1)**15,
CRootOf(7*x**5 - 7*x**3 + 1, 2)**15]
>>> sol = solve(eq, check=False)
>>> [abs(eq.subs(x,i).n(2)) for i in sol]
[0.48, 0.e-110, 0.e-110, 0.052, 0.052]

第一个解是否定的所以 real_root 必须用于确保它满足表达式:

>>> abs(real_root(eq.subs(x, sol[0])).n(2))
0.e-110

如果方程的根不是实的,则需要更仔细地寻找根,特别是对于高阶方程。考虑以下表达式:

>>> expr = root(x, 3) - root(x, 5)

我们将在x=3处为这个表达式构造一个已知值,方法是为每个根号选择第1个根:

>>> expr1 = root(x, 3, 1) - root(x, 5, 1)
>>> v = expr1.subs(x, -3)

这个 solve 函数找不到此方程的精确根:

>>> eq = Eq(expr, v); eq1 = Eq(expr1, v)
>>> solve(eq, check=False), solve(eq1, check=False)
([], [])

函数 unrad ,但是,可以用来得到方程的一种形式,其中可以找到数值根:

>>> from sympy.solvers.solvers import unrad
>>> from sympy import nroots
>>> e, (p, cov) = unrad(eq)
>>> pvals = nroots(e)
>>> inversion = solve(cov, x)[0]
>>> xvals = [inversion.subs(p, i) for i in pvals]

虽然 eqeq1 可能是用来找的 xvals ,解决方案只能用 expr1

>>> z = expr - v
>>> [xi.n(chop=1e-9) for xi in xvals if abs(z.subs(x, xi).n()) < 1e-9]
[]
>>> z1 = expr1 - v
>>> [xi.n(chop=1e-9) for xi in xvals if abs(z1.subs(x, xi).n()) < 1e-9]
[-3.0]

参见

rsolve

用于解决递归关系

dsolve

用于解微分方程

sympy.solvers.solvers.solve_linear(lhs, rhs=0, symbols=[], exclude=[])[源代码]#

返回派生自的元组 f = lhs - rhs 这是下列情况之一: (0, 1)(0, 0)(symbol, solution)(n, d) .

解释

(0, 1) 意思是 f 与中的符号无关 符号 那不在 排除 .

(0, 0) 这意味着在给定的符号之间没有方程的解。如果元组的第一个元素不为零,则保证函数依赖于中的符号 符号 .

(symbol, solution) 其中符号以线性形式出现在 f ,在中 符号 (如有),且不在 排除 (如有)。没有简化 f 除了 mul=True 因此,解将严格对应于唯一解。

(n, d) 在哪里? nd 分子和分母是 f 分子在任何感兴趣的符号中都不是线性的; n 永远不会是一个符号,除非找到该符号的解(在这种情况下,第二个元素是解,而不是分母)。

实例

>>> from sympy import cancel, Pow

f 与中的符号无关 符号 那不在 排除

>>> from sympy import cos, sin, solve_linear
>>> from sympy.abc import x, y, z
>>> eq = y*cos(x)**2 + y*sin(x)**2 - y  # = y*(1 - 1) = 0
>>> solve_linear(eq)
(0, 1)
>>> eq = cos(x)**2 + sin(x)**2  # = 1
>>> solve_linear(eq)
(0, 1)
>>> solve_linear(x, exclude=[x])
(0, 1)

变量 x 在以下各项中显示为线性变量:

>>> solve_linear(x + y**2)
(x, -y**2)
>>> solve_linear(1/x - y**2)
(x, y**(-2))

当不是线性时 xy 然后返回分子和分母:

>>> solve_linear(x**2/y**2 - 3)
(x**2 - 3*y**2, y**2)

如果表达式的分子是符号,则 (0, 0) 如果该符号的解决方案将任何分母设置为0,则返回:

>>> eq = 1/(1/x - 2)
>>> eq.as_numer_denom()
(x, 1 - 2*x)
>>> solve_linear(eq)
(0, 0)

但自动重写可能会导致分母中的符号出现在分子中,因此将返回解决方案:

>>> (1/x)**-1
x
>>> solve_linear((1/x)**-1)
(x, 0)

请使用未赋值的表达式来避免这种情况:

>>> solve_linear(Pow(1/x, -1, evaluate=False))
(0, 0)

如果 x 在以下表达式中允许取消,则它在中显示为线性 x ,但这种取消不是由 solve_linear 因此,解始终满足原始表达式,而不会导致零除误差。

>>> eq = x**2*(1/x - z**2/x)
>>> solve_linear(cancel(eq))
(x, 0)
>>> solve_linear(eq)
(x**2*(1 - z**2), x)

可给出需要解决方案的符号列表:

>>> solve_linear(x + y + z, symbols=[y])
(y, -x - z)

还可以给出要忽略的符号列表:

>>> solve_linear(x + y + z, exclude=[x])
(y, -x - z)

(解决方案 y 因为它是具有线性解的符号的规范排序列表中的第一个变量。)

sympy.solvers.solvers.solve_linear_system(system, *symbols, **flags)[源代码]#

求解具有\(M\)变量的\(N\)线性方程组,这意味着同时支持欠定和超定系统。

解释

可能的解的数目是零、一或无限。此过程将分别返回None或包含解决方案的字典。在欠定系统的情况下,跳过所有的任意参数。这可能会导致返回空字典的情况。在这种情况下,可以为所有符号指定任意值。

在形式上,\(M是一个函数,它是一个被增广的矩阵。如果您喜欢输入\)N\(方程式和\)M$未知项,则使用 solve(Neqs, *Msymbols) 相反。注意:此例程将生成矩阵的本地副本,因此传递的矩阵不会被修改。

这里使用的算法是无分数高斯消去法,它在消除后得到一个上三角矩阵。然后用反代换法求出解。这种方法比Gauss-Jordan方法更有效、更紧凑。

实例

>>> from sympy import Matrix, solve_linear_system
>>> from sympy.abc import x, y

解决以下系统:

   x + 4 y ==  2
-2 x +   y == 14
>>> system = Matrix(( (1, 4, 2), (-2, 1, 14)))
>>> solve_linear_system(system, x, y)
{x: -6, y: 2}

退化系统返回空字典:

>>> system = Matrix(( (0,0,0), (0,0,0) ))
>>> solve_linear_system(system, x, y)
{}
sympy.solvers.solvers.solve_linear_system_LU(matrix, syms)[源代码]#

使用 LUsolve 并返回一个字典,在该字典中,解被键控为 syms 按命令。

解释

矩阵必须可逆。

实例

>>> from sympy import Matrix, solve_linear_system_LU
>>> from sympy.abc import x, y, z
>>> solve_linear_system_LU(Matrix([
... [1, 2, 0, 1],
... [3, 2, 2, 1],
... [2, 0, 0, 1]]), [x, y, z])
{x: 1/2, y: 1/4, z: -1/2}

参见

LUsolve

sympy.solvers.solvers.solve_undetermined_coeffs(equ, coeffs, *syms, **flags)[源代码]#

Solve a system of equations in \(k\) parameters that is formed by matching coefficients in variables coeffs that are on factors dependent on the remaining variables (or those given explicitly by syms.

解释

The result of this function is a dictionary with symbolic values of those parameters with respect to coefficients in \(q\) -- empty if there is no solution or coefficients do not appear in the equation -- else None (if the system was not recognized). If there is more than one solution, the solutions are passed as a list. The output can be modified using the same semantics as for \(solve\) since the flags that are passed are sent directly to \(solve\) so, for example the flag dict=True will always return a list of solutions as dictionaries.

This function accepts both Equality and Expr class instances. The solving process is most efficient when symbols are specified in addition to parameters to be determined, but an attempt to determine them (if absent) will be made. If an expected solution is not obtained (and symbols were not specified) try specifying them.

实例

>>> from sympy import Eq, solve_undetermined_coeffs
>>> from sympy.abc import a, b, c, h, p, k, x, y
>>> solve_undetermined_coeffs(Eq(a*x + a + b, x/2), [a, b], x)
{a: 1/2, b: -1/2}
>>> solve_undetermined_coeffs(a - 2, [a])
{a: 2}

The equation can be nonlinear in the symbols:

>>> X, Y, Z = y, x**y, y*x**y
>>> eq = a*X + b*Y + c*Z - X - 2*Y - 3*Z
>>> coeffs = a, b, c
>>> syms = x, y
>>> solve_undetermined_coeffs(eq, coeffs, syms)
{a: 1, b: 2, c: 3}

And the system can be nonlinear in coefficients, too, but if there is only a single solution, it will be returned as a dictionary:

>>> eq = a*x**2 + b*x + c - ((x - h)**2 + 4*p*k)/4/p
>>> solve_undetermined_coeffs(eq, (h, p, k), x)
{h: -b/(2*a), k: (4*a*c - b**2)/(4*a), p: 1/(4*a)}

Multiple solutions are always returned in a list:

>>> solve_undetermined_coeffs(a**2*x + b - x, [a, b], x)
[{a: -1, b: 0}, {a: 1, b: 0}]

Using flag dict=True (in keeping with semantics in solve()) will force the result to always be a list with any solutions as elements in that list.

>>> solve_undetermined_coeffs(a*x - 2*x, [a], dict=True)
[{a: 2}]
sympy.solvers.solvers.nsolve(*args, dict=False, **kwargs)[源代码]#

数值求解非线性方程组: nsolve(f, [args,] x0, modules=['mpmath'], **kwargs) .

解释

f 是表示系统的符号表达式的向量函数。 args 是变量。如果只有一个变量,则可以省略此参数。 x0 是接近解的起始向量。

使用modules关键字指定应使用哪些模块来计算函数和雅可比矩阵。确保使用支持矩阵的模块。有关语法的详细信息,请参见的docstring lambdify .

如果关键字参数包含 dict=True (默认值为False) nsolve 将返回解决方案映射的列表(可能为空)。如果您想使用 nsolve 作为一个后备解决方案,因为对两个方法使用dict参数都会产生一致类型结构的返回值。请注意:为了保持与 solve ,解决方案将在列表中返回,即使 nsolve (至少目前)一次只能找到一个解决方案。

支持超定系统。

实例

>>> from sympy import Symbol, nsolve
>>> import mpmath
>>> mpmath.mp.dps = 15
>>> x1 = Symbol('x1')
>>> x2 = Symbol('x2')
>>> f1 = 3 * x1**2 - 2 * x2**2 - 1
>>> f2 = x1**2 - 2 * x1 + x2**2 + 2 * x2 - 8
>>> print(nsolve((f1, f2), (x1, x2), (-1, 1)))
Matrix([[-1.19287309935246], [1.27844411169911]])

对于一维函数,语法被简化:

>>> from sympy import sin, nsolve
>>> from sympy.abc import x
>>> nsolve(sin(x), x, 2)
3.14159265358979
>>> nsolve(sin(x), 2)
3.14159265358979

要以比默认值更高的精度进行求解,请使用prec参数:

>>> from sympy import cos
>>> nsolve(cos(x) - x, 1)
0.739085133215161
>>> nsolve(cos(x) - x, 1, prec=50)
0.73908513321516064165531208767387340401341175890076
>>> cos(_)
0.73908513321516064165531208767387340401341175890076

要求解实函数的复根,必须指定非回复初始点:

>>> from sympy import I
>>> nsolve(x**2 + 2, I)
1.4142135623731*I

mpmath.findroot ,您可以找到它们更广泛的文档,特别是有关关键字参数和可用解算器的文档。但是,请注意,在根附近非常陡峭的函数,解决方案的验证可能会失败。在这种情况下,您应该使用标志 verify=False 并独立验证解决方案。

>>> from sympy import cos, cosh
>>> f = cos(x)*cosh(x) - 1
>>> nsolve(f, 3.14*100)
Traceback (most recent call last):
...
ValueError: Could not find root within given tolerance. (1.39267e+230 > 2.1684e-19)
>>> ans = nsolve(f, 3.14*100, verify=False); ans
312.588469032184
>>> f.subs(x, ans).n(2)
2.1e+121
>>> (f/f.diff(x)).subs(x, ans).n(2)
7.4e-15

如果知道根的边界并且使用了对分方法,则可以安全地跳过验证:

>>> bounds = lambda i: (3.14*i, 3.14*(i + 1))
>>> nsolve(f, bounds(100), solver='bisect', verify=False)
315.730061685774

或者,当忽略分母时,函数可能表现得更好。然而,由于情况并非总是如此,因此使用什么功能的决定权由用户自行决定。

>>> eq = x**2/(1 - x)/(1 - 2*x)**2 - 100
>>> nsolve(eq, 0.46)
Traceback (most recent call last):
...
ValueError: Could not find root within given tolerance. (10000 > 2.1684e-19)
Try another starting point or tweak arguments.
>>> nsolve(eq.as_numer_denom()[0], 0.46)
0.46792545969349058
sympy.solvers.solvers.checksol(f, symbol, sol=None, **flags)[源代码]#

检查sol是否是方程f==0的解。

解释

输入可以是单个符号和相应的值,也可以是符号和值的字典。作为字典和旗帜 simplify=True ,字典中的值将被简化。 f 可以是一个方程,也可以是一组方程。一个解必须满足 f 被认为是有效的;如果一个解不满足任何等式,则返回False;如果一个或多个检查没有结果(并且没有一个是False),则不返回任何一个。

实例

>>> from sympy import checksol, symbols
>>> x, y = symbols('x,y')
>>> checksol(x**4 - 1, x, 1)
True
>>> checksol(x**4 - 1, x, 0)
False
>>> checksol(x**2 + y**2 - 5**2, {x: 3, y: 4})
True

使用检查表达式是否为零 checksol() ,作为 f 寄一本空字典 符号

>>> checksol(x**2 + x - x*(x + 1), {})
True

如果没有返回,则 checksol() 无法得出结论。

旗帜:
'数值=真(默认)'

快速数值检查 f 只有一个符号。

'最小值=真(默认值为False)'

一个非常快速,最小的测试。

'warn=True(默认值为False)'

如果checksol()无法结束,则显示警告。

'简化=真(默认)'

在代入函数之前先简化解,在尝试具体的简化之前先简化函数

'力=True(默认值为False)'

在不假设符号的情况下,使所有符号为正。

sympy.solvers.solvers.unrad(eq, *syms, **flags)[源代码]#

删除带有符号参数的部首并返回(eq,cov)、None或引发错误。

解释

如果没有要删除的自由基,则不会返回任何。

如果存在根且无法移除,或无法解决原始符号与将系统重写为多项式所需的变量变化之间的关系,则会引发NotImplementedError。

否则元组, (eq, cov) ,其中:

eqcov

eq 是一个没有根的方程(用符号表示),其解是原始表达式解的超集。 eq 可能会根据新变量重写;与原始变量的关系由 cov 它是一个包含 vv**p - b 在哪里? p 清除激进分子和 b 是现在用多项式表示的根在符号中的意义。例如,对于sqrt(2-x),元组将是 (c, c**2 - 2 + x) . 解决方案 eq 将包含原始方程的解(如果有的话)。

syms

一种符号的集合,如果提供,将限制除根的焦点:只有具有一个或多个感兴趣符号的部首才会被清除。如果出现以下情况,则使用所有自由符号 syms 未设置。

旗帜 在递归调用期间用于内部通信。还有两种选择:

take 定义时,将解释为单参数函数,如果应处理给定的Pow,则返回True。

在下列情况下,可以从表达式中删除部首:

  • 根式的所有基都是相同的;在这种情况下,变量发生了变化。

  • 如果所有的部首都出现在表达式的一个术语中。

  • 只有四个带有sqrt()因子的项,或者少于四个具有sqrt()因子的项。

  • 部首只有两个词。

实例

>>> from sympy.solvers.solvers import unrad
>>> from sympy.abc import x
>>> from sympy import sqrt, Rational, root
>>> unrad(sqrt(x)*x**Rational(1, 3) + 2)
(x**5 - 64, [])
>>> unrad(sqrt(x) + root(x + 1, 3))
(-x**3 + x**2 + 2*x + 1, [])
>>> eq = sqrt(x) + root(x, 3) - 2
>>> unrad(eq)
(_p**3 + _p**2 - 2, [_p, _p**6 - x])

常微分方程#

ODE .

偏微分方程#

PDE .

Deutils(用于解决ODE和PDE的实用程序)#

sympy.solvers.deutils.ode_order(expr, func)[源代码]#

对给定阶的微分方程返回。

此函数是递归实现的。

实例

>>> from sympy import Function
>>> from sympy.solvers.deutils import ode_order
>>> from sympy.abc import x
>>> f, g = map(Function, ['f', 'g'])
>>> ode_order(f(x).diff(x, 2) + f(x).diff(x)**2 +
... f(x).diff(x), f(x))
2
>>> ode_order(f(x).diff(x, 2) + g(x).diff(x, 3), f(x))
2
>>> ode_order(f(x).diff(x, 2) + g(x).diff(x, 3), g(x))
3

递推方程#

sympy.solvers.recurr.rsolve(f, y, init=None)[源代码]#

用有理系数求解一元递归问题。

鉴于 \(k\) -四阶线性递归 \(\operatorname{{L}} y = f\) ,或等效:

\[a{k}(n)y(n+k)+a{k-1}(n)y(n+k-1)+\]

在哪里? \(a_{{i}}(n)\) ,为了 \(i=0, \ldots, k\) ,是多项式还是有理函数 \(n\)\(f\) 是一个超几何函数,或是一个固定数目的成对不同的超几何项之和 \(n\) ,查找所有解决方案或返回 None ,如果没有找到。

初始条件可以用两种形式作为字典给出:

  1. {  n_0  : v_0,   n_1  : v_1, ...,   n_m  : v_m}

  2. {y(n_0) : v_0, y(n_1) : v_1, ..., y(n_m) : v_m}

或者作为一个列表 L 价值观:

L = [v_0, v_1, ..., v_m]

在哪里? L[i] = v_i ,为了 \(i=0, \ldots, m\) ,映射到 \(y(n_i)\) .

实例

让我们考虑以下重复:

\[(n-1)y(n+2)-(n^2+3 n-2)y(n+1)+\]
>>> from sympy import Function, rsolve
>>> from sympy.abc import n
>>> y = Function('y')
>>> f = (n - 1)*y(n + 2) - (n**2 + 3*n - 2)*y(n + 1) + 2*n*(n + 1)*y(n)
>>> rsolve(f, y(n))
2**n*C0 + C1*factorial(n)
>>> rsolve(f, y(n), {y(0):0, y(1):3})
3*2**n - 3*factorial(n)
sympy.solvers.recurr.rsolve_poly(coeffs, f, n, shift=0, **hints)[源代码]#

给定线性递归算子 \(\operatorname{{L}}\) 秩序 \(k\) 多项式系数非齐次方程 \(\operatorname{{L}} y = f\) 在哪里 \(f\) 是一个多项式,我们求域上所有的多项式解 \(K\) 特征零点。

该算法执行两个基本步骤:

  1. 计算度 \(N\) 一般多项式解的。

  2. 求所有次多项式 \(N\) 或更少 \(\operatorname{{L}} y = f\) .

There are two methods for computing the polynomial solutions. If the degree bound is relatively small, i.e. it's smaller than or equal to the order of the recurrence, then naive method of undetermined coefficients is being used. This gives a system of algebraic equations with \(N+1\) unknowns.

In the other case, the algorithm performs transformation of the initial equation to an equivalent one for which the system of algebraic equations has only \(r\) indeterminates. This method is quite sophisticated (in comparison with the naive one) and was invented together by Abramov, Bronstein and Petkovsek.

本文所实现的算法可以推广到线性q差分和微分方程的情况。

假设我们想计算 \(m\) -贝努利多项式到常数。为此我们可以使用 \(b(n+1) - b(n) = m n^{{m-1}}\) 递归,有解 \(b(n) = B_m + C\) . 例如:

>>> from sympy import Symbol, rsolve_poly
>>> n = Symbol('n', integer=True)
>>> rsolve_poly([-1, 1], 4*n**3, n)
C0 + n**4 - 2*n**3 + n**2

工具书类

[R890]

S、 A.Abramov,M.Bronstein和M.Petkovsek,关于线性算子方程的多项式解,载:T.Levelt,ed.,Proc。ISSAC’95,ACM出版社,纽约,1995年,290-296。

[R891]

M、 周国平,周立波,周立波,周立波,周立波,周立波,周立波,周立波,周立波,周立波,周立波。

[R892]
  1. Petkovsek,H.S.Wilf,D.Zeilberger,A=B,1996年。

sympy.solvers.recurr.rsolve_ratio(coeffs, f, n, **hints)[源代码]#

给定线性递归算子 \(\operatorname{{L}}\) 秩序 \(k\) 多项式系数非齐次方程 \(\operatorname{{L}} y = f\) 在哪里 \(f\) 是一个多项式,我们寻求域上所有有理解 \(K\) 特征零点。

此过程只接受多项式,但是如果您对用有理系数求解递归感兴趣,则使用 rsolve 它将预处理给定的方程并用多项式参数运行此过程。

该算法执行两个基本步骤:

  1. 计算多项式 \(v(n)\) 它可以作为方程的任何有理解的公分母 \(\operatorname{{L}} y = f\) .

  2. 用代换法构造新的线性差分方程 \(y(n) = u(n)/v(n)\) 然后解决它 \(u(n)\) 找到所有的多项式解。返回 None 如果没有找到。

The algorithm implemented here is a revised version of the original Abramov's algorithm, developed in 1989. The new approach is much simpler to implement and has better overall efficiency. This method can be easily adapted to the q-difference equations case.

Besides finding rational solutions alone, this functions is an important part of Hyper algorithm where it is used to find a particular solution for the inhomogeneous part of a recurrence.

实例

>>> from sympy.abc import x
>>> from sympy.solvers.recurr import rsolve_ratio
>>> rsolve_ratio([-2*x**3 + x**2 + 2*x - 1, 2*x**3 + x**2 - 6*x,
... - 2*x**3 - 11*x**2 - 18*x - 9, 2*x**3 + 13*x**2 + 22*x + 8], 0, x)
C0*(2*x - 3)/(2*(x**2 - 1))

参见

rsolve_hyper

工具书类

[R893]

S、 A.阿布拉莫夫,多项式系数线性差分方程和q-差分方程的有理解,载:T.Levelt,ed.,Proc。ISSAC’95,ACM出版社,纽约,1995年,285-289年

sympy.solvers.recurr.rsolve_hyper(coeffs, f, n, **hints)[源代码]#

给定线性递归算子 \(\operatorname{{L}}\) 秩序 \(k\) 多项式系数非齐次方程 \(\operatorname{{L}} y = f\) 我们寻求场上所有的超几何解 \(K\) 特征零点。

非均匀部分可以是超几何的,也可以是固定数量的成对不同的超几何项之和。

该算法执行三个基本步骤:

  1. 将相似的超几何项组合在 \(\operatorname{{L}} y = f\) 并用Abramov算法求出具体解。

  2. 计算发电机组 \(\operatorname{{L}}\) 并在此基础上求其基,使所有解线性无关。

  3. 用任意常数的个数等于基的维数形成最终解 \(\operatorname{{L}}\) .

术语 \(a(n)\) 如果它被多项式系数的一阶线性差分方程湮没,或者,简单地说,如果连续项比率是有理函数,则它是超几何的。

这个过程的输出是固定数目的超几何项的线性组合。然而,底层方法可以生成更大类的解-D'Alembertian项。

还应注意的是,这种方法不仅计算非齐次方程的核,而且还将其简化为一个基,从而使该过程产生的解是线性无关的

实例

>>> from sympy.solvers import rsolve_hyper
>>> from sympy.abc import x
>>> rsolve_hyper([-1, -1, 1], 0, x)
C0*(1/2 - sqrt(5)/2)**x + C1*(1/2 + sqrt(5)/2)**x
>>> rsolve_hyper([-1, 1], 1 + x, x)
C0 + x*(x + 1)/2

工具书类

[R894]

M、 周国平,周立波,周立波,周立波,周立波,周立波,周立波,周立波,周立波,周立波,周立波。

[R895]
  1. Petkovsek,H.S.Wilf,D.Zeilberger,A=B,1996年。

多项式方程组#

sympy.solvers.polysys.solve_poly_system(seq, *gens, strict=False, **args)[源代码]#

Return a list of solutions for the system of polynomial equations or else None.

参数:

seq: a list/tuple/set

列出所有需要求解的方程

gens:生成器

我们想要解的seq方程的生成器

strict: a boolean (default is False)

if strict is True, NotImplementedError will be raised if the solution is known to be incomplete (which can occur if not all solutions are expressible in radicals)

args:关键字参数

Special options for solving the equations.

返回:

表 [元组]

a list of tuples with elements being solutions for the symbols in the order they were passed as gens

没有

None is returned when the computed basis contains only the ground.

实例

>>> from sympy import solve_poly_system
>>> from sympy.abc import x, y
>>> solve_poly_system([x*y - 2*y, 2*y**2 - x**2], x, y)
[(0, 0), (2, -sqrt(2)), (2, sqrt(2))]
>>> solve_poly_system([x**5 - x + y**3, y**2 - 1], x, y, strict=True)
Traceback (most recent call last):
...
UnsolvableFactorError
sympy.solvers.polysys.solve_triangulated(polys, *gens, **args)[源代码]#

用Gianni-Kalkbrenner算法求解多项式系统。

该算法首先在地域中计算一个Groebner基,然后在适当构造的地域代数扩张中迭代计算多项式因式分解。

参数:

polys: a list/tuple/set

列出所有需要求解的方程

gens:生成器

我们想要解的多边形方程的生成元

args:关键字参数

求解方程的特殊选项

返回:

表 [元组]

元组列表。满足polys中所列方程的符号的解

实例

>>> from sympy import solve_triangulated
>>> from sympy.abc import x, y, z
>>> F = [x**2 + y + z - 1, x + y**2 + z - 1, x + y + z**2 - 1]
>>> solve_triangulated(F, x, y, z)
[(0, 0, 1), (0, 1, 0), (1, 0, 0)]

工具书类

1陈国平,陈国平,陈国华,应用代数中多项式方程组的代数解法,应用代数的AAECC-5,代数算法与纠错码,LNCS 356 247--2571989

丢番图方程#

丢番图

不平等#

不等式解算器

Linear Programming (Optimization)#

sympy.solvers.simplex.lpmax(f, constr)[源代码]#

return maximum of linear equation f under linear constraints expressed using Ge, Le or Eq.

All variables are unbounded unless constrained.

实例

>>> from sympy.solvers.simplex import lpmax
>>> from sympy import Eq
>>> from sympy.abc import x, y
>>> lpmax(x, [2*x - 3*y >= -1, Eq(x+ 3*y,2), x <= 2*y])
(4/5, {x: 4/5, y: 2/5})

Negative values for variables are permitted unless explicitly exluding:

>>> lpmax(x, [x <= -1])
(-1, {x: -1})

If a non-negative constraint is added for x, there is no possible solution:

>>> lpmax(x, [x <= -1, x >= 0])
Traceback (most recent call last):
...
sympy.solvers.simplex.InfeasibleLPError: inconsistent/False constraint

参见

linprog, lpmin

sympy.solvers.simplex.lpmin(f, constr)[源代码]#

return minimum of linear equation f under linear constraints expressed using Ge, Le or Eq.

All variables are unbounded unless constrained.

实例

>>> from sympy.solvers.simplex import lpmin
>>> from sympy import Eq
>>> from sympy.abc import x, y
>>> lpmin(x, [2*x - 3*y >= -1, Eq(x + 3*y, 2), x <= 2*y])
(1/3, {x: 1/3, y: 5/9})

Negative values for variables are permitted unless explicitly exluding, so minimizing x for x <= 3 is an unbounded problem while the following has a bounded solution:

>>> lpmin(x, [x >= 0, x <= 3])
(0, {x: 0})

Without indicating that x is nonnegative, there is no minimum for this objective:

>>> lpmin(x, [x <= 3])
Traceback (most recent call last):
...
sympy.solvers.simplex.UnboundedLPError:
Objective function can assume arbitrarily large values!

参见

linprog, lpmax

sympy.solvers.simplex.linprog(c, A=None, b=None, A_eq=None, b_eq=None, bounds=None)[源代码]#

Return the minimization of c*x with the given constraints A*x <= b and A_eq*x = b_eq. Unless bounds are given, variables will have nonnegative values in the solution.

If A is not given, then the dimension of the system will be determined by the length of C.

By default, all variables will be nonnegative. If bounds is given as a single tuple, (lo, hi), then all variables will be constrained to be between lo and hi. Use None for a lo or hi if it is unconstrained in the negative or positive direction, respectively, e.g. (None, 0) indicates nonpositive values. To set individual ranges, pass a list with length equal to the number of columns in A, each element being a tuple; if only a few variables take on non-default values they can be passed as a dictionary with keys giving the corresponding column to which the variable is assigned, e.g. bounds={2: (1, 4)} would limit the 3rd variable to have a value in range [1, 4].

实例

>>> from sympy.solvers.simplex import linprog
>>> from sympy import symbols, Eq, linear_eq_to_matrix as M, Matrix
>>> x = x1, x2, x3, x4 = symbols('x1:5')
>>> X = Matrix(x)
>>> c, d = M(5*x2 + x3 + 4*x4 - x1, x)
>>> a, b = M([5*x2 + 2*x3 + 5*x4 - (x1 + 5)], x)
>>> aeq, beq = M([Eq(3*x2 + x4, 2), Eq(-x1 + x3 + 2*x4, 1)], x)
>>> constr = [i <= j for i,j in zip(a*X, b)]
>>> constr += [Eq(i, j) for i,j in zip(aeq*X, beq)]
>>> linprog(c, a, b, aeq, beq)
(9/2, [0, 1/2, 0, 1/2])
>>> assert all(i.subs(dict(zip(x, _[1]))) for i in constr)

参见

lpmin, lpmax