如何使用 DSolve:用户指南

简介

本教程旨在提供一个独立的工作指南,帮助大家了解如何用 DSolve 求解各种类型的问题.

使用 DSolve 的第一步是正确设置问题. 下一步是使用 DSolve 获取解的表达式. 算出解后,可以使用符号或数字技术进行验证,也可以用 Wolfram 系统函数(如 PlotPlot3DContourPlot)画出解的曲线. 解的曲线图通常会告诉我们一些不能从解的解析表达式观察出来的信息.

如果没有为问题指定边界条件,则 DSolve 的输出是包含任意参数的某种形式的通解. 可用 GeneratedParameters 选项标记这些任意参数.

在许多应用中,微分方程包含符号参数,例如逻辑方程中的增长率. 微分方程还可以包含非精确量,如以前的计算产生的机器数. DSolve 允许使用符号参数和非精确量,但最好注意它们的存在并正确对解进行释义.

DSolve 在计算过程中做出任何假设或遇到困难时,它会发出一条对问题进行概述的警告信息. 通常可以忽略这些消息,但有时它们指出了答案中存在的严重的局限性.

对问题的陈述进行分析以发现可能存在的歧义,这种做法非常有益,它可以确保问题的适定性,以便能够从 DSolve 获得有意义的答案.

设置问题

DSolve 的第一个参数是微分方程,第二个参数是未知函数,最后一个参数给定自变量.

以下是使用 DSolve 求解一阶线性 ODE 的输入. 变量 sol 表示下一步中要用到的解:

DSolve 的输出是微分方程的解的列表. 由于某些方程式有多个解,因此需要额外的列表. 此处,由于方程是 1 阶的且是线性的,所以只有一个解:y[x]->+-5 x C[1]. 因为没有指定初始条件,解中含有不确定常数 C[1]. 可通过元素指定从解的列表中将解提取出来.

将解提取出来:

这种形式的解对于求 自身很有用,但不适用于求 的导数或 在某一点的值.

这里是解给出的 的值:
解不适用于 ,因为解只是针对 的规则:

如果需要将解用在下一步中,最好使用 而不是 来指定未知函数. 下面用 Function[x,expr] 类型的纯函数给出解.

这里,用 指定未知函数. 解是一个纯函数:

当解是纯函数时,可求出 的导数的表达式和特定点上 的值.

下面给出了 的表达式:

当一个问题有多个解时,可以从解的列表中选择个别解,也可以直接使用列表.

以下求解非线性一阶方程.有两个解:
可通过指定元素将解提取出来:
返回两个表达式:

如果要求解方程组,DSolve 的第一个参数必须是方程列表,第二个参数必须是未知函数的列表.

下面的例子是有三个未知数的一阶线性方程组. 因为是线性的,所以只有一个解:

方程组的每个解都是未知函数的替换规则列表. 如上所示,可以循例提取未知函数的表达式.

下面给出了未知函数的表达式列表. 可用 Simplify 返回简化形式的表达式:

如果针对该问题给定了初始条件,则可以消除一些或所有未确定的常数.

这里给出了未知函数及其导数在初始点的值:
如果仅指定了初始值,则解仍包含任意常量:

对于偏微分方程,DSolve 的第三个参数是方程的自变量列表.

下面求解自变量为 的 PDE. C[1] 表示 y + Cos[y[x]] 的任意函数:

微分代数方程的指定方式与常微分方程组相同.

下面是给定了初始条件的 DAE:

请注意,并不是总能够以明确的形式给出问题的解. 下面的例子用未计算的 Solve 对象或 InverseFunction 给出解.

无法给出明确形式的解. 输出表示的是一个隐式解:
同样可通过元素指定提取解:
InverseFunction 对象给出下面方程的解:
通过消除 InverseFunction 对象,可以将每个解重写为隐式方程:

解的验证

可以使用各种方法验证 DSolve 给出的解. 最简单的方法是将解代回方程式. 如果结果为 True,则为有效解.

在下面这个简单的例子中,我们把解代回方程进行验证. 为方便以后的步骤,DSolve 的第一个参数被分配给 eqn
此例中,把解代回方程以验证方程和初始条件:

有时,代回的结果不是 TrueFalse 这样简单. 可以通过使用 Simplify 简化结果来验证. 如果简化结果为 True,则为有效解.

以下是二阶非齐次方程的通解:
将解代回方程:
Simplify 验证解:
这是一个线性 PDE,可用 Simplify 验证解:

如果方程涉及特殊函数,则可能需要使用 FullSimplify 来验证解.

以下是一个涉及贝塞尔函数的例子:

如果解很大或者 SimplifyFullSimplify 无法验证解,则可以使用 RandomRealRandomComplex 为问题中的所有变量和参数生成值,然后进行数值验证. 在这种情况下,建议使用几组随机值重复检查.

