在Mathematica中的两个单独的绘图命令中使用微分方程的解

时间:2009-08-25 11:51:13

标签: wolfram-mathematica plot differential-equations

我尝试在两个单独的绘图命令中使用 NDSolve 的答案时遇到了问题。为了说明这个问题,我将使用一个简单的微分方程和一个绘图命令。如果我写这样的话:

{Plot[x[t], {t, 0, 10}], x[4]} 
/. NDSolve[{x'[s] == - x[s], x[0] == 1}, x, {s, 0, 10}]

它解决了方程并计算x [4]没有问题,但是情节变空了,我不明白为什么。

在我的实际问题中,我的方程是一个非常复杂的系统,用于多个函数,而不是 x [4] 我绘制了求解函数的参数图。我最终打算将所有这些包含在 Manipulate 语句中,所以我不希望 NDSolve 语句出现多次(花费太长时间)而且我不能只是提前计算(因为它有很多参数)。


编辑:我想澄清并扩展我的问题:我真正想要做的是以下列方式将我的绘图声明包含在操纵语句中:

Manipulate[{Plot[x[t], {t, 0, 10}], x[4]} 
/. NDSolve[{x'[s] == - a*x[s], x[0] == 1}, x, {s, 0, 10}]
,{{a,1},0,5}]

由于只有 Manipulate 语句为参数 a 赋值,因此我无法预先计算 NDSolve 的答案。另外,由于我的实际方程系统非常复杂且非线性,我不能使用符号函数 DSolve

很抱歉,如果以前不清楚的话。

2 个答案:

答案 0 :(得分:8)

你的问题是Plot []做了一些有趣的事情,使得绘图更方便,而它所做的一件事就是不能绘制无法用数字评估的东西。所以在你发布的表达中,

Plot[x[t], {t, 0, 10}]

继续使用NDSolve中的解决方案进行规则替换前评估,生成空图的图形对象。该图形对象不包含对x的引用,因此没有什么可以替代的。

您希望确保在绘图之前完成替换。如果您还想确保替换可以在多个位置完成,您希望将解决方案存储到变量中。

sol = NDSolve[{x'[s] == - x[s], x[0] == 1}, x, {s, 0, 10}];
{Plot[Evaluate[x[t] /. sol], {t, 0, 10}], x[4] /. sol} 

Plot中的Evaluate []确保Mathematica仅进行一次替换,而不是每个绘图点执行一次。对于像这样的简单规则替换并不重要,但是如果你想要绘制更复杂的东西,那么使用它是个好习惯。


为了使这个工作在Manipulate中,简单的方法是使用With [],这是Mathematica的范围构造之一;它是一个用于你想要替换的东西,而不使用它作为变量,你可以变异。

例如,

Manipulate[
  With[{sol = NDSolve[{x'[s] == - x[s], x[0] == 1}, x, {s, 0, 10}]},
    {Plot[x[t] /. sol // Evaluate, {t, 0, 10}, PlotRange -> {0, 1}], 
     x[4] /. sol}],
  {{a, 1}, {0, 5}}]

使用PlotRange选项保持y轴固定;否则,随着变化的价值,事物会以丑陋的方式跳跃。当您使用Manipulate执行更复杂的操作时,有许多选项可用于控制更新速度,如果您的ODE足够复杂以至于需要一段时间才能解决,这一点非常重要。

答案 1 :(得分:2)

与此同时,我找到了另一种方法。它不太优雅,但它只使用一个替换,所以我想我也会在这里发布它。

我们的想法是在 Plot 上使用 Hold ,这样就不会对其进行评估,执行规则替换,然后 ReleaseHold ,在操纵之前。

Manipulate[ReleaseHold[
  Hold[ {Plot[x[t], {t, 0, 10}, PlotRange -> {0, 1}], x[4]} ]
 /.NDSolve[{x'[s] == -a x[s], x[0] == 1}, x, {s, 0, 10}]
], {{a, 1}, 0, 5}]