为何R语言deSolve包的ode无法正确求解简单微分方程
问题背景
计划使用deSolve包求解耦合偏微分方程,目前正通过ode函数求解简单微分方程熟悉该包的使用方法。已知微分方程y' = sqrt(1-y^2)的解析解为sin(t + c),因此分别设置初始条件y(0) = 0和y(0) = 1开展测试,预期将分别得到sin(t)和sin(t + pi/2)的求解结果,但最终绘制出的解曲线与预期完全不符,结果十分异常。
测试代码
yini <- c(y = 0) derivs <- function(t, y) list(sqrt(1 - y^2)) times <- seq(from = 0, to = 4, by = 0.2) out <- ode(y = yini, times = times, func = derivs) head(out, n =3) yini <- c(y = 1) out2 <- ode(y = yini, times = times, func = derivs) plot(out, out2, main = "", lwd = 2)
异常结果

问题原因
- 对微分方程解的适用范围理解错误:方程右侧
sqrt(1-y^2)是算术平方根,返回值恒大于等于0,也就是说解曲线的斜率永远不会为负。所认为的全域解析解sin(t+c)仅在t+c ∈ [-π/2, π/2]区间满足该方程:当t+c > π/2时,sin(t+c)的导数变为负数,和方程右端非负的要求完全矛盾,根本不是该方程的合法解。这个方程的真实解是当y增长到1之后,就会保持y=1的常数水平不再变化,不会继续沿正弦曲线下降。 - 浮点计算误差触发数值异常:当初始条件设置为
y(0)=1时,理论上该点导数为0,解应该是恒为1的常数函数,但数值计算过程中会产生极小的舍入误差,可能导致y的计算值略微超过1,此时1-y^2为负数,R中对负数开平方会返回NaN,直接导致求解过程异常中断,输出不符合预期的结果。 - 分离变量法求解的边界被忽略:用分离变量法推导该方程时,
arcsin(y) = t + c的成立前提是y ∈ [-1, 1]且导数非负,忽略这个前提,把仅在半周期内成立的局部解错当成了全域的正弦函数,自然会觉得数值求解结果和预期不符。
内容的提问来源于stack exchange,提问作者Top Secret
相关产品推荐
相关产品推荐

