我有以下工作 Mathematica 代码:

ODENInit[n_, xIni_] :=
    Join[{x[1][0] == xIni}, Table[x[i][0] == 0, {i, 2, n}]]
ODEN[n_] :=
    Join[{x[1]'[t] == k1 - k2 x[1][t]},
    Table[x[i]'[t] == k1 x[i - 1][t] - k2 x[i][t], {i, 2, n}]]
ODENVars[n_] := Table[x[i][t], {i, 1, n}];

Manipulate[
    Module[{sol},
        sol = NDSolve[
            Join[ODEN[10], ODENInit[10, 0]] /. {k1 -> mk1, k2 -> mk2},
                 ODENVars[10], {t, 0, 10}];
        Plot[Evaluate@Table[x[i][t] /. sol, {i, 1, 10}], {t, 0, 10}]],
    {{mk1, 1}, 0.1, 10, .1}, {{mk2, 1}, 0.1, 10, .1}]

有什么方法可以重写 Manipulate 部分,这样我就不需要将 k1 和 k2 参数重新分配给虚拟参数,这里是 mk1 和 mk2?感谢您提前提供任何提示。

最佳答案

是的,只需将它们作为函数 ODEN 的参数即可。还有几点可以改进代码:

1) 使用Initialization引入函数,使代码自可靠

3) 使用 ControlType -> None 引入一个虚拟本地化变量,以避免在 Module 中添加额外的 manipulate - 因为 Manipulate 无论如何都将 DynamicModule 包裹在其内容周围。

Manipulate[

 sol = NDSolve[Join[ODEN[10, k1, k2], ODENInit[10, 0]],
   ODENVars[10], {t, 0, 10}];

 Plot[Evaluate@Table[x[i][t] /. sol, {i, 1, 10}], {t, 0, 10}],

 {{k1, 1}, 0.1, 10, .1},
 {{k2, 1}, 0.1, 10, .1},
 {sol, ControlType -> None},

 Initialization :> {

   ODENInit[n_, xIni_] :=
    Join[{x[1][0] == xIni}, Table[x[i][0] == 0, {i, 2, n}]],

   ODEN[n_, k1_, k2_] :=
    Join[{x[1]'[t] == k1 - k2 x[1][t]},
     Table[x[i]'[t] == k1 x[i - 1][t] - k2 x[i][t], {i, 2, n}]],

   ODENVars[n_] := Table[x[i][t], {i, 1, n}]

   }]

为了回答您的评论,如果您真的倾向于在函数外部全局定义 k ,那么这样做:
Manipulate[

 Block[{sol, k1 = mk1, k2 = mk2},
  sol = NDSolve[Join[ODEN[10], ODENInit[10, 0]],
    ODENVars[10], {t, 0, 10}];
  Plot[Evaluate@Table[x[i][t] /. sol, {i, 1, 10}], {t, 0, 10}]],

 {{mk1, 1}, 0.1, 10, .1}, {{mk2, 1}, 0.1, 10, .1}]

关于wolfram-mathematica - 在 Manipulate 内绘制 NDSolve,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13846121/

10-12 19:10