以下是数值验证的例子:

虽然数值验证不能完全确定地验证解,但可以通过使用更高的精度或允许变量采用复值来进行更严格的检查.

下面以更高的精度验证之前的解:
用随机复数验证以前的解:

只有在给出显式解时,才使用之前的方法. 最后一个例子显示了如何验证一阶 ODE 的隐式解.

求解一阶 ODE:
化简其导数来验证解:

绘制解

绘制 DSolve 给出的解的曲线可以提供有关解性质的有用信息,例如,它是否是振荡的. 如果从理论上或通过绘制与微分方程相关的向量场知道解的形状,它也可以作为验证解的一种方式. 下面是一些使用不同的 Wolfram 语言绘图函数的例子.

这是线性一阶方程的通解:
可以用 Plot 绘制常数 C[1] 取特定值的解. 使用 Evaluate 减少了 Plot 所花费的时间,并且还有助于处理解有断点的情况:
下面是线性二阶 ODE 的曲线,初始值为 0:
这个非线性方程有两个解,可将它们绘制在同一张图上:
这个 Abel ODE 的解是以隐式形式给出的:
等高线图可用于研究解的性质. 每个等高线对应于一个 C[1] 取特定值的 ODE 的解:
这里绘制的是两个线性 ODE 方程组的解. Plot 中的 WorkingPrecision 选项是必需的,因为解相当复杂:
ParametricPlot 函数可用于跟踪平面中解的曲线 {x[t],y[t]}
以下是 DAE 的解的曲线图:
下面是线性 PDE 的通解:
以下绘制的是任意函数 C[1] 取特定值时解的曲面图:

生成的参数

微分方程的通解含有未确定的系数,记作 C[1]C[2] 等.

此例有一个未确定的参数 C[1]

要更改未确定参数的名称,请使用 GeneratedParameters 选项.

将未确定系数的名称改为 P[1]

参数 C 应该被认为是一个纯函数,它作用于一组索引以产生不同的常数 C[i].

以下显示了 C 的行为:

在内部,使用纯函数允许 DSolve 正确地增大高阶 ODE 和 ODE 方程组的解的 C[i] 中的参数 i.

可用纯函数指定 GeneratedParameters

如果要用其他值(默认值为 1)开始对参数进行索引,则使用纯函数特别有用.

下面用纯函数标记之前例子中的参数,使用 const[2]const[3]

有时可使用下标或其他样式显示参数的索引.

此处,用带有下标的变量命名参数:

最后,通过使用 Module 变量,可在不同的 DSolve 调用中得到独特的参数名.

同样的 DSolve 调用产生了不同的参数名:

完整解

含有多项式或有理函数系数的线性 ODE 的解可以用完整函数 DifferentialRoot 表示.

求解含有多项式系数的线性微分方程:
绘制解:

选项 Method"Holonomic" 强制 DSolve 返回线性 ODE 的完整解.

求解线性 ODE:
返回线性 ODE 的完整解:

奇异解

默认情况下,DSolve 返回线性或非线性 ODE 的依赖于任意参数的通解. 对于某些非线性 ODE,也可能存在奇异解. 这些奇异解不能通过给通解中的任意常数赋特定值来获得,但在动力系统研究等方面很有用.

DSolve 选项 IncludeSingularSolutionsTrue 返回非线性 ODE 的奇异解和通解.

为了说明这一点,请考虑以下 Clairaut ODE,其通解是一系列直线:
这种情况下,奇异解是直线族的包络线(envelope)
下图显示了通解以及该直线族形成的包络线:
来看第二个例子,考虑以下逻辑方程:
这种情况下的奇异解是平衡解:
下图显示了通解以及该曲线族形成的包络线:

假设

在某些情况下,根据参数或变量的特定类型和范围 ODE 有不同的解. DSolve 中的 Assumptions 选项允许指定参数和变量的类型或范围以选择必要的解.

求解二阶线性微分方程的特征值问题:
Assumptions 选项指定了参数 的范围:
指定自变量 为实数,解 ODE:

符号参数和非精确量

实际出现的微分方程有两种类型.

  • 方程中唯一的变量是自变量和因变量. 因此,DSolve 的第一个参数中出现的所有变量也出现在第二个或第三个参数中.
  • 方程中还有其他符号量,如质量和弹簧常数. 这种情况下,解取决于自变量、因变量和其他符号参数.
第一种类型的例子:
第二种类型的例子. 方程中有一个符号参数

DSolve 有能力处理这两种方程. 对于第二类方程,获取参数取所有可能的值时的解非常有用.

以下是参数 取不同值时的上面的解的曲线图:

应该注意,符号参数的存在可能导致相当复杂的输出.

可从下面的例子([K59] 的第 401 页,方程 2.14)中看出这一点:

