m = 10; c = 2; k = 5; F = 12;
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
{f,0,5}(0 =< f< = 5)
如何绘制三维图像:
x = u(t,f)
............
如果f = 0.1,0.2,... 5, 我们可以解决这个等式:
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
x是t和f
的函数...............
m = 10; c = 2; k = 5; F = 12;
f = 0.1
s = NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
Plot[Evaluate[x[t] /. s], {t, 0, 30}, PlotRange -> All]
f = 0.1
f = 0.2
f = 0.3
f = 5
如何绘制三维图像: x = u(t,f)
答案 0 :(得分:6)
这是一个解决方案。
m = 10; c = 2; k = 5; F = 12;
NumberOfDiscrit$f = 20;(* Number of points you want to divide 0<=f<=5*)
NumberOfDiscrit$t = 100;(* Number of points you want to divide 0<=t<=30 *)
fValues = Range[0., 5., 5./(NumberOfDiscrit$f - 1)];
tValues = Range[0., 30., 30./(NumberOfDiscrit$t - 1)];
res = Map[(x /.
First@First@
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*#*t])*x[t] ==
F*Sin[2*Pi*#*t], x[0] == 0, x'[0] == 0}, x, {t, 0, 30}]) &,
fValues];
AllDat = Map[(#@tValues) &, res];
InterpolationDat =
Flatten[Table[
Transpose@{tValues,
Table[fValues[[j]], {i, 1, NumberOfDiscrit$t}],
AllDat[[j]]}, {j, 1, NumberOfDiscrit$f}], 1];
Final3DFunction = Interpolation[InterpolationDat];
Plot3D[Final3DFunction[t, f], {t, 0, 30}, {f, 0, 5}, PlotRange -> All,
PlotPoints -> 60, MaxRecursion -> 3, Mesh -> None]
您可以使用Manipulate
动态更改某些参数。顺便说一下,如果在f
中将u(t,f)
作为连续变量,则上述3D图片可能会产生误导。你应该注意到,数值解似乎对t>>30
的渐近值有所了解。见下图。
希望这可以帮助你。
答案 1 :(得分:6)
你也可以这样做
Clear[f]
m = 10; c = 2; k = 5; F = 12;
s = NDSolve[{m*Derivative[2, 0][x][t, f] +
c*Derivative[1, 0][x][t, f] + (k*Sin[2*Pi*f*t])*x[t, f] == F*Sin[2*Pi*f*t],
x[0, f] == 0,
Derivative[1, 0][x][0, f] == 0}, x, {t, 0, 30}, {f, 0, .2}]
Plot3D[Evaluate[x[t, f] /. s[[1]]], {t, 0, 30}, {f, 0, .2}, PlotRange -> All]
答案 2 :(得分:3)
这应该这样做。
m = 10; c = 2; k = 5; F = 12;
fun[f_?NumericQ] :=
Module[
{x, t},
First[x /.
NDSolve[
{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0},
x, {t, 0, 30}
]
]
]
ContourPlot[fun[f][t], {f, 0, 5}, {t, 0, 30}]
重点:
模式_?NumericQ阻止{symbol}参数的fun
被评估(考虑fun[a]
),并导致NDSolve::nlnum
错误。
由于NDSolve
似乎没有本地化其功能变量(t
),我们需要使用Module
手动执行此操作以防止t
之间发生冲突NDSolve
中使用的ContourPlot
和ContourPlot
中使用的{}。 (你可以在Clear[funMemo] (* very important!! *)
funMemo[f_?NumericQ] :=
funMemo[f] = Module[{x, t},
First[x /.
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] ==
F*Sin[2*Pi*f*t], x[0] == 0, x'[0] == 0}, x, {t, 0, 30}]]]
ContourPlot[funMemo[f][t], {f, 0, 5}, {t, 0, 30}] (* much faster than with fun *)
中使用不同名称的变量,但我认为指出这个警告很重要。)
如果在绘图方面有显着的加速,你可以使用memoization,正如巫师先生所指出的那样。
SetAttributes[memo, HoldAll]
SetAttributes[memoStore, HoldFirst]
SetAttributes[memoVals, HoldFirst]
memoVals[_] = {};
memoStore[f_, x_] :=
With[{vals = memoVals[f]},
If[Length[vals] > 100, f /: memoStore[f, First[vals]] =.;
memoVals[f] ^= Append[Rest[memoVals[f]], x],
memoVals[f] ^= Append[memoVals[f], x]];
f /: memoStore[f, x] = f[x]]
memo[f_Symbol][x_?NumericQ] := memoStore[f, x]
如果你喜欢冒险,并且愿意更深入地探索Mathematica,你可以通过限制允许使用缓存定义的内存量as I described here来进一步改善这一点。
让我们定义一个辅助函数来启用memoization:
fun
然后使用原始的,未记忆的ContourPlot[memo[fun][f][t], {f, 0, 5}, {t, 0, 30}]
函数,绘制为
{{1}}