ODE#
备注
For a beginner-friendly guide focused on solving ODEs, refer to Solve an Ordinary Differential Equation (ODE) Algebraically.
用户功能#
这些函数是通过 from sympy import *
. 这些功能(不像 Hint Functions ,以下)仅供SymPy的普通用户使用。
- sympy.solvers.ode.dsolve(eq, func=None, hint='default', simplify=True, ics=None, xi=None, eta=None, x0=0, n=6, **kwargs)[源代码]#
解任何一类(支持的)常微分方程和常微分方程组。
一阶常微分方程
当方程的个数
eq
是一个。 使用dsolve(eq, f(x), hint)
->解常微分方程eq
功能f(x)
,使用方法hint
.Details
eq
可以是任何支持的常微分方程(请参见f(x)
是一个变量的函数,其导数variable make up the ordinary differential equation
eq
. In many cases it is not necessary to provide this; it will be autodetected (and an error raised if it could not be detected).hint
是希望dsolve使用的求解方法。使用classify_ode(eq, f(x))
为了得到一首颂歌的所有可能的提示。默认提示,default
,将使用首先返回的任何提示classify_ode()
. 你可以在下面看到更多的提示。simplify
通过以下方式实现简化odesimp()
. 有关详细信息,请参见其docstring。例如,禁用此选项可禁用func
或者任意常数的简化。它仍将与此提示集成。请注意,在启用此选项的情况下,解决方案可能包含比ODE的顺序更多的任意常量。xi
和eta
是普通函数的无穷小函数微分方程。它们是微分方程不变的点变换李群的无穷小。用户可以指定无穷小的值。如果没有具体说明,
xi
和eta
使用infinitesimals()
在各种启发式的帮助下。ics
是微分方程的初始/边界条件集。它应该以
{{f(x0): x1, f(x).diff(x).subs(x, x2): x3}}
等等。对于幂级数解,如果没有指定初始条件f(0)
假设为C0
幂级数解约为0。x0
是微分的幂级数解的点待评估方程式。
n
给出幂级数达到的因变量的指数对一个微分方程的解进行评价。
Hints
除了各种解决方法,还有一些元提示可以传递给您
dsolve()
:default
:它使用首先返回的任何提示
classify_ode()
. 这是的默认参数dsolve()
.all
:使
dsolve()
应用所有相关分类提示,使用dsolve(ODE, func, hint="all")
. 这将返回一个字典hint:solution
条款。如果提示导致dsolve引发NotImplementedError
,则该提示的键的值将是引发的异常对象。字典还将包括一些特殊的关键字:order
:颂歌的顺序。另请参见ode_order()
在里面deutils.py
.best
:最简单的提示;返回的结果是什么best
下面。best_hint
:将生成由给出的解决方案的提示best
. 如果多个提示产生最佳解决方案,则元组中的第一个由classify_ode()
是被选中的。default
:默认情况下将返回的解决方案。这是由在返回的元组中首先出现的提示生成的classify_ode()
.
all_Integral
:这和
all
,除非提示也具有相应的_Integral
提示,它只返回_Integral
提示。如果all
原因dsolve()
因难积分或不可能积分而挂起。这个元提示也将比all
,因为integrate()
是一个昂贵的例行程序。best
:拥有
dsolve()
尝试所有方法并返回最简单的方法。这将考虑到解在函数中是否可解,它是否包含任何积分类(即不可赋值的积分),以及哪一个是最短的。
也见
classify_ode()
docstring获取有关提示的更多信息,以及ode
所有支持的提示的列表。Tips
可以通过以下方式声明未知函数的导数:
>>> from sympy import Function, Derivative >>> from sympy.abc import x # x is the independent variable >>> f = Function("f")(x) # f is a function of x >>> # f_ will be the derivative of f with respect to x >>> f_ = Derivative(f, x)
见
test_ode.py
对于许多测试,这也是如何使用dsolve()
.dsolve()
始终返回Equality
类(除了提示为all
或all_Integral
). 如果可能,它显式地为要求解的函数求解。否则,它将返回隐式解决方案。任意常数是名为
C1
,C2
等等。因为所有的解在数学上都应该是等价的,所以一些提示可能会为一个ODE返回完全相同的结果。不过,通常两个不同的提示会返回格式不同的同一个解决方案。两者应该是相等的。另外请注意,有时两个不同溶液中任意常数的值可能不相同,因为一个常数可能“吸收”了其他常数。
做
help(ode.ode_<hintname>)
要获取有关特定提示的详细信息,请执行以下操作:<hintname>
是一个没有提示的名字_Integral
.
对于常微分方程组
- Usage
dsolve(eq, func)
->解常微分方程组eq
对于func
功能列表包括 \(x(t)\) , \(y(t)\) , \(z(t)\) 其中,列表中函数的数量取决于eq
.
Details
eq
可以是任何支持的常微分方程组,也可以是Equality
,或一个表达式,假定等于0
.func
holdsx(t)
andy(t)
being functions of one variable which together with some of their derivatives make up the system of ordinary differential equationeq
. It is not necessary to provide this; it will be autodetected (and an error raised if it could not be detected).Hints
这些提示由classify_sysode返回的参数组成,它们组合在一起会给出后面用于形成方法名的提示名称。
实例
>>> from sympy import Function, dsolve, Eq, Derivative, sin, cos, symbols >>> from sympy.abc import x >>> f = Function('f') >>> dsolve(Derivative(f(x), x, x) + 9*f(x), f(x)) Eq(f(x), C1*sin(3*x) + C2*cos(3*x))
>>> eq = sin(x)*cos(f(x)) + cos(x)*sin(f(x))*f(x).diff(x) >>> dsolve(eq, hint='1st_exact') [Eq(f(x), -acos(C1/cos(x)) + 2*pi), Eq(f(x), acos(C1/cos(x)))] >>> dsolve(eq, hint='almost_linear') [Eq(f(x), -acos(C1/cos(x)) + 2*pi), Eq(f(x), acos(C1/cos(x)))] >>> t = symbols('t') >>> x, y = symbols('x, y', cls=Function) >>> eq = (Eq(Derivative(x(t),t), 12*t*x(t) + 8*y(t)), Eq(Derivative(y(t),t), 21*x(t) + 7*t*y(t))) >>> dsolve(eq) [Eq(x(t), C1*x0(t) + C2*x0(t)*Integral(8*exp(Integral(7*t, t))*exp(Integral(12*t, t))/x0(t)**2, t)), Eq(y(t), C1*y0(t) + C2*(y0(t)*Integral(8*exp(Integral(7*t, t))*exp(Integral(12*t, t))/x0(t)**2, t) + exp(Integral(7*t, t))*exp(Integral(12*t, t))/x0(t)))] >>> eq = (Eq(Derivative(x(t),t),x(t)*y(t)*sin(t)), Eq(Derivative(y(t),t),y(t)**2*sin(t))) >>> dsolve(eq) {Eq(x(t), -exp(C1)/(C2*exp(C1) - cos(t))), Eq(y(t), -1/(C1 - cos(t)))}
- sympy.solvers.ode.systems.dsolve_system(eqs, funcs=None, t=None, ics=None, doit=False, simplify=True)[源代码]#
解任何(支持的)常微分方程组
- 参数:
eqs 名单
有待解决的ODE系统
函数 :列出或无
构成ODE系统的因变量列表
t :符号或无
常微分方程系统中的自变量
ics :Dict或None
常微分方程组的初始边界条件
doit :布尔值
Evaluate the solutions if True. Default value is True. Can be set to false if the integral evaluation takes too much time and/or is not required.
简化:布尔
Simplify the solutions for the systems. Default value is True. Can be set to false if simplification takes too much time and/or is not required.
- 返回:
方程式列表
- 加薪:
NotImplementedError
当常微分方程组不可解时。
ValueError
When the parameters passed are not in the required form.
解释
此函数以ODE系统作为输入,确定此函数是否可解,如果找到,则返回解决方案。
此函数可以处理:1。二阶常系数线性齐次系统。线性,一阶,常系数非齐次方程组。线性,一阶,非常系数齐次方程组。线性,一阶,非常系数非齐次方程组。任何可分为上述4种形式6的颂诗体系的隐含系统。任何高阶线性常微分方程组,可简化为上述5种系统形式之一。
The types of systems described above are not limited by the number of equations, i.e. this function can solve the above types irrespective of the number of equations in the system passed. But, the bigger the system, the more time it will take to solve the system.
此函数返回解决方案列表。每个解都是一组方程,其中LHS是因变量,RHS是自变量的表达式。
在非常系数类型中,并不是所有的系统都能用这个函数来求解。只有那些具有具有交换反导数的系数矩阵的系统,或者那些可以进一步划分以便被分割的系统可以具有具有交换反导数的系数矩阵的系统。
实例
>>> from sympy import symbols, Eq, Function >>> from sympy.solvers.ode.systems import dsolve_system >>> f, g = symbols("f g", cls=Function) >>> x = symbols("x")
>>> eqs = [Eq(f(x).diff(x), g(x)), Eq(g(x).diff(x), f(x))] >>> dsolve_system(eqs) [[Eq(f(x), -C1*exp(-x) + C2*exp(x)), Eq(g(x), C1*exp(-x) + C2*exp(x))]]
You can also pass the initial conditions for the system of ODEs:
>>> dsolve_system(eqs, ics={f(0): 1, g(0): 0}) [[Eq(f(x), exp(x)/2 + exp(-x)/2), Eq(g(x), exp(x)/2 - exp(-x)/2)]]
Optionally, you can pass the dependent variables and the independent variable for which the system is to be solved:
>>> funcs = [f(x), g(x)] >>> dsolve_system(eqs, funcs=funcs, t=x) [[Eq(f(x), -C1*exp(-x) + C2*exp(x)), Eq(g(x), C1*exp(-x) + C2*exp(x))]]
Lets look at an implicit system of ODEs:
>>> eqs = [Eq(f(x).diff(x)**2, g(x)**2), Eq(g(x).diff(x), g(x))] >>> dsolve_system(eqs) [[Eq(f(x), C1 - C2*exp(x)), Eq(g(x), C2*exp(x))], [Eq(f(x), C1 + C2*exp(x)), Eq(g(x), C2*exp(x))]]
- sympy.solvers.ode.classify_ode(eq, func=None, dict=False, ics=None, *, prep=True, xi=None, eta=None, n=None, **kwargs)[源代码]#
返回可能的元组
dsolve()
颂歌的分类。对元组进行排序,因此第一项是
dsolve()
默认情况下用于求解ODE。一般来说,在列表开头的分类会比接近末尾的分类更快地产生更好的解决方案,尽管总会有例外。使dsolve()
使用不同的分类,使用dsolve(ODE, func, hint=<classification>)
.另请参见dsolve()
你可以使用的不同元提示的docstring。如果
dict
是真的,classify_ode()
将返回的字典hint:match
表达式术语。本文件仅供内部使用dsolve()
. 请注意,由于字典是任意排序的,因此这很可能与元组的顺序不同。您可以通过执行
help(ode.ode_hintname)
在哪里hintname
是没有提示的名称_Integral
.见
allhints
或ode
所有支持的提示的列表,可从classify_ode()
.笔记
这些是提示名称的注释。
_Integral
如果分类有
_Integral
最后,它将返回一个未赋值的表达式Integral
上课吧。请注意,如果integrate()
无法进行积分,尽管只是使用_Integral
会快得多。的确,一个_Integral
提示将始终比相应的提示快_Integral
因为integrate()
是一个昂贵的例行程序。如果dsolve()
挂了,可能是因为integrate()
是挂在一个难的或不可能的积分上。尝试使用_Integral
提示或all_Integral
为了得到回报。注意,有些提示没有
_Integral
相对应的人。这是因为integrate()
不用于求解这些方法的ODE。例如, \(n\) 常系数线性齐次常系数常微分方程不需要积分求解,因此不需要积分nth_linear_homogeneous_constant_coeff_Integrate
提示。您可以轻松评估任何未评估的Integral
用做来表达expr.doit()
.序数
有些提示包含序数,如
1st_linear
. 这有助于将它们与其他提示以及可能尚未实现的其他方法区分开来。如果一个暗示nth
在里面,比如nth_linear
提示,这意味着所使用的方法适用于任何顺序的ode。indep
anddep
有些暗示包含了这些词
indep
或dep
. 它们分别引用自变量和因变量。例如,如果一首颂歌 \(f(x)\) 然后indep
将指 \(x\) 和dep
将指 \(f\) .subs
If a hints has the word
subs
in it, it means that the ODE is solved by substituting the expression given after the wordsubs
for a single dummy variable. This is usually in terms ofindep
anddep
as above. The substituted expression will be written only in characters allowed for names of Python objects, meaning operators will be spelled out. For example,indep
/dep
will be written asindep_div_dep
.coeff
单词
coeff
在暗示中指的是颂歌中某物的系数,通常是导数项的系数。有关详细信息,请参见各个方法的docstring (help(ode)
). 这与coefficients
,如undetermined_coefficients
,它引用方法的公共名称。_best
具有多个基本方法来求解的方法将为每个子方法和
_best
元分类。这将评估所有的提示并返回最好的,使用与正常情况相同的注意事项best
元提示。实例
>>> from sympy import Function, classify_ode, Eq >>> from sympy.abc import x >>> f = Function('f') >>> classify_ode(Eq(f(x).diff(x), 0), f(x)) ('nth_algebraic', 'separable', '1st_exact', '1st_linear', 'Bernoulli', '1st_homogeneous_coeff_best', '1st_homogeneous_coeff_subs_indep_div_dep', '1st_homogeneous_coeff_subs_dep_div_indep', '1st_power_series', 'lie_group', 'nth_linear_constant_coeff_homogeneous', 'nth_linear_euler_eq_homogeneous', 'nth_algebraic_Integral', 'separable_Integral', '1st_exact_Integral', '1st_linear_Integral', 'Bernoulli_Integral', '1st_homogeneous_coeff_subs_indep_div_dep_Integral', '1st_homogeneous_coeff_subs_dep_div_indep_Integral') >>> classify_ode(f(x).diff(x, 2) + 3*f(x).diff(x) + 2*f(x) - 4) ('factorable', 'nth_linear_constant_coeff_undetermined_coefficients', 'nth_linear_constant_coeff_variation_of_parameters', 'nth_linear_constant_coeff_variation_of_parameters_Integral')
- sympy.solvers.ode.checkodesol(ode, sol, func=None, order='auto', solve_for_func=True)[源代码]#
替代品
sol
进入之内ode
并检查结果0
.这在什么时候起作用
func
是一个函数,比如 \(f(x)\) 或者一个函数列表,比如 \([f(x), g(x)]\) 什么时候? \(ode\) 是一个颂歌体系。sol
可以是单个解决方案或解决方案列表。每个解决方案可能是Equality
解决方案满足,例如。Eq(f(x), C1), Eq(f(x) + C1, 0)
或者仅仅是Expr
,例如f(x) - C1
. 在大多数情况下,如果不能从原始函数中显式地推导出它,那么在大多数情况下,它将不能从原始函数中推导出来func
争论。如果传递了一系列解决方案,则将使用相同类型的容器来返回每个解决方案的结果。
它依次尝试以下方法,直到找到零等价:
用溶液代替 \(f\) 在原始方程式中。只有当
ode
解决了 \(f\) . 它将试图首先解决它,除非solve_for_func == False
.接受 \(n\) 解的导数,其中 \(n\) 顺序是
ode
,然后检查是否等于溶液。这只适用于准确的颂歌。坐1号,2号。。。, \(n\) 第四个导数的解,每次求解的导数为 \(f\) 这是可能的,因为 \(f\) 是线性运算符)。然后将每个导数反替换为
ode
以相反的顺序。
此函数返回一个元组。元组中的第一项是
True
如果替换导致0
和False
否则。元组中的第二项是替换的结果。应该一直这样0
如果第一项是True
. 有时这个函数会返回False
即使表达式与0
. 这种情况发生在simplify()
不会将表达式缩减为0
. 如果此函数返回的表达式完全消失,则sol
真的是解决ode
.如果这个函数似乎挂起了,那可能是因为很难简化。
要使用此函数进行测试,请测试元组的第一项。
实例
>>> from sympy import (Eq, Function, checkodesol, symbols, ... Derivative, exp) >>> x, C1, C2 = symbols('x,C1,C2') >>> f, g = symbols('f g', cls=Function) >>> checkodesol(f(x).diff(x), Eq(f(x), C1)) (True, 0) >>> assert checkodesol(f(x).diff(x), C1)[0] >>> assert not checkodesol(f(x).diff(x), x)[0] >>> checkodesol(f(x).diff(x, 2), x**2) (False, 2)
>>> eqs = [Eq(Derivative(f(x), x), f(x)), Eq(Derivative(g(x), x), g(x))] >>> sol = [Eq(f(x), C1*exp(x)), Eq(g(x), C2*exp(x))] >>> checkodesol(eqs, sol) (True, [0, 0])
- sympy.solvers.ode.homogeneous_order(eq, *symbols)[源代码]#
返回订单 \(n\) 如果 \(g\) 是同质的
None
如果它不是同质的。确定函数是否为同构函数,如果是同构函数,则为同构函数。函数 \(f(x, y, \cdots)\) 顺序是齐次的 \(n\) 如果 \(f(t x, t y, \cdots) = t^n f(x, y, \cdots)\) .
If the function is of two variables, \(F(x, y)\), then \(f\) being homogeneous of any order is equivalent to being able to rewrite \(F(x, y)\) as \(G(x/y)\) or \(H(y/x)\). This fact is used to solve 1st order ordinary differential equations whose coefficients are homogeneous of the same order (see the docstrings of
HomogeneousCoeffSubsDepDivIndep
andHomogeneousCoeffSubsIndepDivDep
).符号可以是函数,但函数的每个参数都必须是符号,并且表达式中出现的函数参数必须与符号列表中给定的参数匹配。如果声明函数的参数与符号列表中给出的参数不同,
None
返回。实例
>>> from sympy import Function, homogeneous_order, sqrt >>> from sympy.abc import x, y >>> f = Function('f') >>> homogeneous_order(f(x), f(x)) is None True >>> homogeneous_order(f(x,y), f(y, x), x, y) is None True >>> homogeneous_order(f(x), f(x), x) 1 >>> homogeneous_order(x**2*f(x)/sqrt(x**2+f(x)**2), x, f(x)) 2 >>> homogeneous_order(x**2+f(x), x, f(x)) is None True
- sympy.solvers.ode.infinitesimals(eq, func=None, order=None, hint='default', match=None)[源代码]#
常微分方程的无穷小函数, \(\xi(x,y)\) 和 \(\eta(x,y)\) ,是微分方程不变的点变换李群的无穷小。所以,颂歌 \(y'=f(x,y)\) 会承认一个谎言集团 \(x^*=X(x,y;\varepsilon)=x+\varepsilon\xi(x,y)\) , \(y^*=Y(x,y;\varepsilon)=y+\varepsilon\eta(x,y)\) 这样的话 \((y^*)'=f(x^*, y^*)\) . 坐标的改变 \(r(x,y)\) 和 \(s(x,y)\) ,这样这个谎言组就变成了翻译组, \(r^*=r\) 和 \(s^*=s+\varepsilon\) . 它们与新系统的坐标曲线相切。
考虑一下这个转变 \((x, y) \to (X, Y)\) 使得微分方程保持不变。 \(\xi\) 和 \(\eta\) 是变换坐标的切线 \(X\) 和 \(Y\) ,在 \(\varepsilon=0\) .
\[\左(\frac{\partial X(X,y;\varepsilon)}{\partial\varepsilon\]通过求解以下偏微分方程可以找到无穷小:
>>> from sympy import Function, Eq, pprint >>> from sympy.abc import x, y >>> xi, eta, h = map(Function, ['xi', 'eta', 'h']) >>> h = h(x, y) # dy/dx = h >>> eta = eta(x, y) >>> xi = xi(x, y) >>> genform = Eq(eta.diff(x) + (eta.diff(y) - xi.diff(x))*h ... - (xi.diff(y))*h**2 - xi*(h.diff(x)) - eta*(h.diff(y)), 0) >>> pprint(genform) /d d \ d 2 d > |--(eta(x, y)) - --(xi(x, y))|*h(x, y) - eta(x, y)*--(h(x, y)) - h (x, y)*--(x > \dy dx / dy dy > > d d > i(x, y)) - xi(x, y)*--(h(x, y)) + --(eta(x, y)) = 0 > dx dx
解决上述偏微分方程并非易事,而且只能通过对 \(\xi\) 和 \(\eta\) (启发式)。一旦找到一个无穷小,尝试寻找更多的启发停止。这样做是为了优化求解微分方程的速度。如果需要所有无穷小的列表,
hint
应标记为all
,它给出了无穷小的完整列表。如果需要找到特定启发式的无穷小,可以将其作为标志传递给hint
.实例
>>> from sympy import Function >>> from sympy.solvers.ode.lie_group import infinitesimals >>> from sympy.abc import x >>> f = Function('f') >>> eq = f(x).diff(x) - x**2*f(x) >>> infinitesimals(eq) [{eta(x, f(x)): exp(x**3/3), xi(x, f(x)): 0}]
工具书类
用对称群解微分方程,约翰·斯塔雷特,第1-14页
- sympy.solvers.ode.checkinfsol(eq, infinitesimals, func=None, order=None)[源代码]#
此函数用于检查给定的无穷小是否是给定的一阶微分方程的实际无穷小。该方法适用于常微分方程的李群求解。
到目前为止,它只是通过替换偏微分方程中的无穷小来进行检查。
\[\frac{\partial\eta}{\partial x}+\left(\frac{\partial\eta}{\partial y}\]在哪里? \(\eta\) 和 \(\xi\) 是无穷小和 \(h(x,y) = \frac{{dy}}{{dx}}\)
无穷小应该以dicts列表的形式给出
[{{xi(x, y): inf, eta(x, y): inf}}]
,对应于函数无穷小的输出。它返回窗体的值列表[(True/False, sol)]
在哪里?sol
是在PDE中替换无穷小后获得的值。如果是的话True
然后sol
会是0。
- sympy.solvers.ode.constantsimp(expr, constants)[源代码]#
简化包含任意常量的表达式。
此函数是专门为使用而编写的
dsolve()
,不用于一般用途。简化是通过将任意常数“吸收”成其他不独立的任意常数、数字和符号来完成的。
所有的符号都必须有相同的名称,后面还有数字,例如,
C1
,C2
,C3
. 这个symbolname
这里是'\(C`\)'startnumber
会是1,而endnumber
会是3。如果任意常数与变量无关x
,则独立符号为x
. 不需要指定依赖函数,例如f(x)
,因为它已经有了独立的符号,x
,在里面。由于术语被“吸收”到任意常数中,并且由于常数在简化后重新编号,expr中的任意常数不一定等于返回结果中同名的常数。
如果两个或两个以上的任意常数相加、相乘或升幂,它们首先被吸收成一个单一的任意常数。然后,如果需要,将新常数合并成其他项。
常数的吸收是在有限的协助下完成的:
条款
Add
收集s来尝试连接常量,因此 \(e^x (C_1 \cos(x) + C_2 \cos(x))\) 将简化为 \(e^x C_1 \cos(x)\) ;指数幂
Add
s是这样展开的 \(e^{{C_1 + x}}\) 将简化为 \(C_1 e^x\) .
使用
constant_renumber()
在简化后对常数重新编号,否则可能会出现常数上的任意数字,例如。 \(C_1 + C_3 x\) .在极少数情况下,一个常数可以“简化”成两个常数。每一个微分方程解都应该有与微分方程阶数相等的任意常数。这里的结果在技术上是正确的,但是它可能,例如 \(C_1\) 和 \(C_2\) 在一个表达式中,当 \(C_1\) 实际上等于 \(C_2\) . 在这种情况下使用你的判断力,也可以利用在
dsolve()
.实例
>>> from sympy import symbols >>> from sympy.solvers.ode.ode import constantsimp >>> C1, C2, C3, x, y = symbols('C1, C2, C3, x, y') >>> constantsimp(2*C1*x, {C1, C2, C3}) C1*x >>> constantsimp(C1 + 2 + x, {C1, C2, C3}) C1 + x >>> constantsimp(C1*C2 + 2 + C2 + C3*x, {C1, C2, C3}) C1 + C3*x
提示函数#
这些功能供内部使用 dsolve()
还有其他人。不同 User Functions ,以上,这些并不是为普通的SymPy用户准备的。相反,诸如 dsolve()
应该使用。尽管如此,这些函数在其docstring中包含有关各种ODE解决方法的有用信息。出于这个原因,这里记录了它们。
- sympy.solvers.ode.allhints = ('factorable', 'nth_algebraic', 'separable', '1st_exact', '1st_linear', 'Bernoulli', '1st_rational_riccati', 'Riccati_special_minus2', '1st_homogeneous_coeff_best', '1st_homogeneous_coeff_subs_indep_div_dep', '1st_homogeneous_coeff_subs_dep_div_indep', 'almost_linear', 'linear_coefficients', 'separable_reduced', '1st_power_series', 'lie_group', 'nth_linear_constant_coeff_homogeneous', 'nth_linear_euler_eq_homogeneous', 'nth_linear_constant_coeff_undetermined_coefficients', 'nth_linear_euler_eq_nonhomogeneous_undetermined_coefficients', 'nth_linear_constant_coeff_variation_of_parameters', 'nth_linear_euler_eq_nonhomogeneous_variation_of_parameters', 'Liouville', '2nd_linear_airy', '2nd_linear_bessel', '2nd_hypergeometric', '2nd_hypergeometric_Integral', 'nth_order_reducible', '2nd_power_series_ordinary', '2nd_power_series_regular', 'nth_algebraic_Integral', 'separable_Integral', '1st_exact_Integral', '1st_linear_Integral', 'Bernoulli_Integral', '1st_homogeneous_coeff_subs_indep_div_dep_Integral', '1st_homogeneous_coeff_subs_dep_div_indep_Integral', 'almost_linear_Integral', 'linear_coefficients_Integral', 'separable_reduced_Integral', 'nth_linear_constant_coeff_variation_of_parameters_Integral', 'nth_linear_euler_eq_nonhomogeneous_variation_of_parameters_Integral', 'Liouville_Integral', '2nd_nonlinear_autonomous_conserved', '2nd_nonlinear_autonomous_conserved_Integral')#
内置不可变序列。
如果未给定参数,则构造函数返回空元组。如果指定了iterable,则从iterable的项初始化元组。
如果参数是元组,则返回值是相同的对象。
- sympy.solvers.ode.ode.odesimp(ode, eq, func, hint)[源代码]#
简化了ode的解决方案,包括尝试为
func
和跑步constantsimp()
.它可以使用提示返回的解决方案类型的知识来应用其他简化。
它还试图整合任何
Integral
如果提示不是_Integral
提示。此函数对返回的表达式不应有任何影响
dsolve()
作为dsolve()
已经打过电话了odesimp()
,但单个提示函数不调用odesimp()
(因为dsolve()
包装器可以)。因此,此功能主要用于内部使用。实例
>>> from sympy import sin, symbols, dsolve, pprint, Function >>> from sympy.solvers.ode.ode import odesimp >>> x, u2, C1= symbols('x,u2,C1') >>> f = Function('f')
>>> eq = dsolve(x*f(x).diff(x) - f(x) - x*sin(f(x)/x), f(x), ... hint='1st_homogeneous_coeff_subs_indep_div_dep_Integral', ... simplify=False) >>> pprint(eq, wrap_line=False) x ---- f(x) / | | / 1 \ | -|u1 + -------| | | /1 \| | | sin|--|| | \ \u1// log(f(x)) = log(C1) + | ---------------- d(u1) | 2 | u1 | /
>>> pprint(odesimp(eq, f(x), 1, {C1}, ... hint='1st_homogeneous_coeff_subs_indep_div_dep' ... )) x --------- = C1 /f(x)\ tan|----| \2*x /
- sympy.solvers.ode.ode.constant_renumber(expr, variables=None, newconstants=None)[源代码]#
对中的任意常数重新编号
expr
使用中给出的符号名称newconstants
. 在这个过程中,这将以一种标准的方式重新排列表达式项。如果
newconstants
则新的常量名称将C1
,C2
等等,否则newconstants
应该是一个iterable,它给出了按顺序用于常量的新符号。这个
variables
参数是非常量符号的列表。在中找到的所有其他自由符号expr
假定为常量,并将重新编号。如果variables
没有给出任何以开头的编号符号C
(例如)C1
)假设为常数。符号的重新编号基于
.sort_key()
,因此应该按照它们在最终的打印表达式中出现的顺序对它们进行粗略编号。注意,这种排序部分基于散列,因此它可以在不同的机器上产生不同的结果。此函数的结构与
constantsimp()
.实例
>>> from sympy import symbols >>> from sympy.solvers.ode.ode import constant_renumber >>> x, C1, C2, C3 = symbols('x,C1:4') >>> expr = C3 + C2*x + C1*x**2 >>> expr C1*x**2 + C2*x + C3 >>> constant_renumber(expr) C1 + C2*x + C3*x**2
这个
variables
参数指定哪些是常量,以便其他符号不会重新编号:>>> constant_renumber(expr, [C1, x]) C1*x**2 + C2 + C3*x
这个
newconstants
参数用于指定替换常量时要使用的符号:>>> constant_renumber(expr, [x], newconstants=symbols('E1:4')) E1 + E2*x + E3*x**2
- sympy.solvers.ode.ode.ode_sol_simplicity(sol, func, trysolving=True)[源代码]#
返回一个扩展整数,该整数表示ODE的解决方案有多简单。
从最简单到最简单的顺序是:
sol
解决了func
.sol
未解决func
,但可以传递给solve(例如,由dsolve(ode, func, simplify=False
)如果
sol
未解决func
,然后根据sol
,由计算得出len(str(sol))
.如果
sol
有没有未估价的Integral
s、 这将自动被认为比上述任何一个简单。
此函数返回一个整数,如果解决方案A比解决方案B简单,则
ode_sol_simplicity(sola, func) < ode_sol_simplicity(solb, func)
.目前,下面是返回的数字,但是如果启发式得到改进,这可能会改变。只保证订购。
简单性
返回
sol
solved forfunc
-2
sol
未解决func
但是可以-1
sol
is not solved nor solvable forfunc
len(str(sol))
sol
contains anIntegral
oo
oo
这里的意思是共轴无穷大,它比任何整数都大。如果你已经知道
solve()
无法解决sol
,你可以使用trysolving=False
跳过这一步,这是唯一可能缓慢的一步。例如,dsolve()
与simplify=False
旗子应该这样做。如果
sol
是解决方案的列表,如果列表中最差的解决方案返回oo
它返回该值,否则返回len(str(sol))
,即表示整个列表的字符串长度。实例
此函数设计为传递给
min
作为关键论点,比如min(listofsolutions, key=lambda i: ode_sol_simplicity(i, f(x)))
.>>> from sympy import symbols, Function, Eq, tan, Integral >>> from sympy.solvers.ode.ode import ode_sol_simplicity >>> x, C1, C2 = symbols('x, C1, C2') >>> f = Function('f')
>>> ode_sol_simplicity(Eq(f(x), C1*x**2), f(x)) -2 >>> ode_sol_simplicity(Eq(x**2 + f(x), C1), f(x)) -1 >>> ode_sol_simplicity(Eq(f(x), C1*Integral(2*x, x)), f(x)) oo >>> eq1 = Eq(f(x)/tan(f(x)/(2*x)), C1) >>> eq2 = Eq(f(x)/tan(f(x)/(2*x) + f(x)), C2) >>> [ode_sol_simplicity(eq, f(x)) for eq in [eq1, eq2]] [28, 35] >>> min([eq1, eq2], key=lambda i: ode_sol_simplicity(i, f(x))) Eq(f(x)/tan(f(x)/(2*x)), C1)
- class sympy.solvers.ode.single.Factorable(ode_problem)[源代码]#
求解具有可解因子的方程。
该函数用于求解有因子的方程。因子可以是代数或ode类型。它将尝试独立地解决每个因素。因素将通过调用dsolve来解决。我们将返回解决方案列表。
实例
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x >>> f = Function('f') >>> eq = (f(x)**2-4)*(f(x).diff(x)+f(x)) >>> pprint(dsolve(eq, f(x))) -x [f(x) = 2, f(x) = -2, f(x) = C1*e ]
- class sympy.solvers.ode.single.FirstExact(ode_problem)[源代码]#
求解一阶精确常微分方程。
如果一阶微分方程是一个函数的全微分,则称之为精确微分方程。也就是微分方程
\[P(x,y)\,\部分{}x+Q(x,y)\,\partial{}y=0\]是精确的,如果有某种功能 \(F(x, y)\) 这样的话 \(P(x, y) = \partial{{}}F/\partial{{}}x\) 和 \(Q(x, y) = \partial{{}}F/\partial{{}}y\) . 证明了一阶常微分方程精确的一个充要条件是 \(\partial{{}}P/\partial{{}}y = \partial{{}}Q/\partial{{}}x\) . 然后,解决方案如下:
>>> from sympy import Function, Eq, Integral, symbols, pprint >>> x, y, t, x0, y0, C1= symbols('x,y,t,x0,y0,C1') >>> P, Q, F= map(Function, ['P', 'Q', 'F']) >>> pprint(Eq(Eq(F(x, y), Integral(P(t, y), (t, x0, x)) + ... Integral(Q(x0, t), (t, y0, y))), C1)) x y / / | | F(x, y) = | P(t, y) dt + | Q(x0, t) dt = C1 | | / / x0 y0
其中的第一部分 \(P\) 和 \(Q\) 在单连通区域存在且连续。
注:Symphy目前无法表示表达式上的惰性替换,因此提示
1st_exact_Integral
将返回一个与 \(dy\) . 这应该表示你正在求解的函数。实例
>>> from sympy import Function, dsolve, cos, sin >>> from sympy.abc import x >>> f = Function('f') >>> dsolve(cos(f(x)) - (x*sin(f(x)) - f(x)**2)*f(x).diff(x), ... f(x), hint='1st_exact') Eq(x*cos(f(x)) + f(x)**3/3, C1)
工具书类
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第73页
#间接试验
- class sympy.solvers.ode.single.HomogeneousCoeffBest(ode_problem)[源代码]#
从两个提示中返回一个ODE的最佳解决方案
1st_homogeneous_coeff_subs_dep_div_indep
和1st_homogeneous_coeff_subs_indep_div_dep
.这取决于
ode_sol_simplicity()
.See the
HomogeneousCoeffSubsIndepDivDep
andHomogeneousCoeffSubsDepDivIndep
docstrings for more information on these hints. Note that there is noode_1st_homogeneous_coeff_best_Integral
hint.实例
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x), f(x), ... hint='1st_homogeneous_coeff_best', simplify=False)) / 2 \ |3*x | log|----- + 1| | 2 | \f (x) / log(f(x)) = log(C1) - -------------- 3
工具书类
https://en.wikipedia.org/wiki/Homogeneous_differential_equation
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第59页
#间接试验
- class sympy.solvers.ode.single.HomogeneousCoeffSubsDepDivIndep(ode_problem)[源代码]#
用代换法求解一阶齐次系数微分方程 \(u_1 = \frac{{\text{{<dependent variable>}}}}{{\text{{<independent variable>}}}}\) .
这是一个微分方程
\[P(x,y)+Q(x,y)dy/dx=0\]这样的话 \(P\) 和 \(Q\) 是同质的,顺序相同。函数 \(F(x, y)\) 顺序是齐次的 \(n\) 如果 \(F(x t, y t) = t^n F(x, y)\) . 相当于, \(F(x, y)\) 可以重写为 \(G(y/x)\) 或 \(H(x/y)\) . 另请参见
homogeneous_order()
.如果系数 \(P\) 和 \(Q\) 在上述微分方程中,均为同阶齐次函数,则可证明代换 \(y = u_1 x\) (即 \(u_1 = y/x\) )将微分方程转化为变量可分离的方程 \(x\) 和 \(u\) . 如果 \(h(u_1)\) 是由替换产生的函数 \(u_1 = f(x)/x\) 在 \(P(x, f(x))\) 和 \(g(u_2)\) 由上的替换产生的函数 \(Q(x, f(x))\) 在微分方程中 \(P(x, f(x)) + Q(x, f(x)) f'(x) = 0\) ,那么一般的解决方案是:
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x >>> f, g, h = map(Function, ['f', 'g', 'h']) >>> genform = g(f(x)/x) + h(f(x)/x)*f(x).diff(x) >>> pprint(genform) /f(x)\ /f(x)\ d g|----| + h|----|*--(f(x)) \ x / \ x / dx >>> pprint(dsolve(genform, f(x), ... hint='1st_homogeneous_coeff_subs_dep_div_indep_Integral')) f(x) ---- x / | | -h(u1) log(x) = C1 + | ---------------- d(u1) | u1*h(u1) + g(u1) | /
哪里 \(u_1 h(u_1) + g(u_1) \ne 0\) 和 \(x \ne 0\) 。
See also the docstrings of
HomogeneousCoeffBest
andHomogeneousCoeffSubsIndepDivDep
.实例
>>> from sympy import Function, dsolve >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x), f(x), ... hint='1st_homogeneous_coeff_subs_dep_div_indep', simplify=False)) / 3 \ |3*f(x) f (x)| log|------ + -----| | x 3 | \ x / log(x) = log(C1) - ------------------- 3
工具书类
https://en.wikipedia.org/wiki/Homogeneous_differential_equation
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第59页
#间接试验
- class sympy.solvers.ode.single.HomogeneousCoeffSubsIndepDivDep(ode_problem)[源代码]#
用代换法求解一阶齐次系数微分方程 \(u_2 = \frac{{\text{{<independent variable>}}}}{{\text{{<dependent variable>}}}}\) .
这是一个微分方程
\[P(x,y)+Q(x,y)dy/dx=0\]这样的话 \(P\) 和 \(Q\) 是同质的,顺序相同。函数 \(F(x, y)\) 顺序是齐次的 \(n\) 如果 \(F(x t, y t) = t^n F(x, y)\) . 相当于, \(F(x, y)\) 可以重写为 \(G(y/x)\) 或 \(H(x/y)\) . 另请参见
homogeneous_order()
.如果系数 \(P\) 和 \(Q\) 在上述微分方程中,均为同阶齐次函数,则可证明代换 \(x = u_2 y\) (即 \(u_2 = x/y\) )将微分方程转化为变量可分离的方程 \(y\) 和 \(u_2\) . 如果 \(h(u_2)\) 是由替换产生的函数 \(u_2 = x/f(x)\) 在 \(P(x, f(x))\) 和 \(g(u_2)\) 由上的替换产生的函数 \(Q(x, f(x))\) 在微分方程中 \(P(x, f(x)) + Q(x, f(x)) f'(x) = 0\) ,则一般的解决方案是:
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x >>> f, g, h = map(Function, ['f', 'g', 'h']) >>> genform = g(x/f(x)) + h(x/f(x))*f(x).diff(x) >>> pprint(genform) / x \ / x \ d g|----| + h|----|*--(f(x)) \f(x)/ \f(x)/ dx >>> pprint(dsolve(genform, f(x), ... hint='1st_homogeneous_coeff_subs_indep_div_dep_Integral')) x ---- f(x) / | | -g(u1) | ---------------- d(u1) | u1*g(u1) + h(u1) | / f(x) = C1*e
Where \(u_1 g(u_1) + h(u_1) \ne 0\) and \(f(x) \ne 0\).
See also the docstrings of
HomogeneousCoeffBest
andHomogeneousCoeffSubsDepDivIndep
.实例
>>> from sympy import Function, pprint, dsolve >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(2*x*f(x) + (x**2 + f(x)**2)*f(x).diff(x), f(x), ... hint='1st_homogeneous_coeff_subs_indep_div_dep', ... simplify=False)) / 2 \ |3*x | log|----- + 1| | 2 | \f (x) / log(f(x)) = log(C1) - -------------- 3
工具书类
https://en.wikipedia.org/wiki/Homogeneous_differential_equation
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第59页
#间接试验
- class sympy.solvers.ode.single.FirstLinear(ode_problem)[源代码]#
求解一阶线性微分方程组。
这些是微分方程的形式
\[dy/dx+P(x)y=Q(x)\text{.}\]这类微分方程可以用一般的方法求解。积分因子 \(e^{{\int P(x) \,dx}}\) 会把方程变成一个可分离的方程。一般的解决办法是:
>>> from sympy import Function, dsolve, Eq, pprint, diff, sin >>> from sympy.abc import x >>> f, P, Q = map(Function, ['f', 'P', 'Q']) >>> genform = Eq(f(x).diff(x) + P(x)*f(x), Q(x)) >>> pprint(genform) d P(x)*f(x) + --(f(x)) = Q(x) dx >>> pprint(dsolve(genform, f(x), hint='1st_linear_Integral')) / / \ | | | | | / | / | | | | | | | | P(x) dx | - | P(x) dx | | | | | | | / | / f(x) = |C1 + | Q(x)*e dx|*e | | | \ / /
实例
>>> f = Function('f') >>> pprint(dsolve(Eq(x*diff(f(x), x) - f(x), x**2*sin(x)), ... f(x), '1st_linear')) f(x) = x*(C1 - cos(x))
工具书类
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第92页
#间接试验
- class sympy.solvers.ode.single.RationalRiccati(ode_problem)[源代码]#
Gives general solutions to the first order Riccati differential equations that have atleast one rational particular solution.
\[y' = b_0(x) + b_1(x) y + b_2(x) y^2\]where \(b_0\), \(b_1\) and \(b_2\) are rational functions of \(x\) with \(b_2 \ne 0\) (\(b_2 = 0\) would make it a Bernoulli equation).
实例
>>> from sympy import Symbol, Function, dsolve, checkodesol >>> f = Function('f') >>> x = Symbol('x')
>>> eq = -x**4*f(x)**2 + x**3*f(x).diff(x) + x**2*f(x) + 20 >>> sol = dsolve(eq, hint="1st_rational_riccati") >>> sol Eq(f(x), (4*C1 - 5*x**9 - 4)/(x**2*(C1 + x**9 - 1))) >>> checkodesol(eq, sol) (True, 0)
工具书类
Riccati ODE: https://en.wikipedia.org/wiki/Riccati_equation
N. Thieu Vo - Rational and Algebraic Solutions of First-Order Algebraic ODEs: Algorithm 11, pp. 78 - https://www3.risc.jku.at/publications/download/risc_5387/PhDThesisThieu.pdf
- class sympy.solvers.ode.single.SecondLinearAiry(ode_problem)[源代码]#
给出了Airy微分方程的解
\[\分形{d^2y}{dx^2}+(a+bx)y(x)=0\]在Airy的特殊功能方面,airyai和airybi。
实例
>>> from sympy import dsolve, Function >>> from sympy.abc import x >>> f = Function("f") >>> eq = f(x).diff(x, 2) - x*f(x) >>> dsolve(eq) Eq(f(x), C1*airyai(x) + C2*airybi(x))
- class sympy.solvers.ode.single.SecondLinearBessel(ode_problem)[源代码]#
给出贝塞尔微分方程的解
\[x^2\frac{d^2y}{dx^2}+x\frac{dy}{dx}y(x)+(x^2-n^2)y(x)\]if \(n\) is integer then the solution is of the form
Eq(f(x), C0 besselj(n,x) + C1 bessely(n,x))
as both the solutions are linearly independent else if \(n\) is a fraction then the solution is of the formEq(f(x), C0 besselj(n,x) + C1 besselj(-n,x))
which can also transform intoEq(f(x), C0 besselj(n,x) + C1 bessely(n,x))
.实例
>>> from sympy.abc import x >>> from sympy import Symbol >>> v = Symbol('v', positive=True) >>> from sympy import dsolve, Function >>> f = Function('f') >>> y = f(x) >>> genform = x**2*y.diff(x, 2) + x*y.diff(x) + (x**2 - v**2)*y >>> dsolve(genform) Eq(f(x), C1*besselj(v, x) + C2*bessely(v, x))
工具书类
- class sympy.solvers.ode.single.Bernoulli(ode_problem)[源代码]#
解伯努利微分方程。
这些都是形式方程
\[dy/dx+P(x)y=Q(x)y^n\text{,}n\ne 1`\text{.}\]The substitution \(w = 1/y^{1-n}\) will transform an equation of this form into one that is linear (see the docstring of
FirstLinear
). The general solution is:>>> from sympy import Function, dsolve, Eq, pprint >>> from sympy.abc import x, n >>> f, P, Q = map(Function, ['f', 'P', 'Q']) >>> genform = Eq(f(x).diff(x) + P(x)*f(x), Q(x)*f(x)**n) >>> pprint(genform) d n P(x)*f(x) + --(f(x)) = Q(x)*f (x) dx >>> pprint(dsolve(genform, f(x), hint='Bernoulli_Integral'), num_columns=110) -1 ----- n - 1 // / / \ \ || | | | | || | / | / | / | || | | | | | | | || | -(n - 1)* | P(x) dx | -(n - 1)* | P(x) dx | (n - 1)* | P(x) dx| || | | | | | | | || | / | / | / | f(x) = ||C1 - n* | Q(x)*e dx + | Q(x)*e dx|*e | || | | | | \\ / / / /
Note that the equation is separable when \(n = 1\) (see the docstring of
Separable
).>>> pprint(dsolve(Eq(f(x).diff(x) + P(x)*f(x), Q(x)*f(x)), f(x), ... hint='separable_Integral')) f(x) / | / | 1 | | - dy = C1 + | (-P(x) + Q(x)) dx | y | | / /
实例
>>> from sympy import Function, dsolve, Eq, pprint, log >>> from sympy.abc import x >>> f = Function('f')
>>> pprint(dsolve(Eq(x*f(x).diff(x) + f(x), log(x)*f(x)**2), ... f(x), hint='Bernoulli')) 1 f(x) = ----------------- C1*x + log(x) + 1
工具书类
https://en.wikipedia.org/wiki/Bernoulli_differential_equation
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第95页
#间接试验
- class sympy.solvers.ode.single.Liouville(ode_problem)[源代码]#
求解二阶Liouville微分方程。
刘维尔颂歌的一般形式是
\[\分形{d^2 y}{dx^2}+g(y)\left(\!\]一般解决方案是:
>>> from sympy import Function, dsolve, Eq, pprint, diff >>> from sympy.abc import x >>> f, g, h = map(Function, ['f', 'g', 'h']) >>> genform = Eq(diff(f(x),x,x) + g(f(x))*diff(f(x),x)**2 + ... h(x)*diff(f(x),x), 0) >>> pprint(genform) 2 2 /d \ d d g(f(x))*|--(f(x))| + h(x)*--(f(x)) + ---(f(x)) = 0 \dx / dx 2 dx >>> pprint(dsolve(genform, f(x), hint='Liouville_Integral')) f(x) / / | | | / | / | | | | | - | h(x) dx | | g(y) dy | | | | | / | / C1 + C2* | e dx + | e dy = 0 | | / /
实例
>>> from sympy import Function, dsolve, Eq, pprint >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(diff(f(x), x, x) + diff(f(x), x)**2/f(x) + ... diff(f(x), x)/x, f(x), hint='Liouville')) ________________ ________________ [f(x) = -\/ C1 + C2*log(x) , f(x) = \/ C1 + C2*log(x) ]
工具书类
Goldstein和Braun,“求解微分方程的高级方法”,第98页
https://www.maplesoft.com/support/help/Maple/view.aspx?path=odeadvisor/Liouville
#间接试验
- class sympy.solvers.ode.single.RiccatiSpecial(ode_problem)[源代码]#
一般的Riccati方程有
\[dy/dx=f(x)y^2+g(x)y+h(x)\text{.}\]虽然它没有一个通用的解决方案 [1] “特殊”形式, \(dy/dx = a y^2 - b x^c\) ,在许多情况下都有解决方案 [2] . 此例程返回的解决方案 \(a(dy/dx) = b y^2 + c y/x + d/x^2\) 这是通过使用适当的变量变化来将其简化为特殊形式而得到的,当两者都不是时有效的 \(a\) 也不 \(b\) 都是零,或者 \(c\) 或 \(d\) 是零。
>>> from sympy.abc import x, a, b, c, d >>> from sympy import dsolve, checkodesol, pprint, Function >>> f = Function('f') >>> y = f(x) >>> genform = a*y.diff(x) - (b*y**2 + c*y/x + d/x**2) >>> sol = dsolve(genform, y, hint="Riccati_special_minus2") >>> pprint(sol, wrap_line=False) / / __________________ \\ | __________________ | / 2 || | / 2 | \/ 4*b*d - (a + c) *log(x)|| -|a + c - \/ 4*b*d - (a + c) *tan|C1 + ----------------------------|| \ \ 2*a // f(x) = ------------------------------------------------------------------------ 2*b*x
>>> checkodesol(genform, sol, order=1)[0] True
工具书类
- class sympy.solvers.ode.single.NthLinearConstantCoeffHomogeneous(ode_problem)[源代码]#
解算 \(n\) 一阶常系数线性齐次微分方程。
这是一个形式方程
\[a{n(n)}(x)+a{n-1}f^{(n-1)}(x)+\cdots+a_1f'(x)\]通过求特征方程的根,可以用一般的方法求解这些方程 \(a_n m^n + a_{{n-1}} m^{{n-1}} + \cdots + a_1 m + a_0 = 0\) . 解决方案是 \(C_n x^i e^{{r x}}\) 术语,用于每个位置 \(C_n\) 常数是任意的, \(r\) 是特征方程的根 \(i\) 是从0到根1的重数的每一个(例如,重数为2的根3将创建项 \(C_1 e^{{3 x}} + C_2 x e^{{3 x}}\) ). 指数通常用欧拉方程展开复根 \(e^{{I x}} = \cos(x) + I \sin(x)\) . 复根在实系数多项式中总是以共轭对的形式出现,因此这两个根(在简化常数后)将表示为 \(e^{{a x}} \left(C_1 \cos(b x) + C_2 \sin(b x)\right)\) .
如果SymPy找不到特征方程的精确根,则a
ComplexRootOf
实例将返回。>>> from sympy import Function, dsolve >>> from sympy.abc import x >>> f = Function('f') >>> dsolve(f(x).diff(x, 5) + 10*f(x).diff(x) - 2*f(x), f(x), ... hint='nth_linear_constant_coeff_homogeneous') ... Eq(f(x), C5*exp(x*CRootOf(_x**5 + 10*_x - 2, 0)) + (C1*sin(x*im(CRootOf(_x**5 + 10*_x - 2, 1))) + C2*cos(x*im(CRootOf(_x**5 + 10*_x - 2, 1))))*exp(x*re(CRootOf(_x**5 + 10*_x - 2, 1))) + (C3*sin(x*im(CRootOf(_x**5 + 10*_x - 2, 3))) + C4*cos(x*im(CRootOf(_x**5 + 10*_x - 2, 3))))*exp(x*re(CRootOf(_x**5 + 10*_x - 2, 3))))
请注意,由于此方法不涉及集成,因此没有
nth_linear_constant_coeff_homogeneous_Integral
提示。实例
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(f(x).diff(x, 4) + 2*f(x).diff(x, 3) - ... 2*f(x).diff(x, 2) - 6*f(x).diff(x) + 5*f(x), f(x), ... hint='nth_linear_constant_coeff_homogeneous')) x -2*x f(x) = (C1 + C2*x)*e + (C3*sin(x) + C4*cos(x))*e
工具书类
https://en.wikipedia.org/wiki/Linear_differential_equation section: Nonhomogeneous_equation_with_constant_coefficients
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第211页
#间接试验
- class sympy.solvers.ode.single.NthLinearConstantCoeffUndeterminedCoefficients(ode_problem)[源代码]#
解算 \(n\) 用待定系数法求解一阶常系数线性微分方程。
这种方法适用于微分方程的形式
\[a{n(n)}(x)+a{n-1}f^{(n-1)}(x)+\cdots+a_1f'(x)\]在哪里? \(P(x)\) 是一个具有有限个线性独立导数的函数。
满足此要求的函数是形式的有限和函数 \(a x^i e^{{b x}} \sin(c x + d)\) 或 \(a x^i e^{{b x}} \cos(c x + d)\) 在哪里 \(i\) 是一个非负整数,并且 \(a\) , \(b\) , \(c\) 和 \(d\) 是常数。例如任何多项式 \(x\) ,功能如下 \(x^2 e^{{2 x}}\) , \(x \sin(x)\) 和 \(e^x \cos(x)\) 都可以使用。产品 \(\sin\) S和 \(\cos\) 的导数是有限的,因为它们可以展开为 \(\sin(a x)\) 和 \(\cos(b x)\) 条款。但是,SymPy目前无法进行扩展,因此需要根据上面的内容手动重写表达式才能使用此方法。例如,您需要手动转换 \(\sin^2(x)\) 进入之内 \((1 + \cos(2 x))/2\) 正确应用待定系数法。
这种方法的工作原理是从表达式及其所有线性独立导数中创建一个试算函数,并将它们代入原始的ODE中。每个项的系数将是一个线性方程组,这些方程组被求解和替换,从而给出解。如果任何一个试算函数与齐次方程的解线性相关,则将它们乘以充分值 \(x\) 使它们线性独立。
实例
>>> from sympy import Function, dsolve, pprint, exp, cos >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(f(x).diff(x, 2) + 2*f(x).diff(x) + f(x) - ... 4*exp(-x)*x**2 + cos(2*x), f(x), ... hint='nth_linear_constant_coeff_undetermined_coefficients')) / / 3\\ | | x || -x 4*sin(2*x) 3*cos(2*x) f(x) = |C1 + x*|C2 + --||*e - ---------- + ---------- \ \ 3 // 25 25
工具书类
https://en.wikipedia.org/wiki/Method_of_undetermined_coefficients
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第221页
#间接试验
- class sympy.solvers.ode.single.NthLinearConstantCoeffVariationOfParameters(ode_problem)[源代码]#
解算 \(n\) 用参数变分法求解一类常系数线性微分方程。
这种方法适用于任何形式的微分方程
\[f^{(n)}(x)+a{n-1}f^{(n-1)}(x)+\cdots+a_1f'(x)+a_0\]该方法的工作原理是假定特定解采用以下形式
\[\和{x=1}^{n}c_i(x)y_i(x)\text{,}\]在哪里? \(y_i\) 是 \(i\) 齐次方程的解。然后用Wronskian和Cramer规则求解。具体解决方案由
\[\和{x=1}^n\左(\int\frac{wwi(x)}{W(x)}\,dx\]在哪里? \(W(x)\) 是基本系统(即 \(n\) 齐次方程的线性独立解),以及 \(W_i(x)\) 是基本系统的Wronskian和 \(i\) 第列替换为 \([0, 0, \cdots, 0, P(x)]\) .
This method is general enough to solve any \(n\)th order inhomogeneous linear differential equation with constant coefficients, but sometimes SymPy cannot simplify the Wronskian well enough to integrate it. If this method hangs, try using the
nth_linear_constant_coeff_variation_of_parameters_Integral
hint and simplifying the integrals manually. Also, prefer usingnth_linear_constant_coeff_undetermined_coefficients
when it applies, because it does not use integration, making it faster and more reliable.警告,在中使用simplify=False,其中“nth_linear_constant_coeff_variation of_parameters”
dsolve()
可能会导致它挂起,因为它在集成之前不会尝试简化Wronskian。对于这种方法,建议您只使用simplify=False和“nth_linear_constant_coeff_variation_parameters_integration”,特别是当齐次方程的解中包含三角函数时。实例
>>> from sympy import Function, dsolve, pprint, exp, log >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(f(x).diff(x, 3) - 3*f(x).diff(x, 2) + ... 3*f(x).diff(x) - f(x) - exp(x)*log(x), f(x), ... hint='nth_linear_constant_coeff_variation_of_parameters')) / / / x*log(x) 11*x\\\ x f(x) = |C1 + x*|C2 + x*|C3 + -------- - ----|||*e \ \ \ 6 36 ///
工具书类
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第233页
#间接试验
- class sympy.solvers.ode.single.NthLinearEulerEqHomogeneous(ode_problem)[源代码]#
Solves an \(n\)th order linear homogeneous variable-coefficient Cauchy-Euler equidimensional ordinary differential equation.
This is an equation with form \(0 = a_0 f(x) + a_1 x f'(x) + a_2 x^2 f''(x) \cdots\).
These equations can be solved in a general manner, by substituting solutions of the form \(f(x) = x^r\), and deriving a characteristic equation for \(r\). When there are repeated roots, we include extra terms of the form \(C_{r k} \ln^k(x) x^r\), where \(C_{r k}\) is an arbitrary integration constant, \(r\) is a root of the characteristic equation, and \(k\) ranges over the multiplicity of \(r\). In the cases where the roots are complex, solutions of the form \(C_1 x^a \sin(b \log(x)) + C_2 x^a \cos(b \log(x))\) are returned, based on expansions with Euler's formula. The general solution is the sum of the terms found. If SymPy cannot find exact roots to the characteristic equation, a
ComplexRootOf
instance will be returned instead.>>> from sympy import Function, dsolve >>> from sympy.abc import x >>> f = Function('f') >>> dsolve(4*x**2*f(x).diff(x, 2) + f(x), f(x), ... hint='nth_linear_euler_eq_homogeneous') ... Eq(f(x), sqrt(x)*(C1 + C2*log(x)))
Note that because this method does not involve integration, there is no
nth_linear_euler_eq_homogeneous_Integral
hint.以下为内部使用:
returns = 'sol'
返回ODE的解决方案。returns = 'list'
returns a list of linearly independent solutions, corresponding to the fundamental solution set, for use with non homogeneous solution methods like variation of parameters and undetermined coefficients. Note that, though the solutions should be linearly independent, this function does not explicitly check that. You can doassert simplify(wronskian(sollist)) != 0
to check for linear independence. Also,assert len(sollist) == order
will need to pass.returns = 'both'
,返回字典{{'sol': <solution to ODE>, 'list': <list of linearly independent solutions>}}
.
实例
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x >>> f = Function('f') >>> eq = f(x).diff(x, 2)*x**2 - 4*f(x).diff(x)*x + 6*f(x) >>> pprint(dsolve(eq, f(x), ... hint='nth_linear_euler_eq_homogeneous')) 2 f(x) = x *(C1 + C2*x)
工具书类
C. Bender & S. Orszag, "Advanced Mathematical Methods for Scientists and Engineers", Springer 1999, pp. 12
#间接试验
- class sympy.solvers.ode.single.NthLinearEulerEqNonhomogeneousVariationOfParameters(ode_problem)[源代码]#
Solves an \(n\)th order linear non homogeneous Cauchy-Euler equidimensional ordinary differential equation using variation of parameters.
This is an equation with form \(g(x) = a_0 f(x) + a_1 x f'(x) + a_2 x^2 f''(x) \cdots\).
该方法的工作原理是假定特定解采用以下形式
\[\sum_{x=1}^{n} c_i(x) y_i(x) {a_n} {x^n} \text{, }\]where \(y_i\) is the \(i\)th solution to the homogeneous equation. The solution is then solved using Wronskian's and Cramer's Rule. The particular solution is given by multiplying eq given below with \(a_n x^{n}\)
\[\sum_{x=1}^n \left( \int \frac{W_i(x)}{W(x)} \, dx \right) y_i(x) \text{, }\]where \(W(x)\) is the Wronskian of the fundamental system (the system of \(n\) linearly independent solutions to the homogeneous equation), and \(W_i(x)\) is the Wronskian of the fundamental system with the \(i\)th column replaced with \([0, 0, \cdots, 0, \frac{x^{- n}}{a_n} g{\left(x \right)}]\).
This method is general enough to solve any \(n\)th order inhomogeneous linear differential equation, but sometimes SymPy cannot simplify the Wronskian well enough to integrate it. If this method hangs, try using the
nth_linear_constant_coeff_variation_of_parameters_Integral
hint and simplifying the integrals manually. Also, prefer usingnth_linear_constant_coeff_undetermined_coefficients
when it applies, because it does not use integration, making it faster and more reliable.警告,在中使用simplify=False,其中“nth_linear_constant_coeff_variation of_parameters”
dsolve()
可能会导致它挂起,因为它在集成之前不会尝试简化Wronskian。对于这种方法,建议您只使用simplify=False和“nth_linear_constant_coeff_variation_parameters_integration”,特别是当齐次方程的解中包含三角函数时。实例
>>> from sympy import Function, dsolve, Derivative >>> from sympy.abc import x >>> f = Function('f') >>> eq = x**2*Derivative(f(x), x, x) - 2*x*Derivative(f(x), x) + 2*f(x) - x**4 >>> dsolve(eq, f(x), ... hint='nth_linear_euler_eq_nonhomogeneous_variation_of_parameters').expand() Eq(f(x), C1*x + C2*x**2 + x**4/6)
- class sympy.solvers.ode.single.NthLinearEulerEqNonhomogeneousUndeterminedCoefficients(ode_problem)[源代码]#
Solves an \(n\)th order linear non homogeneous Cauchy-Euler equidimensional ordinary differential equation using undetermined coefficients.
This is an equation with form \(g(x) = a_0 f(x) + a_1 x f'(x) + a_2 x^2 f''(x) \cdots\).
These equations can be solved in a general manner, by substituting solutions of the form \(x = exp(t)\), and deriving a characteristic equation of form \(g(exp(t)) = b_0 f(t) + b_1 f'(t) + b_2 f''(t) \cdots\) which can be then solved by nth_linear_constant_coeff_undetermined_coefficients if g(exp(t)) has finite number of linearly independent derivatives.
满足此要求的函数是形式的有限和函数 \(a x^i e^{{b x}} \sin(c x + d)\) 或 \(a x^i e^{{b x}} \cos(c x + d)\) 在哪里 \(i\) 是一个非负整数,并且 \(a\) , \(b\) , \(c\) 和 \(d\) 是常数。例如任何多项式 \(x\) ,功能如下 \(x^2 e^{{2 x}}\) , \(x \sin(x)\) 和 \(e^x \cos(x)\) 都可以使用。产品 \(\sin\) S和 \(\cos\) 的导数是有限的,因为它们可以展开为 \(\sin(a x)\) 和 \(\cos(b x)\) 条款。但是,SymPy目前无法进行扩展,因此需要根据上面的内容手动重写表达式才能使用此方法。例如,您需要手动转换 \(\sin^2(x)\) 进入之内 \((1 + \cos(2 x))/2\) 正确应用待定系数法。
After replacement of x by exp(t), this method works by creating a trial function from the expression and all of its linear independent derivatives and substituting them into the original ODE. The coefficients for each term will be a system of linear equations, which are be solved for and substituted, giving the solution. If any of the trial functions are linearly dependent on the solution to the homogeneous equation, they are multiplied by sufficient \(x\) to make them linearly independent.
实例
>>> from sympy import dsolve, Function, Derivative, log >>> from sympy.abc import x >>> f = Function('f') >>> eq = x**2*Derivative(f(x), x, x) - 2*x*Derivative(f(x), x) + 2*f(x) - log(x) >>> dsolve(eq, f(x), ... hint='nth_linear_euler_eq_nonhomogeneous_undetermined_coefficients').expand() Eq(f(x), C1*x + C2*x**2 + log(x)/2 + 3/4)
- class sympy.solvers.ode.single.NthAlgebraic(ode_problem)[源代码]#
解算 \(n\) 利用代数和积分的一阶常微分方程。
对于这类方程,没有一种通用的形式。将微分作为一个可逆的代数函数来代数求解。
实例
>>> from sympy import Function, dsolve, Eq >>> from sympy.abc import x >>> f = Function('f') >>> eq = Eq(f(x) * (f(x).diff(x)**2 - 1), 0) >>> dsolve(eq, f(x), hint='nth_algebraic') [Eq(f(x), 0), Eq(f(x), C1 - x), Eq(f(x), C1 + x)]
注意,这个解算器可以返回没有任何积分常数(在上面的例子中f(x)=0)的代数解。
- class sympy.solvers.ode.single.NthOrderReducible(ode_problem)[源代码]#
使用形式的替换来求解只涉及因变量导数的ODE \(f^n(x) = g(x)\) .
例如任何形式的二阶颂歌 \(f''(x) = h(f'(x), x)\) 可以转化为一对一阶常微分方程 \(g'(x) = h(g(x), x)\) 和 \(f'(x) = g(x)\) . 通常为第一阶颂歌 \(g\) 更容易解决。如果这给出了 \(g\) 然后 \(f\) 只需集成即可找到。
实例
>>> from sympy import Function, dsolve, Eq >>> from sympy.abc import x >>> f = Function('f') >>> eq = Eq(x*f(x).diff(x)**2 + f(x).diff(x, 2), 0) >>> dsolve(eq, f(x), hint='nth_order_reducible') ... Eq(f(x), C1 - sqrt(-1/C2)*log(-C2*sqrt(-1/C2) + x) + sqrt(-1/C2)*log(C2*sqrt(-1/C2) + x))
- class sympy.solvers.ode.single.Separable(ode_problem)[源代码]#
求解可分离的一阶微分方程。
这是任何可以写成的微分方程 \(P(y) \tfrac{{dy}}{{dx}} = Q(x)\) . 然后,通过重新排列术语并整合: \(\int P(y) \,dy = \int Q(x) \,dx\) . 此提示使用
sympy.simplify.simplify.separatevars()
作为它的后端,如果一个可分离的方程没有被这个解算器捕捉到,那很可能是那个函数的错误。separatevars()
聪明到可以做大多数必要的展开和因子分解来转换一个可分离的方程吗 \(F(x, y)\) 以适当的形式 \(P(x)\cdot{{}}Q(y)\) . 一般的解决办法是:>>> from sympy import Function, dsolve, Eq, pprint >>> from sympy.abc import x >>> a, b, c, d, f = map(Function, ['a', 'b', 'c', 'd', 'f']) >>> genform = Eq(a(x)*b(f(x))*f(x).diff(x), c(x)*d(f(x))) >>> pprint(genform) d a(x)*b(f(x))*--(f(x)) = c(x)*d(f(x)) dx >>> pprint(dsolve(genform, f(x), hint='separable_Integral')) f(x) / / | | | b(y) | c(x) | ---- dy = C1 + | ---- dx | d(y) | a(x) | | / /
实例
>>> from sympy import Function, dsolve, Eq >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(Eq(f(x)*f(x).diff(x) + x, 3*x*f(x)**2), f(x), ... hint='separable', simplify=False)) / 2 \ 2 log\3*f (x) - 1/ x ---------------- = C1 + -- 6 2
工具书类
M、 Tenenbaum&H.Pollard,“常微分方程”,多佛1963年,第52页
#间接试验
- class sympy.solvers.ode.single.AlmostLinear(ode_problem)[源代码]#
解一个几乎线性的微分方程。
几乎线性微分方程的一般形式是
\[a(x)g'(f(x))f'(x)+b(x)g(f(x))+c(x)\]在这里 \(f(x)\) 是要求解的函数(因变量)。替代品 \(g(f(x)) = u(x)\) 导出一个线性微分方程 \(u(x)\) 形式的 \(a(x) u' + b(x) u + c(x) = 0\) . 这可以解决 \(u(x)\) 由 \(first_linear\) 暗示然后 \(f(x)\) 是通过求解 \(g(f(x)) = u(x)\) .
实例
>>> from sympy import dsolve, Function, pprint, sin, cos >>> from sympy.abc import x >>> f = Function('f') >>> d = f(x).diff(x) >>> eq = x*d + x*f(x) + 1 >>> dsolve(eq, f(x), hint='almost_linear') Eq(f(x), (C1 - Ei(x))*exp(-x)) >>> pprint(dsolve(eq, f(x), hint='almost_linear')) -x f(x) = (C1 - Ei(x))*e >>> example = cos(f(x))*f(x).diff(x) + sin(f(x)) + 1 >>> pprint(example) d sin(f(x)) + cos(f(x))*--(f(x)) + 1 dx >>> pprint(dsolve(example, f(x), hint='almost_linear')) / -x \ / -x \ [f(x) = pi - asin\C1*e - 1/, f(x) = asin\C1*e - 1/]
工具书类
乔尔·摩西,“象征性整合——暴风雨的十年”,ACM通讯,第14卷,第8期,1971年8月,第558页
- class sympy.solvers.ode.single.LinearCoefficients(ode_problem)[源代码]#
求解具有线性系数的微分方程。
线性系数微分方程的一般形式是
\[y'+F\左(\!\分形{a_1x+b_1y+c_1}{a_2x+b_2y+\]在哪里? \(a_1\) , \(b_1\) , \(c_1\) , \(a_2\) , \(b_2\) , \(c_2\) 是常数和 \(a_1 b_2 - a_2 b_1 \ne 0\) .
可通过以下方式解决:
\[x=x'+\frac{b_2c_1-b_1 c_2}{a_2 b_1-a_1 b_2}\]这种代换将方程简化为齐次微分方程。
实例
>>> from sympy import dsolve, Function, pprint >>> from sympy.abc import x >>> f = Function('f') >>> df = f(x).diff(x) >>> eq = (x + f(x) + 1)*df + (f(x) - 6*x + 1) >>> dsolve(eq, hint='linear_coefficients') [Eq(f(x), -x - sqrt(C1 + 7*x**2) - 1), Eq(f(x), -x + sqrt(C1 + 7*x**2) - 1)] >>> pprint(dsolve(eq, hint='linear_coefficients')) ___________ ___________ / 2 / 2 [f(x) = -x - \/ C1 + 7*x - 1, f(x) = -x + \/ C1 + 7*x - 1]
参见
sympy.solvers.ode.single.HomogeneousCoeffBest
,sympy.solvers.ode.single.HomogeneousCoeffSubsIndepDivDep
,sympy.solvers.ode.single.HomogeneousCoeffSubsDepDivIndep
工具书类
乔尔·摩西,“象征性整合——暴风雨的十年”,ACM通讯,第14卷,第8期,1971年8月,第558页
- class sympy.solvers.ode.single.SeparableReduced(ode_problem)[源代码]#
解一个可化为可分离形式的微分方程。
这个方程的一般形式是
\[y'+(y/x)H(x^n y)=0\文本{}。\]这可以通过替换来解决 \(u(y) = x^n y\) . 然后将方程简化为可分离形式 \(\frac{{u'}}{{u (\mathrm{{power}} - H(u))}} - \frac{{1}}{{x}} = 0\) .
一般解决方案是:
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x, n >>> f, g = map(Function, ['f', 'g']) >>> genform = f(x).diff(x) + (f(x)/x)*g(x**n*f(x)) >>> pprint(genform) / n \ d f(x)*g\x *f(x)/ --(f(x)) + --------------- dx x >>> pprint(dsolve(genform, hint='separable_reduced')) n x *f(x) / | | 1 | ------------ dy = C1 + log(x) | y*(n - g(y)) | /
实例
>>> from sympy import dsolve, Function, pprint >>> from sympy.abc import x >>> f = Function('f') >>> d = f(x).diff(x) >>> eq = (x - x**2*f(x))*d - f(x) >>> dsolve(eq, hint='separable_reduced') [Eq(f(x), (1 - sqrt(C1*x**2 + 1))/x), Eq(f(x), (sqrt(C1*x**2 + 1) + 1)/x)] >>> pprint(dsolve(eq, hint='separable_reduced')) ___________ ___________ / 2 / 2 1 - \/ C1*x + 1 \/ C1*x + 1 + 1 [f(x) = ------------------, f(x) = ------------------] x x
工具书类
乔尔·摩西,“象征性整合——暴风雨的十年”,ACM通讯,第14卷,第8期,1971年8月,第558页
- class sympy.solvers.ode.single.LieGroup(ode_problem)[源代码]#
这个提示实现了求解一阶微分方程的李群方法。其目的是将给定的微分方程从给定的坐标系转换成另一个坐标系,使其在单参数李群平移下保持不变。转换后的常微分方程可以很容易地用求积法求解。它利用了
sympy.solvers.ode.infinitesimals()
返回转换无穷小的函数。坐标 \(r\) 和 \(s\) 可以通过求解下面的偏微分方程得到。
\[\席Frac{{部分R}{部分x}+\etaη\ {部分r}{}部分y}\]\[\席Fr{{部分s}{{部分x}+\etaη\ {部分s}{部分y}\]微分方程在新的坐标系下变得可分离
\[\frac{ds}{dr}=\frac{\frac{\partial s}{\partial x}+\]通过积分求出解后,通过代入将其转换回原始坐标系 \(r\) 和 \(s\) 依据 \(x\) 和 \(y\) 再一次。
实例
>>> from sympy import Function, dsolve, exp, pprint >>> from sympy.abc import x >>> f = Function('f') >>> pprint(dsolve(f(x).diff(x) + 2*x*f(x) - x*exp(-x**2), f(x), ... hint='lie_group')) / 2\ 2 | x | -x f(x) = |C1 + --|*e \ 2 /
工具书类
用对称群解微分方程,约翰·斯塔雷特,第1-14页
- class sympy.solvers.ode.single.SecondHypergeometric(ode_problem)[源代码]#
Solves 2nd order linear differential equations.
It computes special function solutions which can be expressed using the 2F1, 1F1 or 0F1 hypergeometric functions.
\[y'' + A(x) y' + B(x) y = 0\text{,}\]where \(A\) and \(B\) are rational functions.
These kinds of differential equations have solution of non-Liouvillian form.
Given linear ODE can be obtained from 2F1 given by
\[(x^2 - x) y'' + ((a + b + 1) x - c) y' + b a y = 0\text{,}\]where {a, b, c} are arbitrary constants.
笔记
The algorithm should find any solution of the form
\[y = P(x) _pF_q(..; ..;\frac{\alpha x^k + \beta}{\gamma x^k + \delta})\text{,}\]where pFq is any of 2F1, 1F1 or 0F1 and \(P\) is an "arbitrary function". Currently only the 2F1 case is implemented in SymPy but the other cases are described in the paper and could be implemented in future (contributions welcome!).
实例
>>> from sympy import Function, dsolve, pprint >>> from sympy.abc import x >>> f = Function('f') >>> eq = (x*x - x)*f(x).diff(x,2) + (5*x - 1)*f(x).diff(x) + 4*f(x) >>> pprint(dsolve(eq, f(x), '2nd_hypergeometric')) _ / / 4 \\ |_ /-1, -1 | \ |C1 + C2*|log(x) + -----||* | | | x| \ \ x + 1// 2 1 \ 1 | / f(x) = -------------------------------------------- 3 (x - 1)
工具书类
"Non-Liouvillian solutions for second order linear ODEs" by L. Chan, E.S. Cheb-Terrab
- sympy.solvers.ode.ode.ode_1st_power_series(eq, func, order, match)[源代码]#
幂级数解法是一种将泰勒级数展开用于求解微分方程的方法。
对于一阶微分方程 \(\frac{{dy}}{{dx}} = h(x, y)\) ,幂级数解决方案存在于某个点上 \(x = x_{{0}}\) 如果 \(h(x, y)\) 在分析 \(x_{{0}}\) . 解决方案由
\[y(x)=y(x{0})+\sum{n=1}^{\infty}\frac{F{n}(x{0},b)(x-x{0})^n}{n!},\]在哪里? \(y(x_{{0}}) = b\) 是y的初始值 \(x_{{0}}\) . 计算 \(F_{{n}}(x_{{0}},b)\) 遵循以下算法,直到生成所需数量的术语。
\(F_1 = h(x_{0}, b)\)
\(F_{n+1} = \frac{\partial F_{n}}{\partial x} + \frac{\partial F_{n}}{\partial y}F_{1}\)
实例
>>> from sympy import Function, pprint, exp, dsolve >>> from sympy.abc import x >>> f = Function('f') >>> eq = exp(x)*(f(x).diff(x)) - f(x) >>> pprint(dsolve(eq, hint='1st_power_series')) 3 4 5 C1*x C1*x C1*x / 6\ f(x) = C1 + C1*x - ----- + ----- + ----- + O\x / 6 24 60
工具书类
崔维思.沃克.解一阶微分方程的解析幂级数法,第17、18页
- sympy.solvers.ode.ode.ode_2nd_power_series_ordinary(eq, func, order, match)[源代码]#
给出了一类二阶多项式系数齐次微分方程在常点处的幂级数解。齐次微分方程的形式是
\[P(x)\frac{d^2y}{dx^2} + Q(x)\frac{dy}{dx} + R(x) y(x) = 0\]为了简单起见,我们假设 \(P(x)\) , \(Q(x)\) 和 \(R(x)\) 是多项式,这就足够了 \(\frac{{Q(x)}}{{P(x)}}\) 和 \(\frac{{R(x)}}{{P(x)}}\) 存在于 \(x_{{0}}\) . 通过代入得到一个递推关系 \(y\) 作为 \(\sum_{{n=0}}^\infty a_{{n}}x^{{n}}\) ,在微分方程中,并等价于第n项。利用这种关系可以生成各种术语。
实例
>>> from sympy import dsolve, Function, pprint >>> from sympy.abc import x >>> f = Function("f") >>> eq = f(x).diff(x, 2) + f(x) >>> pprint(dsolve(eq, hint='2nd_power_series_ordinary')) / 4 2 \ / 2\ |x x | | x | / 6\ f(x) = C2*|-- - -- + 1| + C1*x*|1 - --| + O\x / \24 2 / \ 6 /
工具书类
https://tutorial.math.lamar.edu/Classes/DE/SeriesSolutions.aspx
George E.Simmons,“微分方程及其应用和历史笔记”,第176-184页
- sympy.solvers.ode.ode.ode_2nd_power_series_regular(eq, func, order, match)[源代码]#
给出了在正则点处具有多项式系数的二阶齐次微分方程的幂级数解。二阶齐次微分方程是
\[P(x)\frac{d^2y}{dx^2} + Q(x)\frac{dy}{dx} + R(x) y(x) = 0\]点被称为正则单数 \(x0\) 如果 \(x - x0\frac{{Q(x)}}{{P(x)}}\) 和 \((x - x0)^{{2}}\frac{{R(x)}}{{P(x)}}\) 分析 \(x0\) . 为了简单起见 \(P(x)\) , \(Q(x)\) 和 \(R(x)\) 假设是多项式。求幂级数解的算法是:
试着表达 \((x - x0)P(x)\) 和 \(((x - x0)^{{2}})Q(x)\) 作为关于x0的幂级数解决方案。查找 \(p0\) 和 \(q0\) 它们是幂级数展开式的常数。
求指数方程 \(f(m) = m(m - 1) + m*p0 + q0\) ,以获得根 \(m1\) 和 \(m2\) 指数方程的。
如果 \(m1 - m2\) 非整数存在两个级数解。如果 \(m1 = m2\) ,只有一个解决方案。如果 \(m1 - m2\) 是一个整数,则证明了一个解的存在性。另一种解决方案可能存在,也可能不存在。
幂级数解的形式是 \(x^{{m}}\sum_{{n=0}}^\infty a_{{n}}x^{{n}}\) . 系数由以下递推关系确定。 \(a_{{n}} = -\frac{{\sum_{{k=0}}^{{n-1}} q_{{n-k}} + (m + k)p_{{n-k}}}}{{f(m + n)}}\) . 在这种情况下 \(m1 - m2\) 是一个整数,从递推关系可以看出,对于下根 \(m\) 当 \(n\) 等于两个根的差,分母变为零。因此,如果分子不等于零,则存在第二个级数解。
实例
>>> from sympy import dsolve, Function, pprint >>> from sympy.abc import x >>> f = Function("f") >>> eq = x*(f(x).diff(x, 2)) + 2*(f(x).diff(x)) + x*f(x) >>> pprint(dsolve(eq, hint='2nd_power_series_regular')) / 6 4 2 \ | x x x | / 4 2 \ C1*|- --- + -- - -- + 1| |x x | \ 720 24 2 / / 6\ f(x) = C2*|--- - -- + 1| + ------------------------ + O\x / \120 6 / x
工具书类
George E.Simmons,“微分方程及其应用和历史笔记”,第176-184页
测谎法#
这些函数用于李群解算器的内部使用。尽管如此,它们在docstring中包含了各种启发式算法的有用信息。
- sympy.solvers.ode.lie_group.lie_heuristic_abaco1_simple(match, comp=False)[源代码]#
第一个启发式使用以下四组假设 \(\xi\) 和 \(\eta\)
\[\席=0,η=f(x)\]\[\席=0,η=f(y)\]\[\席=f(x),η=0\]\[\席=f(y),η=0\]这种启发式的成功取决于代数因式分解。对于第一个假设 \(\xi = 0\) 和 \(\eta\) 成为…的函数 \(x\) ,PDE
\[\frac{\partial \eta}{\partial x} + (\frac{\partial \eta}{\partial y} - \frac{\partial \xi}{\partial x})*h - \frac{\partial \xi}{\partial y}*h^{2} - \xi*\frac{\partial h}{\partial x} - \eta*\frac{\partial h}{\partial y} = 0\]减少到 \(f'(x) - f\frac{{\partial h}}{{\partial y}} = 0\) 如果 \(\frac{{\partial h}}{{\partial y}}\) 是的函数 \(x\) ,那么这通常可以很容易地集成。类似的想法也适用于其他3个假设。
工具书类
E、 S Cheb Terrab,L.G.S Duarte and L.A,C.P da Mota,用对称方法求解一阶常微分方程,第8页
- sympy.solvers.ode.lie_group.lie_heuristic_abaco1_product(match, comp=False)[源代码]#
第二个启发式使用以下两个假设 \(\xi\) 和 \(\eta\)
\[席η=0,\xI= f(x)*g(y)\]\[η=f(x)*g(y),\席=0\]这个启发式的第一个假设成立 \(\frac{{1}}{{h^{{2}}}}\frac{{\partial^2}}{{\partial x \partial y}}\log(h)\) 是可分离的 \(x\) 和 \(y\) ,然后分离出包含 \(x\) 是 \(f(x)\) 和 \(g(y)\) 由获得
\[e^{\int f\frac{\partial}{\partial x}\left(\frac{1}{f*h}\right)\,dy}\]假如 \(f\frac{{\partial}}{{\partial x}}\left(\frac{{1}}{{f*h}}\right)\) 是的函数 \(y\) 只有。
如果第二个假设成立 \(\frac{{dy}}{{dx}} = h(x, y)\) 重写为 \(\frac{{dy}}{{dx}} = \frac{{1}}{{h(y, x)}}\) 第一个假设的相同性质满足。在获得 \(f(x)\) 和 \(g(y)\) ,坐标再次交换,得到 \(\eta\) 作为 \(f(x)*g(y)\)
工具书类
E、 S.Cheb Terrab,A.D.Roche,《对称性与一阶颂歌模式》,第7-8页
- sympy.solvers.ode.lie_group.lie_heuristic_bivariate(match, comp=False)[源代码]#
第三个启发式假设无穷小 \(\xi\) 和 \(\eta\) 二元多项式 \(x\) 和 \(y\) . 以下逻辑的假设是 \(h\) 是一个有理函数 \(x\) 和 \(y\) 虽然这对于无穷小不是二元多项式是必要的。用多项式和多项式的相似性来代替多项式和多项式的解,因为它们是用多项式和多项式的非平凡解来代替的。假设的二元数增加到某个最大值。
工具书类
李群与微分方程第327-329页
- sympy.solvers.ode.lie_group.lie_heuristic_chi(match, comp=False)[源代码]#
第四个启发式的目的是找到函数 \(\chi(x, y)\) 满足PDE的要求 \(\frac{{d\chi}}{{dx}} + h\frac{{d\chi}}{{dx}} - \frac{{\partial h}}{{\partial y}}\chi = 0\) .
这是假设 \(\chi\) 二元多项式 \(x\) 和 \(y\) . 凭直觉, \(h\) 应该是一个有理函数 \(x\) 和 \(y\) . 这里使用的方法是用一般的二项式代替 \(\chi\) 达到一定的最大程度。多项式的系数,通过在 \(x\) 和 \(y\) .
发现后 \(\chi\) ,下一步是使用 \(\eta = \xi*h + \chi\) ,以确定 \(\xi\) 和 \(\eta\) . 这可以通过除法来实现 \(\chi\) 通过 \(h\) 会给你 \(-\xi\) 作为商和 \(\eta\) 作为剩余部分。
工具书类
E、 S Cheb Terrab,L.G.S Duarte and L.A,C.P da Mota,用对称方法求解一阶常微分方程,第8页
- sympy.solvers.ode.lie_group.lie_heuristic_abaco2_similar(match, comp=False)[源代码]#
这个启发式使用以下两个假设 \(\xi\) 和 \(\eta\)
\[席η=g(x),\xI= f(x)\]\[席η=f(y),\xI= g(y)\]对于第一个假设,
弗斯特 \(\frac{{\frac{{\partial h}}{{\partial y}}}}{{\frac{{\partial^{{2}} h}}{{ \partial yy}}}}\) 是经过计算的。我们假设这个值是
如果这是常数,那么 \(h\) 与表单匹配 \(A(x) + B(x)e^{{ \frac{{y}}{{C}}}}\) 然后, \(\frac{{e^{{\int \frac{{A(x)}}{{C}} \,dx}}}}{{B(x)}}\) 给予 \(f(x)\) 和 \(A(x)*f(x)\) 给予 \(g(x)\)
否则 \(\frac{{\frac{{\partial A}}{{\partial X}}}}{{\frac{{\partial A}}{{ \partial Y}}}} = \gamma\) 是经过计算的。如果
甲] \(\gamma\) 是的函数 \(x\) 单独地
乙] \(\frac{{\gamma\frac{{\partial h}}{{\partial y}} - \gamma'(x) - \frac{{ \partial h}}{{\partial x}}}}{{h + \gamma}} = G\) 是的函数 \(x\) 独自一人。然后, \(e^{{\int G \,dx}}\) 给予 \(f(x)\) 和 \(-\gamma*f(x)\) 给予 \(g(x)\)
如果第二个假设成立 \(\frac{{dy}}{{dx}} = h(x, y)\) 重写为 \(\frac{{dy}}{{dx}} = \frac{{1}}{{h(y, x)}}\) 第一个假设的相同性质满足。在获得 \(f(x)\) 和 \(g(x)\) ,坐标再次交换,得到 \(\xi\) 作为 \(f(x^*)\) 和 \(\eta\) 作为 \(g(y^*)\)
工具书类
E、 S.Cheb Terrab,A.D.Roche,《对称性与一阶颂歌图案》,第10-12页
- sympy.solvers.ode.lie_group.lie_heuristic_function_sum(match, comp=False)[源代码]#
这个启发式使用以下两个假设 \(\xi\) 和 \(\eta\)
\[席η=0,\xI= f(x)+g(y)\]\[η=f(x)+g(y),\席=0\]这个启发式的第一个假设成立
\[\frac{\partial}{\partial y}[(h\frac{\partial^{2}}}{\]是可分离的 \(x\) 和 \(y\) ,
包含 \(y\) 是 \(\frac{{\partial g}}{{\partial y}}\) . 从这里 \(g(y)\) 可以确定。
包含 \(x\) 是 \(f''(x)\) .
\(h\frac{{\partial^{{2}}}}{{\partial x^{{2}}}}(h^{{-1}})\) 等于 \(\frac{{f''(x)}}{{f(x) + g(y)}}\) . 从这里 \(f(x)\) 可以确定。
如果第二个假设成立 \(\frac{{dy}}{{dx}} = h(x, y)\) 重写为 \(\frac{{dy}}{{dx}} = \frac{{1}}{{h(y, x)}}\) 第一个假设的相同性质满足。在获得 \(f(x)\) 和 \(g(y)\) ,坐标再次交换,得到 \(\eta\) 作为 \(f(x) + g(y)\) .
对于这两个假设,常数因子在 \(g(y)\) 和 \(f''(x)\) ,这样 \(f''(x)\) 从3]得到的结果与从2]得到的结果相同。如果不可能,那么这个启发就失败了。
工具书类
E、 S.Cheb Terrab,A.D.Roche,《对称性与一阶颂歌模式》,第7-8页
- sympy.solvers.ode.lie_group.lie_heuristic_abaco2_unique_unknown(match, comp=False)[源代码]#
这种启发式假设存在未知函数或具有非整数幂的已知函数。
包含x和y的所有函数和非整数幂的列表
在每个元素上循环 \(f\) 在列表中,找到 \(\frac{{\frac{{\partial f}}{{\partial x}}}}{{ \frac{{\partial f}}{{\partial x}}}} = R\)
如果它在 \(x\) 和 \(y\) ,让 \(X\) 是包含 \(x\) . 然后
- a] 检查是否 \(\xi = X\) 和 \(\eta = -\frac{{X}}{{R}}\) 满足PDE。如果是,则返回
\(\xi\) and \(\eta\)
- b] 检查是否 \(\xi = \frac{{-R}}{{X}}\) 和 \(\eta = -\frac{{1}}{{X}}\) 满足PDE。
如果是,则返回 \(\xi\) 和 \(\eta\)
如果没有,则检查
甲] \(\xi = -R,\eta = 1\)
乙] \(\xi = 1, \eta = -\frac{{1}}{{R}}\)
是解决方案。
工具书类
E、 S.Cheb Terrab,A.D.Roche,《对称性与一阶颂歌图案》,第10-12页
- sympy.solvers.ode.lie_group.lie_heuristic_abaco2_unique_general(match, comp=False)[源代码]#
这个启发式算法发现 \(\eta = f(x)\) , \(\xi = g(y)\) 不做任何假设 \(h\) .
下面的文章给出了完整的步骤顺序。
工具书类
E、 S.Cheb Terrab,A.D.Roche,《对称性与一阶颂歌图案》,第10-12页
- sympy.solvers.ode.lie_group.lie_heuristic_linear(match, comp=False)[源代码]#
这个启发式假设
\(\xi = ax + by + c\) 和
\(\eta = fx + gy + h\)
在确定PDE时替换以下假设后,将其简化为
\[f+(g-a)h-bh^{2}-(ax+by+c)\frac{\partial h}{\partial x}\]用特征线法求解得到的简化偏微分方程变得不切实际。所采用的方法是将相似项分组,然后求解得到的线性方程组。二元启发式的区别在于 \(h\) 在这种情况下不必是有理函数。
工具书类
E、 S.Cheb Terrab,A.D.Roche,《对称性与一阶颂歌图案》,第10-12页
Rational Riccati Solver#
These functions are intended for internal use to solve a first order Riccati differential equation with atleast one rational particular solution.
- sympy.solvers.ode.riccati.riccati_normal(w, x, b1, b2)[源代码]#
Given a solution \(w(x)\) to the equation
\[w'(x) = b_0(x) + b_1(x)*w(x) + b_2(x)*w(x)^2\]and rational function coefficients \(b_1(x)\) and \(b_2(x)\), this function transforms the solution to give a solution \(y(x)\) for its corresponding normal Riccati ODE
\[y'(x) + y(x)^2 = a(x)\]using the transformation
\[y(x) = -b_2(x)*w(x) - b'_2(x)/(2*b_2(x)) - b_1(x)/2\]
- sympy.solvers.ode.riccati.riccati_inverse_normal(y, x, b1, b2, bp=None)[源代码]#
Inverse transforming the solution to the normal Riccati ODE to get the solution to the Riccati ODE.
- sympy.solvers.ode.riccati.riccati_reduced(eq, f, x)[源代码]#
Convert a Riccati ODE into its corresponding normal Riccati ODE.
- sympy.solvers.ode.riccati.construct_c(num, den, x, poles, muls)[源代码]#
Helper function to calculate the coefficients in the c-vector for each pole.
- sympy.solvers.ode.riccati.construct_d(num, den, x, val_inf)[源代码]#
Helper function to calculate the coefficients in the d-vector based on the valuation of the function at oo.
- sympy.solvers.ode.riccati.rational_laurent_series(num, den, x, r, m, n)[源代码]#
The function computes the Laurent series coefficients of a rational function.
- 参数:
num: A Poly object that is the numerator of `f(x)`.
den: A Poly object that is the denominator of `f(x)`.
x: The variable of expansion of the series.
r: The point of expansion of the series.
m: Multiplicity of r if r is a pole of `f(x)`. Should
be zero otherwise.
n: Order of the term upto which the series is expanded.
- 返回:
series: A dictionary that has power of the term as key
and coefficient of that term as value.
Below is a basic outline of how the Laurent series of a
rational function \(f(x)\) about \(x_0\) is being calculated -
Substitute \(x + x_0\) in place of \(x\). If \(x_0\)
is a pole of \(f(x)\), multiply the expression by \(x^m\)
where \(m\) is the multiplicity of \(x_0\). Denote the
the resulting expression as g(x). We do this substitution
so that we can now find the Laurent series of g(x) about
\(x = 0\).
We can then assume that the Laurent series of \(g(x)\)
takes the following form -
\[g(x) = \frac{num(x)}{den(x)} = \sum_{m = 0}^{\infty} a_m x^m\]where \(a_m\) denotes the Laurent series coefficients.
Multiply the denominator to the RHS of the equation
and form a recurrence relation for the coefficients \(a_m\).
- sympy.solvers.ode.riccati.compute_m_ybar(x, poles, choice, N)[源代码]#
Helper function to calculate -
1. m - The degree bound for the polynomial solution that must be found for the auxiliary differential equation.
2. ybar - Part of the solution which can be computed using the poles, c and d vectors.
- sympy.solvers.ode.riccati.solve_aux_eq(numa, dena, numy, deny, x, m)[源代码]#
Helper function to find a polynomial solution of degree m for the auxiliary differential equation.
- sympy.solvers.ode.riccati.remove_redundant_sols(sol1, sol2, x)[源代码]#
Helper function to remove redundant solutions to the differential equation.
- sympy.solvers.ode.riccati.get_gen_sol_from_part_sol(part_sols, a, x)[源代码]#
" Helper function which computes the general solution for a Riccati ODE from its particular solutions.
There are 3 cases to find the general solution from the particular solutions for a Riccati ODE depending on the number of particular solution(s) we have - 1, 2 or 3.
For more information, see Section 6 of "Methods of Solution of the Riccati Differential Equation" by D. R. Haaheim and F. M. Stein
颂诗体系#
这些功能供内部使用 dsolve()
对于微分方程组。
- sympy.solvers.ode.ode._linear_2eq_order1_type6(x, y, t, r, eq)[源代码]#
这种颂歌的方程是。
\[x'=f(t)x+g(t)y\]\[y'=a [f(t)+a h(t)] x+a公司 [g(t) - h(t)] Y\]首先将第一个方程乘以 \(-a\) 把它加到第二个方程中,得到
\[y'-a x'=-a h(t)(y-a x)\]设置 \(U = y - ax\) 积分我们得到的方程
\[y-ax=cU1e^{-a\inth(t)\,dt}\]代入第一方程中的y值,得到一阶常微分方程。解决后 \(x\) ,我们可以得到 \(y\) 通过替换 \(x\) 在第二个等式中。
- sympy.solvers.ode.ode._linear_2eq_order1_type7(x, y, t, r, eq)[源代码]#
这种颂歌的方程是。
\[x'=f(t)x+g(t)y\]\[y'=h(t)x+p(t)y\]微分第一个方程并代入 \(y\) 从第二个方程可以得到一个二阶线性方程
\[g x''-(fg+gp+g')x'+(fgp-g^{2}h+f g'-f'g)x=0\]如果满足以下条件,上述方程可以很容易地积分。
\(fgp - g^{2} h + f g' - f' g = 0\)
\(fgp - g^{2} h + f g' - f' g = ag, fg + gp + g' = bg\)
若满足第一个条件,则由电流解算器求解,在第二种情况下,它变成常系数微分方程,并由电流解算器求解。
否则,如果上述条件失败,则假定特定解决方案为 \(x = x_0(t)\) 和 \(y = y_0(t)\) 则通解表示为
\[x=C_1 x_0(t)+C_2 x_0(t)\int\frac{g(t)F(t)P(t)}{x_0^{2}(t)},dt\]\[y = C_1 y_0(t) + C_2 [\frac{F(t) P(t)}{x_0(t)} + y_0(t) \int \frac{g(t) F(t) P(t)}{x_0^{2}(t)} \,dt]\]其中C1和C2是任意常数,并且
\[F(t) = e^{\int f(t) \,dt}, P(t) = e^{\int p(t) \,dt}\]
- sympy.solvers.ode.systems.linear_ode_to_matrix(eqs, funcs, t, order)[源代码]#
线性常微分方程组的矩阵形式转换
- 参数:
eqs : list of SymPy expressions or equalities
将方程作为表达式(假设等于零)。
函数 :应用功能列表
常微分方程系统的因变量。
t :符号
自变量。
秩序 :内景
颂诗体系的秩序。
- 返回:
元组
(As, b)
在哪里?As
是矩阵的元组b
是表示矩阵方程rhs的矩阵。
- 加薪:
ODEOrderError
当ODE系统的顺序大于指定值时
ODENonlinearError
当常微分方程组为非线性时
解释
将线性常微分方程组表示为单矩阵微分方程 [1] . 例如,系统\(x'=x+y+1\)和\(y'=x-y\)可以表示为
\[A_1 X' = A_0 X + b\]其中,\(A_1\)和\(A_0\)是2\(矩阵的2倍,而\)b\(、\)X\(和\)X'\(是\)2\乘以1\(矩阵的\)X= [x, y] ^台币。
高阶系统用附加矩阵表示,例如二阶系统看起来像
\[A_2 X''=A_1 X'+A_0 X+b\]实例
>>> from sympy import Function, Symbol, Matrix, Eq >>> from sympy.solvers.ode.systems import linear_ode_to_matrix >>> t = Symbol('t') >>> x = Function('x') >>> y = Function('y')
我们可以创造一个线性的系统
>>> eqs = [ ... Eq(x(t).diff(t), x(t) + y(t) + 1), ... Eq(y(t).diff(t), x(t) - y(t)), ... ] >>> funcs = [x(t), y(t)] >>> order = 1 # 1st order system
现在
linear_ode_to_matrix
可以将其表示为矩阵微分方程。>>> (A1, A0), b = linear_ode_to_matrix(eqs, funcs, t, order) >>> A1 Matrix([ [1, 0], [0, 1]]) >>> A0 Matrix([ [1, 1], [1, -1]]) >>> b Matrix([ [1], [0]])
原始方程可以从这些矩阵中恢复:
>>> eqs_mat = Matrix([eq.lhs - eq.rhs for eq in eqs]) >>> X = Matrix(funcs) >>> A1 * X.diff(t) - A0 * X - b == eqs_mat True
如果系统的阶数大于系统的最大阶数,则会引发系统的最大阶数。
>>> eqs = [Eq(x(t).diff(t, 2), x(t).diff(t) + x(t)), Eq(y(t).diff(t), y(t) + x(t))] >>> linear_ode_to_matrix(eqs, funcs, t, 1) Traceback (most recent call last): ... ODEOrderError: Cannot represent system in 1-order form
如果方程组是非线性的,则提出了非线性误差。
>>> eqs = [Eq(x(t).diff(t), x(t) + y(t)), Eq(y(t).diff(t), y(t)**2 + x(t))] >>> linear_ode_to_matrix(eqs, funcs, t, 1) Traceback (most recent call last): ... ODENonlinearError: The system of ODEs is nonlinear.
参见
linear_eq_to_matrix
对于线性代数方程组。
工具书类
- sympy.solvers.ode.systems.canonical_odes(eqs, funcs, t)[源代码]#
求系统中最高阶导数的函数
- 参数:
eqs 名单
诗集目录
函数 名单
因变量列表
t :符号
自变量
- 返回:
表
解释
此函数输入ODE系统,并基于系统、因变量及其最高阶数,以以下形式返回系统:
\[X'(t)=A(t)X(t)+b(t)\]这里,\(X(t)\)是低阶因变量的向量,\(A(t)\)是系数矩阵,\(b(t)\)是非齐次项,\(X'(t)\)是因变量的最高阶向量。我们用规范形式一词来暗示上述形式的颂诗体系。
如果传递的系统有一个具有多个解的非线性项,则系统列表将以其规范形式返回。
实例
>>> from sympy import symbols, Function, Eq, Derivative >>> from sympy.solvers.ode.systems import canonical_odes >>> f, g = symbols("f g", cls=Function) >>> x, y = symbols("x y") >>> funcs = [f(x), g(x)] >>> eqs = [Eq(f(x).diff(x) - 7*f(x), 12*g(x)), Eq(g(x).diff(x) + g(x), 20*f(x))]
>>> canonical_eqs = canonical_odes(eqs, funcs, x) >>> canonical_eqs [[Eq(Derivative(f(x), x), 7*f(x) + 12*g(x)), Eq(Derivative(g(x), x), 20*f(x) - g(x))]]
>>> system = [Eq(Derivative(f(x), x)**2 - 2*Derivative(f(x), x) + 1, 4), Eq(-y*f(x) + Derivative(g(x), x), 0)]
>>> canonical_system = canonical_odes(system, funcs, x) >>> canonical_system [[Eq(Derivative(f(x), x), -1), Eq(Derivative(g(x), x), y*f(x))], [Eq(Derivative(f(x), x), 3), Eq(Derivative(g(x), x), y*f(x))]]
- sympy.solvers.ode.systems.linodesolve_type(A, t, b=None)[源代码]#
帮助函数,该函数确定要使用解决的ODE系统的类型
sympy.solvers.ode.systems.linodesolve()
- 参数:
A :矩阵
常微分方程组的系数矩阵
b :矩阵或无
系统的非齐次项。默认值为“无”。如果此参数为“无”,则假定系统是同构的。
- 返回:
双关语
- 加薪:
NotImplementedError
When the coefficient matrix does not have a commutative antiderivative
解释
此函数接受系数矩阵和/或非齐次项,并返回可通过
sympy.solvers.ode.systems.linodesolve()
.如果系统是常数系数齐次的,则返回“type1”
如果系统是常系数非齐次系统,则返回“type2”
如果系统是非常系数齐次系统,则返回“type3”
如果系统是非常系数非齐次系统,则返回“type4”
如果系统有一个可以分解为常系数矩阵的非常系数矩阵,则当系统为齐次或非齐次时,分别返回“type5”或“type6”。
注意,如果ODEs系统是“type3”或“type4”,那么除了类型之外,还返回系数矩阵的交换反导数。
如果系统无法解决
sympy.solvers.ode.systems.linodesolve()
,则引发NotImplementedError。实例
>>> from sympy import symbols, Matrix >>> from sympy.solvers.ode.systems import linodesolve_type >>> t = symbols("t") >>> A = Matrix([[1, 1], [2, 3]]) >>> b = Matrix([t, 1])
>>> linodesolve_type(A, t) {'antiderivative': None, 'type_of_equation': 'type1'}
>>> linodesolve_type(A, t, b=b) {'antiderivative': None, 'type_of_equation': 'type2'}
>>> A_t = Matrix([[1, t], [-t, 1]])
>>> linodesolve_type(A_t, t) {'antiderivative': Matrix([ [ t, t**2/2], [-t**2/2, t]]), 'type_of_equation': 'type3'}
>>> linodesolve_type(A_t, t, b=b) {'antiderivative': Matrix([ [ t, t**2/2], [-t**2/2, t]]), 'type_of_equation': 'type4'}
>>> A_non_commutative = Matrix([[1, t], [t, -1]]) >>> linodesolve_type(A_non_commutative, t) Traceback (most recent call last): ... NotImplementedError: The system does not have a commutative antiderivative, it cannot be solved by linodesolve.
参见
linodesolve
获取其信息的函数
- sympy.solvers.ode.systems.matrix_exp_jordan_form(A, t)[源代码]#
矩阵指数$exp(A t) 矩阵的$ A 和标量 t*。
- 参数:
A :矩阵
表达式\(\exp(A*t)中的矩阵\)A$$
t :符号
自变量
解释
返回\(\exp(A*t)\)的Jordan形式以及矩阵\(P\),以便:
\[\实验(A *t) = P * 表达式*P^{-1}\]实例
>>> from sympy import Matrix, Symbol >>> from sympy.solvers.ode.systems import matrix_exp, matrix_exp_jordan_form >>> t = Symbol('t')
我们将考虑2x2缺陷矩阵。这表明我们的方法即使对有缺陷的矩阵也是有效的。
>>> A = Matrix([[1, 1], [0, 1]])
可以看出,这个函数给出了Jordan范式和所需的可逆矩阵P。
>>> P, expJ = matrix_exp_jordan_form(A, t)
这里证明了这个函数返回的P和expJ是正确的,因为它们满足以下公式:P expJ公司 P_逆=exp(A*t)。
>>> P * expJ * P.inv() == matrix_exp(A, t) True
工具书类
- sympy.solvers.ode.systems.matrix_exp(A, t)[源代码]#
矩阵的指数\(\exp(A*t)\)
A
和标量t
.- 参数:
A :矩阵
表达式\(\exp(A*t)中的矩阵\)A$$
t :符号
自变量
解释
此函数通过执行简单的矩阵乘法返回\(\exp(A*t)\):
\[\实验(A *t) = P * 表达式*P^{-1}\]其中\(expJ\)是\(\exp(J*t)\)。\(J\)是A\(的约旦标准形式,\)P$是矩阵,因此:
\[A = P * J * P^{-1}\]矩阵指数\(\exp(A*t)\)出现在线性微分方程的解中。例如,如果\(x\)是一个向量,\(a\)是一个矩阵,那么初始值问题
\[\分形{dx(t)}{dt}=A\乘以x(t),x(0)=x0\]有独特的解决方案
\[x(t)=\exp(A t)x0\]实例
>>> from sympy import Symbol, Matrix, pprint >>> from sympy.solvers.ode.systems import matrix_exp >>> t = Symbol('t')
我们将考虑一个2x2矩阵来计算指数
>>> A = Matrix([[2, -5], [2, -4]]) >>> pprint(A) [2 -5] [ ] [2 -4]
现在,exp(A*t)如下所示:
>>> pprint(matrix_exp(A, t)) [ -t -t -t ] [3*e *sin(t) + e *cos(t) -5*e *sin(t) ] [ ] [ -t -t -t ] [ 2*e *sin(t) - 3*e *sin(t) + e *cos(t)]
参见
matrix_exp_jordan_form
对于Jordan正规型的指数
工具书类
- sympy.solvers.ode.systems.linodesolve(A, t, b=None, B=None, type='auto', doit=False, tau=None)[源代码]#
n方程组一阶线性微分方程组
- 参数:
A :矩阵
线性一阶常微分方程组的系数矩阵。
t :符号
常微分方程系统中的自变量。
b :矩阵或无
常微分系统中的非齐次项。如果没有通过,则假定为ODE的同构系统。
B :矩阵或无
系数矩阵的反导数。如果反导数没有通过,而解算器需要该项,则解算器将在内部计算它。
type :字符串
传递的ODE系统的类型。根据类型,计算解决方案。允许的类型值及其求解的相应系统为:常系数齐次的“类型1”,常系数非均匀的“类型2”,非常系数非均匀的“类型3”,非常系数非均匀的“类型4”,“类型5”和“类型6”分别用于非常系数齐次系统和非齐次系统,其中系数矩阵可分解为常系数矩阵。默认值为“auto”,这将让解算器决定传递的系统的正确类型。
doit :布尔值
计算解决方案如果为True,则默认值为False
陶:表情
用来代替 \(t\) 在得到系统的解后。
- 返回:
表
- 加薪:
ValueError
This error is raised when the coefficient matrix, non-homogeneous term or the antiderivative, if passed, are not a matrix or do not have correct dimensions
NonSquareMatrixError
When the coefficient matrix or its antiderivative, if passed is not a square matrix
NotImplementedError
If the coefficient matrix does not have a commutative antiderivative
解释
This solver solves the system of ODEs of the following form:
\[X'(t)=A(t)X(t)+b(t)\]这里,\(A(t)\)是系数矩阵,\(X(t)\)是n个自变量的向量,\(b(t)\)是非齐次项,\(X'(t)\)是\(X(t)的导数\)
根据\(A(t)\)和\(b(t)\)的属性,此解算器将以不同的方式计算解决方案。
当\(A(t)\)为常数系数矩阵,\(b(t)\)为零向量,即系统为齐次系统时,系统为“类型1”。解决方案是:
\[X(t)=\exp(A t)C\]这里,\(C\)是常数向量,\(a\)是常数系数矩阵。
当\(A(t)\)为常系数矩阵,\(b(t)\)为非零,即系统为非齐次系统时,系统为“类型2”。解决方案是:
\[X(t)=e^{att}(\inte^{-att}b\,dt+C)\]当\(A(t)\)是系数矩阵,使得其与其反导数\(B(t)\)和\(B(t)\)交换为零向量,即系统是齐次的,则系统为“类型3”。解决方案是:
\[X(t)=\exp(B(t))C\]当\(A(t)\)与其反导数\(B(t)\)可交换且\(B(t)\)为非零,即系统为非齐次系统时,系统为“类型4”。解决方案是:
\[X(t)=e^{B(t)}(\int e^{-B(t)}B(t)\,dt+C)\]当\(A(t)\)是一个系数矩阵时,它可以分解为标量矩阵和常数系数矩阵:
\[A(t)=f(t)*A\]其中,\(f(t)\)是自变量\(t\)中的标量表达式,\(a\)是常量矩阵,则可以进行以下替换:
\[tau=\int f(t)dt,X(t)=Y(τ),b(t)=b(f^{-1}(tau))\]这里,非齐次项的代换只在其非零时进行。使用这些替换,我们的原始系统变成:
\[Y'(τ)=A*Y(τ)+b(τ)/f(τ)\]根据系统的均匀性,使用“类型1”或“类型2”的解决方案,可以轻松解决上述系统。当我们得到\(Y(tau)\)的解后,我们将\(tau\)的解替换为\(t\),以获得\(X(t)\)
\[X(t)=Y(τ)\]“类型5”和“类型6”的系统有一个可交换的反导数,但我们使用这个解决方案是因为它计算速度更快。
因为它的四个矩阵的逆解都是一个常数矩阵。
这个函数的另一个特点是,如果有人想替换自变量的值,他们可以通过替换 \(tau\) 解将用传递的表达式替换自变量 (\(tau\) )
实例
要直接使用此函数求解ODEs系统,必须按正确的顺序完成几件事。错误的函数输入将导致错误的结果。
>>> from sympy import symbols, Function, Eq >>> from sympy.solvers.ode.systems import canonical_odes, linear_ode_to_matrix, linodesolve, linodesolve_type >>> from sympy.solvers.ode.subscheck import checkodesol >>> f, g = symbols("f, g", cls=Function) >>> x, a = symbols("x, a") >>> funcs = [f(x), g(x)] >>> eqs = [Eq(f(x).diff(x) - f(x), a*g(x) + 1), Eq(g(x).diff(x) + g(x), a*f(x))]
在这里,需要注意的是,在我们推导系数矩阵之前,重要的是要将ODEs系统转换成所需的形式。为此我们将使用
sympy.solvers.ode.systems.canonical_odes()
.>>> eqs = canonical_odes(eqs, funcs, x) >>> eqs [[Eq(Derivative(f(x), x), a*g(x) + f(x) + 1), Eq(Derivative(g(x), x), a*f(x) - g(x))]]
现在,我们将使用
sympy.solvers.ode.systems.linear_ode_to_matrix()
得到系数矩阵和非齐次项。>>> eqs = eqs[0] >>> (A1, A0), b = linear_ode_to_matrix(eqs, funcs, x, 1) >>> A = A0
我们已经准备好了系数矩阵和非齐次项。现在,我们可以使用
sympy.solvers.ode.systems.linodesolve_type()
获取ODE系统的信息,最终将其传递给解算器。>>> system_info = linodesolve_type(A, x, b=b) >>> sol_vector = linodesolve(A, x, b=b, B=system_info['antiderivative'], type=system_info['type_of_equation'])
现在,我们可以用
sympy.solvers.ode.checkodesol()
>>> sol = [Eq(f, s) for f, s in zip(funcs, sol_vector)] >>> checkodesol(eqs, sol) (True, [0, 0])
我们也可以使用doit方法来计算函数传递的解。
>>> sol_vector_evaluated = linodesolve(A, x, b=b, type="type2", doit=True)
现在,我们来看一个常微分方程组。
>>> eqs = [Eq(f(x).diff(x), f(x) + x*g(x)), Eq(g(x).diff(x), -x*f(x) + g(x))]
The system defined above is already in the desired form, so we do not have to convert it.
>>> (A1, A0), b = linear_ode_to_matrix(eqs, funcs, x, 1) >>> A = A0
用户还可以传递ODEs的type3和type4所需的交换反除法。传递错误的结果将导致错误的结果。如果系数矩阵与其反导数不可交换,则
sympy.solvers.ode.systems.linodesolve_type()
引发NotImplementedError。如果它有一个可交换的反导数,那么函数只返回有关系统的信息。>>> system_info = linodesolve_type(A, x, b=b)
现在,我们可以通过反除法作为一个论点来得到解决方案。如果未传递系统信息,则解算器将在内部计算所需参数。
>>> sol_vector = linodesolve(A, x, b=b)
再次,我们可以验证得到的解。
>>> sol = [Eq(f, s) for f, s in zip(funcs, sol_vector)] >>> checkodesol(eqs, sol) (True, [0, 0])
参见
linear_ode_to_matrix
系数矩阵计算函数
canonical_odes
敖德萨体系的表现变化
linodesolve_type
获取有关要在该解算器中传递的ODE系统的信息
- sympy.solvers.ode.ode._nonlinear_2eq_order1_type1(x, y, t, eq)[源代码]#
方程:
\[x'=x^n F(x,y)\]\[y'=g(y)F(x,y)\]解决方案:
\[x=\varphi(y),\int\frac{1}{g(y)F(\varphi(y),y)}\,dy=t+C_2\]在哪里?
如果 \(n \neq 1\)
\[\varphi = [C_1 + (1-n) \int \frac{1}{g(y)} \,dy]^{\frac{1}{1-n}}\]如果 \(n = 1\)
\[\varphi=C_1e^{\int\frac{1}{g(y)}\,dy}\]在哪里? \(C_1\) 和 \(C_2\) 是任意常数。
- sympy.solvers.ode.ode._nonlinear_2eq_order1_type2(x, y, t, eq)[源代码]#
方程:
\[x'=e^{\lambda x}F(x,y)\]\[y'=g(y)F(x,y)\]解决方案:
\[x=\varphi(y),\int\frac{1}{g(y)F(\varphi(y),y)}\,dy=t+C_2\]在哪里?
如果 \(\lambda \neq 0\)
\[\varphi=-\frac{1}{\lambda}log(C_1-\lambda\int\frac{1}{g(y)}\,dy)\]如果 \(\lambda = 0\)
\[\varphi=C_1+\int\frac{1}{g(y)}\,dy\]在哪里? \(C_1\) 和 \(C_2\) 是任意常数。
- sympy.solvers.ode.ode._nonlinear_2eq_order1_type3(x, y, t, eq)[源代码]#
一般形式自治系统
\[x'=F(x,y)\]\[y'=G(x,y)\]假设 \(y = y(x, C_1)\) 在哪里? \(C_1\) 任意常数是一阶方程的通解
\[F(x,y)y’’x=G(x,y)\]那么原始方程组的通解就有了形式
\[\int\frac{1}{F(x,y(x,C_1))}\,dx=t+C_1\]
- sympy.solvers.ode.ode._nonlinear_2eq_order1_type4(x, y, t, eq)[源代码]#
公式:
\[x'=f_1(x)g_1(y)\phi(x,y,t)\]\[y'=f_2(x)g_2(y)\phi(x,y,t)\]第一积分:
\[\int\frac{f_2(x)}{f1(x)}\,dx-\int\frac{g_1(y)}{g_2(y)}\,dy=C\]在哪里? \(C\) 常数是任意的。
关于求解 \(x\) (责任)。, \(y\) )将得到的表达式代入原解的任一方程,得到一个一阶方程 \(y\) (责任)。, \(x\) )
- sympy.solvers.ode.ode._nonlinear_2eq_order1_type5(func, t, eq)[源代码]#
克莱奥特颂歌体系
\[x=t x'+F(x',y')\]\[y=t y'+G(x',y')\]以下是系统的解决方案
\((i)\) 直线:
\[x=C_1 t+F(C_1,C_2),y=C_2 t+G(C_1,C_2)\]在哪里? \(C_1\) 和 \(C_2\) 是任意常数;
\((ii)\) 上述线路的信封;
\((iii)\) 由线段组成的连续可微直线 \((i)\) 和 \((ii)\) .
- sympy.solvers.ode.ode._nonlinear_3eq_order1_type1(x, y, z, t, eq)[源代码]#
方程:
\[a x'=(b-c)y z,\n空间b y'=(c-a)z x,\n空间c z'=(a-b)x y\]第一积分:
\[a x^{2}+by^{2}+cz^{2}=c1\]\[a ^{2}x^{2}+b^{2}y^{2}+c^{2}z^{2}=c}2}\]在哪里? \(C_1\) 和 \(C_2\) 是任意常数。关于求解 \(y\) 和 \(z\) 将得到的表达式代入系统的第一个方程,得到了一个可分的一阶方程 \(x\) . 同样的,对于另外两个方程,我们将得到一阶方程 \(y\) 和 \(z\) 也是。
工具书类
- sympy.solvers.ode.ode._nonlinear_3eq_order1_type2(x, y, z, t, eq)[源代码]#
方程:
\[a x'=(b-c)y z f(x,y,z,t)\]\[b y'=(c-a)z x f(x,y,z,t)\]\[c z'=(a-b)x y f(x,y,z,t)\]第一积分:
\[a x^{2}+by^{2}+cz^{2}=c1\]\[a ^{2}x^{2}+b^{2}y^{2}+c^{2}z^{2}=c}2}\]在哪里? \(C_1\) 和 \(C_2\) 是任意常数。关于求解 \(y\) 和 \(z\) 把得到的表达式代入系统的第一个方程,我们得到了一个一阶微分方程 \(x\) . 同样地,对于另外两个方程,我们将得到一阶方程 \(y\) 和 \(z\) .
工具书类
- sympy.solvers.ode.ode._nonlinear_3eq_order1_type3(x, y, z, t, eq)[源代码]#
方程:
\[x'=c F_2-b F_3,\n空间y'=a F_3-c F_1,\n空间z'=b F_1-a F_2\]在哪里? \(F_n = F_n(x, y, z, t)\) .
第一积分:
\[a x+b y+c z=c_1,\]其中C是任意常数。
2如果我们假设函数 \(F_n\) 独立于 \(t\) ,i.e, \(F_n\) = \(F_n (x, y, z)\) 然后,关于消除 \(t\) 和 \(z\) 从系统的前两个方程出发,得到一阶方程
\[\frac{dy}{dx}=\frac{afu 3(x,y,z)-cf1(x,y,z)}{cf2(x,y,z)-\]在哪里? \(z = \frac{{1}}{{c}} (C_1 - a x - b y)\)
工具书类
- sympy.solvers.ode.ode._nonlinear_3eq_order1_type4(x, y, z, t, eq)[源代码]#
方程:
\[x'=cz F_2-b y F_3,\n空间y'=a x F_3-c z F_1,\n空间z'=b y F_1-a x F_2\]在哪里? \(F_n = F_n (x, y, z, t)\)
第一积分:
\[a x^{2}+by^{2}+cz^{2}=c1\]在哪里? \(C\) 常数是任意的。
2假设函数 \(F_n\) 独立于 \(t\) : \(F_n = F_n (x, y, z)\) . 然后在消除 \(t\) 和 \(z\) 从系统的前两个方程中,可以得到一阶方程
\[\frac{dy}{dx}=\frac{a x F_3(x,y,z)-czf_1(x,y,z)}\]在哪里? \(z = \pm \sqrt{{\frac{{1}}{{c}} (C_1 - a x^{{2}} - b y^{{2}})}}\)
工具书类
- sympy.solvers.ode.ode._nonlinear_3eq_order1_type5(x, y, z, t, eq)[源代码]#
- \[x'=x(c F_2-b F_3),\n空间y'=y(a F_3-c F_1),\n空间z'=z(b F_1-a F_2)\]
在哪里? \(F_n = F_n (x, y, z, t)\) 是任意函数。
第一积分:
\[\left | x\ right | ^{a}\ left | y\ right | ^{b}\left | z\ right | ^{c}=c_1\]在哪里? \(C\) 是任意常数。如果函数 \(F_n\) 独立于 \(t\) ,然后,通过消除 \(t\) 和 \(z\) 从系统的前两个方程中,可以得到一阶方程。
工具书类
ode模块信息#
本模块包含 dsolve()
以及它使用的不同助手函数。
dsolve()
解常微分方程。有关各种函数的用法,请参见docstring。请注意,偏微分方程支持 pde.py
. 请注意,提示函数有描述其各种方法的docstring,但它们是用于内部使用的。使用 dsolve(ode, func, hint=hint)
使用一个特定的提示来解决一个ODE。另请参见上的docstring dsolve()
.
本模块中的功能
以下是本模块中的用户功能:
dsolve()
-ODEs解决了。
classify_ode()
-将ode分类为dsolve()
.
checkodesol()
-检查方程式是否是ODE的解。
homogeneous_order()
-返回表达式的同构顺序。
infinitesimals()
-返回一个ODE的点变换李群的无穷小,使其不变性。
checkinfsol()
-检查给定的无穷小是否是一阶代码的实际无穷小。这些是供内部使用的非解算器辅助函数。用户应该使用各种选项来
dsolve()
要获得这些函数提供的功能:
odesimp()
-做所有形式的颂歌简化。
ode_sol_simplicity()
-通过简单性比较解决方案的关键功能。
constantsimp()
-简化任意常数。
constant_renumber()
-对任意常数重新编号。
_handle_Integral()
-计算未赋值积分。另请参见这些函数的docstring。
当前实现的解算器方法
以下方法用于求解常微分方程。有关每个(运行)的更多信息,请参见各种提示函数的docstrings help(ode)
):
一阶可分离微分方程。
一阶微分方程,其系数或 \(dx\) 和 \(dy\) 函数是同阶齐次的吗。
一阶精确微分方程。
一阶线性微分方程。
一阶伯努利微分方程。
一阶微分方程的幂级数解。
求解一阶微分方程的李群方法。
二阶Liouville微分方程。
二阶微分方程常奇点和正则奇点的幂级数解。
\(n\) 可以用代数重排和积分法求解的四阶微分方程。
\(n\) 一阶常系数线性齐次微分方程。
\(n\) 用待定系数法求解一阶常系数线性非齐次微分方程。
\(n\) 用参数变分法求解一类常系数线性非齐次微分方程。
本模块背后的理念
这个模块被设计成可以很容易地添加新的ODE解算方法,而不必为其他方法的解算代码带来麻烦。我们的想法是 classify_ode()
函数,它接受一个ODE并告诉您什么提示(如果有的话)将解决这个ODE。它不需要求解ODE就可以做到这一点,所以速度很快。每种求解方法都是一个提示,它有自己的函数,名为 ode_<hint>
. 该函数接收ODE和收集到的任何匹配表达式 classify_ode()
并返回一个已解决的结果。如果这个结果中有任何积分,提示函数将返回一个未赋值的 Integral
班级。 dsolve()
,它是围绕这一切的用户包装函数,然后调用 odesimp()
结果,除其他外,它将尝试求解因变量的方程(我们要求解的函数),简化表达式中的任意常数,并计算任何积分(如果提示允许)。
如何添加新的求解方法
如果你有你想要的颂歌 dsolve()
为了能够解决,尽量避免在这里添加特殊情况代码。相反,试着找到一个通用的方法来解决你的颂歌,以及其他方法。这边,那个 ode
模块将变得更加健壮,并且不受特殊情况下黑客攻击的阻碍。WolphramAlpha和Maple's DETools [odeadvisor公司] 函数是两种可用于对特定ODE进行分类的资源。方法使用 \(n\) 如果可能的话,不要只使用特定的顺序。
To add a new method, there are a few things that you need to do. First, you
need a hint name for your method. Try to name your hint so that it is
unambiguous with all other methods, including ones that may not be implemented
yet. If your method uses integrals, also include a hint_Integral
hint.
If there is more than one way to solve ODEs with your method, include a hint
for each one, as well as a <hint>_best
hint. Your ode_<hint>_best()
function should choose the best using min with ode_sol_simplicity
as the
key argument. See
HomogeneousCoeffBest
, for example.
The function that uses your method will be called ode_<hint>()
, so the
hint must only use characters that are allowed in a Python function name
(alphanumeric characters and the underscore '_
' character). Include a
function for every hint, except for _Integral
hints
(dsolve()
takes care of those automatically).
Hint names should be all lowercase, unless a word is commonly capitalized
(such as Integral or Bernoulli). If you have a hint that you do not want to
run with all_Integral
that does not have an _Integral
counterpart (such
as a best hint that would defeat the purpose of all_Integral
), you will
need to remove it manually in the dsolve()
code.
See also the classify_ode()
docstring for
guidelines on writing a hint name.
确定 一般来说 方法返回的解决方案与其他可能解决相同ode的方法相比如何。然后,把你的暗示放在 allhints
按应该调用它们的顺序进行元组。这个元组的顺序决定了哪些提示是默认的。请注意,异常是可以的,因为用户很容易用 dsolve()
. 一般来说, _Integral
变体应该放在列表的末尾,并且 _best
变体应该放在它们所应用的各种提示之前。例如 undetermined_coefficients
提示出现在 variation_of_parameters
提示是因为,尽管参数的变化比待定系数更一般,但待定系数通常会比参数变化更容易解决ODE的结果,而且不需要积分,因此速度更快。
Next, you need to have a match expression or a function that matches the type
of the ODE, which you should put in classify_ode()
(if the match function is more than just a few lines. It should match the
ODE without solving for it as much as possible, so that
classify_ode()
remains fast and is not hindered by
bugs in solving code. Be sure to consider corner cases. For example, if your
solution method involves dividing by something, make sure you exclude the case
where that division will be 0.
在大多数情况下,ODE的匹配也会给您解决它所需的各个部分。你应该把它放进字典里 (.match()
将为您完成此操作),并将其添加为 matching_hints['hint'] = matchdict
在 classify_ode()
. classify_ode()
然后把这个寄给 dsolve()
,它将把它作为 match
争论。您的函数应该命名为 ode_<hint>(eq, func, order, match)`. If you need to send more information, put it in the `` 匹配字典。例如,如果必须在 :py:meth:`~sympy.solvers.ode.classify_ode` 要匹配ODE,需要使用 `match` dict访问它。您可以使用 ``func.args[0]
,以及因变量(您试图求解的函数)作为 func.func
. 如果,当你试图解决颂歌,你发现你不能,提高 NotImplementedError
. dsolve()
将使用 all
元提示,而不是导致整个例程失败。
向函数中添加一个docstring,该函数描述所使用的方法。与SymPy中的任何其他内容一样,除了在中的实际测试之外,还需要向docstring添加doctest test_ode.py
. 尝试与其他提示函数的docstring保持一致。将您的方法添加到此docstring顶部的列表中。另外,将您的方法添加到 ode.rst
在 docs/src
目录,这样Sphinx文档将把它的docstring拉到主SymPy文档中。确保通过运行 make html
从doc目录中验证docstring格式是否正确。
如果您的解决方法涉及集成,请使用 Integral
而不是 integrate()
. 这允许用户通过使用 _Integral
你暗示的变体。在大多数情况下 sympy.core.basic.Basic.doit()
将集成您的解决方案。如果不是这样,您将需要编写特殊代码 _handle_Integral()
. 任意常量应该是名为 C1
, C2
等等。所有解决方案方法都应该返回一个相等实例。如果需要任意数量的任意常数,可以使用 constants = numbered_symbols(prefix='C', cls=Symbol, start=1)
. 如果可以用一般的方法求解相依函数,那么就这样做。否则,尽你所能,但不要在你的 ode_<hint>()
功能。 odesimp()
会尝试为你解决问题,所以你不需要这么做。最后,如果您的ODE有一个可以应用于您的解决方案的通用简化,您可以在 odesimp()
为了它。例如,从 1st_homogeneous_coeff
暗示往往有很多 log
条件,所以 odesimp()
电话 logcombine()
在它们上(这也有助于将任意常数写成 log(C1)
而不是 C1
在这种情况下)。还可以考虑一些常见的方法来重新安排您的解决方案 constantsimp()
好好利用它。最好简化一下 odesimp()
而不是在您的方法中,因为它可以在 dsolve()
. 如果你有任何的简化,一定要用你的函数 if match.get('simplify', True):
,特别是如果它可以是缓慢的或如果它可以减少解决方案的领域。
Finally, as with every contribution to SymPy, your method will need to be
tested. Add a test for each method in test_ode.py
. Follow the
conventions there, i.e., test the solver using dsolve(eq, f(x),
hint=your_hint)
, and also test the solution using
checkodesol()
(you can put these in a separate
tests and skip/XFAIL if it runs too slow/does not work). Be sure to call your
hint specifically in dsolve()
, that way the test
will not be broken simply by the introduction of another matching hint. If your
method works for higher order (>1) ODEs, you will need to run sol =
constant_renumber(sol, 'C', 1, order)
for each solution, where order
is
the order of the ODE. This is because constant_renumber
renumbers the
arbitrary constants by printing order, which is platform dependent. Try to
test every corner case of your solver, including a range of orders if it is a
\(n\)th order solver, but if your solver is slow, such as if it involves hard
integration, try to keep the test run time down.
请随意重构现有的提示,以避免重复代码或造成不一致。如果您可以证明您的方法与现有方法完全相同,包括在获得解决方案的简单性和速度方面,那么您可以删除旧的、不太通用的方法。现有代码在 test_ode.py
,所以,如果有任何东西被破坏,其中一个测试肯定会失败。
这些功能不适用于最终用户。