然而,对于参数的某些特殊值,解可能会变得非常简单.

如果 取以下值,解将变得异常简单:

偶尔会出现这种情况,解对参数的大多数值都有效,但不是全部.

由于此例中的输入在 处无效,因此解也有相同的限制:
当然,在这种情况下有一个简单的补救措施,即令

总之,能求解含有符号参数的微分方程是任何符号求解器(如 DSolve)必须拥有的强大武器. 但是,应注意以下几点.

  • 解可能很复杂,并且此类计算通常需要大量时间和内存.
  • 答案可能对参数的某些特殊值无效.
  • 对于参数的某些特殊值,可能很容易对解进行符号式验证,但一般情况下,数值验证法更可取.

Wolfram 语言中的数值量可以有三种类型:无限精度、机器精度或任意精度. 第一种类型的数字被称为 "exact",而其余两种类型表示的是不完整的信息,因此被称为 "inexact".

下面的例子显示了这三种数字:

由于 DSolve 是一个符号求解器,因此它使用的算法主要基于输入是精确的这个假设. 但是,DSolve 同样以普通方式处理含有非精确量的方程.

这些方程分别含有非精确数字 3. 和 3.`40:

非精确输入有时可能会出现,例如,当方程中的系数来自之前的计算并且只是近似值时. 这种情况下,将方程转换为精确形式可能不切实际,因为这可能会显著减慢计算速度.

这是一个线性 ODE 方程组,每个方程都具有精确的系数. 请注意,即使 的值非常小,也需要很长时间才能完成计算:
对解进行验证. 由于解很复杂,因此使用数值验证方法:
如果只引入一个非精确量(在函数 中),求解的速度会快得多:

因此,即使在如 DSolve 这样的符号函数内,也要尽量使用非精确量. 还要注意的是,这种情况下获得的解可能会有一定的数值误差,应该仔细检查. 因此,如果题目不是太庞大(例如,方程的数量少于五个),则应使用 Rationalize 函数将输入转换为精确形式.

以下方程含有非精确量:
在求解前将方程转换为精确形式:

问题是否为适定问题?

如果未指定初始条件或边界条件,DSolve 将返回问题的通解.

返回方程的通解:

但是,如果指定了初始条件或边界条件,DSolve 的输出必须满足所给微分方程及给定条件.

下面的例子给出了边界条件:

这种情况下,应该好好检查以下 DSolve 求解的是否是一个合理的问题,换句话说,检查问题的适定性. 如果能确保解存在于某些众所周知的函数类(例如,解析函数)中,解是惟一的,且解连续地取决于数据,则说初始值或边界值问题是适定问题. 给定一个 阶 ODE(或 个一阶方程组成的方程组)和 个初始条件,有标准存在和唯一性定理,表明该问题在一组特定条件下是适定的. 上个例子中的一阶线性 ODE 的右侧是 的多项式,因此是无限可微的. 所以我们完全可以应用皮卡的存在和唯一性定理,因为只需要右侧是 Lipschitz 连续的.

实际中出现的大多数问题都是适定的,因为它们来自可靠的理论. 但是,请注意,也有例外,下面是 DSolve 可能难以找到问题的满意的解的例子.

这里是一阶 ODE 的解,其中右侧在 0 处不满足 Lipschitz 条件:
通解有两个分支:
这个初始值问题在初始条件周围的区域中是适定的,因此 DSolve 成功地为给定的初始条件挑选出正确的分支:
这是一个二阶 ODE. 边界条件使该问题无解:

最后,问题可能有一个解,但 DSolve 无法找到它,因为通解是隐式形式或涉及高阶超越函数.

此例中,只有将自变量和因变量反转后才有解:

Working with DSolveValue

DSolve 一样,也可用函数 DSolveValue 来求解微分方程. DSolveValue 可以求解常微分方程 (ODE)、偏微分方程 (PDE)、微分代数方程 (DAE)、时滞微分方程 (DDE)、积分方程、积分微分方程和混合微分方程.

DSolveValue 的输出由依赖函数( )的形式控制.

解微分方程:
返回 纯函数解:
验证解:
绘制解:

DSolve 不同,DSolveValue 的第二个参数可以是因变量和自变量的任何表达式. DSolveValue[eqn,expr,x] 给出由含有自变量 的常微分方程 eqn 的符号解确定的 expr 的值.

解 ODE 并返回解在点 处的值:
返回解的导数:

如果微分方程的解有多个分支,则 DSolveValue 生成一条警告消息并仅返回其中一个解.

下面的 ODE 的解有多个分支:
可用 DSolve 获取所有分支:

关于高效使用 DSolve 的基本原则的讨论到此结束. 请参阅在 DSolve 的开发过程中或在本文档的准备过程中发现的有用的参考资料列表.