在数值求解微分方程并绘制结果后,我想确定绘制范围内的单个最大值,但不知道如何。
下面的代码用于数值求解微分方程并绘制结果。
s = NDSolve[{x''[t] + x[t] - 0.167 x[t]^3 == 0.005 Cos[t + -0.0000977162*t^2/2], x[0] == 0, x'[0] == 0}, x, {t, 0, 1000}]
Plot[Evaluate[x[t] /. s], {t, 0, 1000},
Frame -> {True, True, False, False}, FrameLabel -> {"t", "x"}, FrameStyle -> Directive[FontSize -> 15], Axes -> False]
答案 0 :(得分:4)
使用 NMaximize
第一个近似值:
s = NDSolve[{x''[t] + x[t] - 0.167 x[t]^3 ==
0.005 Cos[t + -0.0000977162*t^2/2], x[0] == 0, x'[0] == 0}, x[t],
{t, 0, 1000}]
NMaximize[{Evaluate[x[t] /. s[[1]]] , 100 < t < 1000}, t]
{1.26625, {t -> 821.674}}
由于你的函数是这样的快速振荡:,它没有捕获真正的最大值,如下所示:
Plot[{1.26625, Evaluate[x[t] /. s[[1]]]}, {t, 790, 830},
Frame -> {True, True, False, False}, FrameLabel -> {"t", "x"},
FrameStyle -> Directive[FontSize -> 15], Axes -> False,
PlotRange -> {{790, 830}, {1.25, 1.27}}]
所以我们改进边界,并稍微调整一下NMaximize函数:
NMaximize[{Evaluate[x[t] /. s[[1]]] , 814 < t < 816}, t,
AccuracyGoal -> 20, PrecisionGoal -> 18, MaxIterations -> 1000]
NMaximize::cvmit: Failed to converge to the requested accuracy or
precision within 1000 iterations. >>
{1.26753, {t -> 814.653}}
它未能在所需精度内收敛,但现在结果已足够
Plot[{1.2675307922753962`, Evaluate[x[t] /. s[[1]]]}, {t, 790, 830},
Frame -> {True, True, False, False}, FrameLabel -> {"t", "x"},
FrameStyle -> Directive[FontSize -> 15], Axes -> False,
PlotRange -> {{790, 830}, {1.25, 1.27}}]
答案 1 :(得分:3)
您可以使用Reap
和Sow
从任何评估中提取值列表。对于一个简单的Plot
,您可以Sow
绘制函数的值,并将整个绘图括在Reap
中:
list = Reap[
Plot[Sow@Evaluate[x[t] /. s], {t, 0, 1000},
Frame -> {True, True, False, False},
FrameLabel -> {"t", "x"},
FrameStyle -> Directive[FontSize -> 15],
Axes -> False]];
list
的第一个元素是图本身,第二个元素是Mathematica在图中使用的x值列表。获得最大值:
In[1] := Max[lst[[2, 1]]]
Out[1] := 1.26191