Wolfram mathematica NDSolve中的递归函数未更新
下面的代码在Mathematica中为一个简单的SIR模型(用于疾病控制)建模。(我直接从笔记本上抄的) 可以使用Wolfram mathematica NDSolve中的递归函数未更新,wolfram-mathematica,Wolfram Mathematica,下面的代码在Mathematica中为一个简单的SIR模型(用于疾病控制)建模。(我直接从笔记本上抄的) 可以使用NDSolve求解方程,并将解插入三个不同的函数中以供进一步使用 可以看出,第一行的Beta项根据Inf[t]的值而变化,Inf[t]是NDSolve函数的三种解决方案之一 这段代码工作得很好,为了更好地解释下面的问题,我加入了这段代码 Beta = Piecewise[{{0.01, Inf[t] > 20}, {.06, Inf[t] <= 20}}]; Mu = 0
NDSolve
求解方程,并将解插入三个不同的函数中以供进一步使用
可以看出,第一行的Beta项根据Inf[t]的值而变化,Inf[t]是NDSolve
函数的三种解决方案之一
这段代码工作得很好,为了更好地解释下面的问题,我加入了这段代码
Beta = Piecewise[{{0.01, Inf[t] > 20}, {.06, Inf[t] <= 20}}];
Mu = 0.1;
Pop = 100;
ans = NDSolve[{S'[t] == -Beta S[t] Inf[t],
Inf'[t] == Beta S[t] Inf[t] - Mu Inf[t],
R'[t] == Mu Inf[t],
S[0] == Pop - 1, Inf[0] == 1,
R[0] == 0}, {S[t], Inf[t], R[t]}, {t, 0, 10}];
Sus[t_] = S[t] /. ans[[1, 1]];
Infected[t_] = Inf[t] /. ans[[1, 2]];
Rec[t_] = R[t] /. ans[[1, 3]];
有人能解释一下为什么这可能无法正常运行吗
编辑:这是更新后的函数
UpdateTransmission[S_, Th_, Infect_] := Module[{BetaOverall},
P = S;
For[i = 1, i <= Pop, i++,
P[[i]] = Sign[Infect - Th[[i]]];];
BetaOverall = ((Count[P, 1]*.02) + (Count[P, -1]*.5))/Pop
]
编辑编辑
好的,我把所有的东西放在一起,试着画出我的三条曲线。从这里可以看出,它们都是平衬里。Sus[t]线保持在100,而其他两条线似乎保持在1以下。这里应该发生的是,Sus[t]线应该大幅下降,而其他两条线应该上升
(我试图插入和图像,但我不能,因为我没有所需的信誉点,所以我将刚刚通过代码,您可以在自己的机器上看到绘图)
Pop=100;
SpinMatrix=表[-1,{Pop}];
val:=RandomReal[正态分布[.5,1]];
ThresholdMatrix=表[Pop*val,{Pop}];
updateTransmission[S_,Th_,Infect_]:=Module[{},P=S;
对于[i=1,i,在某些方面,您遇到了(=
)和(:=
)之间的差异。例如,如果您编写了f=7
,f
在初始化后所有出现的f
中都变成7
。但是,如果您编写了f=7 t
,并尝试将其作为函数使用,即f[8]
,您将得到(7 t)[8]
因为Set
表示f
的值是不变的。SetDelayed
表示f
的值会发生变化,每次发生时都必须重新计算。不过,您的初始情况是特殊的
当你写信的时候
Beta = Piecewise[{{0.01, Inf[t] > 20}, {.06, Inf[t] <= 20}}]
Beta = UpdateTransmission[Inf[t]]
这里的问题是,UpdateTransmission
只有在最初定义了Beta
时才会执行,而分段
仍然未计算,UpdateTransmission
很可能仍然会给出纯符号输入的结果
用更新传输[Inf[t]
替换方程中出现的每一次Beta
SetDelayed
重新定义Beta
,例如
Beta := UpdateTransmission[Inf[t]]
以便在每次遇到时重新评估,或UpdateTransmission
以不通过
UpdateTransmission[x_?(Head[#]=!=Symbol&)] := ...
或
UpdateTransmission[Inf[t]]
保持未评估状态,并有效地执行与选项1相同的操作。但是,它需要最少的更改。就个人而言,我支持选项1或3,因为我不知道在NDSolve
运行时,Beta
需要重新评估多少次。罪魁祸首是Sign[]
我不知道为什么,但我发现问题出在NDSolve内的Sign[]函数无法正常工作
删除它:
Pop = 100;
SpinMatrix = Table[-1, {Pop}];
val := RandomReal[NormalDistribution[.5, .1]];
ThresholdMatrix = Table[Pop*val, {Pop}];
updateTransmission[Th_, Inf_] :=
Total[Table[If[Inf >= Th[[i]], 2/100, 1/2]/Pop , {i, Pop}]];
beta[t_] := updateTransmission[ThresholdMatrix, Inf[t]];
mu = 0.1;
ans = NDSolve[{
S'[t] == -beta[t] S[t] Inf[t],
Inf'[t] == beta[t] S[t] Inf[t] - mu Inf[t],
R'[t] == mu Inf[t],
S[0] == Pop - 1,
R[0] == 0,
Inf[0] == 1}, {S[t], Inf[t], R[t]}, {t, 0, 10}];
Sus[t_] = S[t] /. First@ans;
Infected[t_] = Inf[t] /. First@ans;
Rec[t_] := R[t] /. First@ans;
Plot[{Sus[t], Infected[t], Rec[t]}, {t, 0, 10}]
给出:
也许对Mma有更好了解的人可以解释代码中发生了什么
HTH!再次欢迎使用Stackoverflow。我通过将代码放入代码块并删除Mathematica标记来设置代码的可读性。我建议学习使用markdown,这是一种用于设置帖子格式的html引擎。在每个问答文本框上方都有一个问号,详细说明了如何使用markdown,而且它非常广泛。此外,Mathematica内部用
\[beta]
表示字符beta,内部版本是复制的。为了可读性,应该删除标记。我应该注意一个折衷,beta
在Mathematica中是保留字,但\[beta]
不是。因此,上述代码不再是直接可执行的,我认为资深成员对需要做的事情没有达成一致意见。我的想法是应该删除标记,将符号小写。其他人对此有什么想法吗?好的,谢谢你的建议。我以后会尝试一下问题OK谢谢你的建议。我已经试着投票选出答案,但我不能,因为我的总数暂时太低。我当然希望随着我自身知识的增长,我能回答其他人的问题。嗨,谢谢你的回答。我试图输出的是一个3个函数在结束时与时间的关系图。当我这样做时,尽管我得到了答案由于我的Beta值没有更新(保持在0),所以出现了三条扁平线。我尝试将Beta变成一个函数,就像你在上面所做的那样,但它没有改变任何事情。@Sperick,在上面的Beta=updateTransmission[Inf[t]中使用updateTransmission
的定义
,我得到了与贝里萨里乌斯相同的结果。你能发布更新传输的定义吗
,因为贝里萨里乌斯的操作是用2inf[t].
替换2inf[t]+1.
,正如我在回答中指出的,它仍然没有被评估。这意味着你的定义是在解释Inf[t]
当它有一个值时,应该不进行计算。好吧,我简化了UpdateTransmission,以使问题不那么复杂。它实际上是一个模块,但希望不会有太大的区别。这里是(顺便问一下,注释是做这件事的最佳位置吗?我似乎无法开始新的段落)UpdateTransmission[S_u,Th_u,Infect_u]:=Module[{[Beta]Overall},P=S;对于[i=1,i@Sperick,请将该代码发布为您问题的更新(单击问题下方的“编辑”),以便您可以正确格式化它hi-belisarius-i-up
Beta = UpdateTransmission[Inf[t]]
Beta := UpdateTransmission[Inf[t]]
UpdateTransmission[x_?(Head[#]=!=Symbol&)] := ...
UpdateTransmission[x_] /; Head[x]=!= Symbol := ...
Pop = 100;
SpinMatrix = Table[-1, {Pop}];
val := RandomReal[NormalDistribution[.5, .1]];
ThresholdMatrix = Table[Pop*val, {Pop}];
updateTransmission[Th_, Inf_] :=
Total[Table[If[Inf >= Th[[i]], 2/100, 1/2]/Pop , {i, Pop}]];
beta[t_] := updateTransmission[ThresholdMatrix, Inf[t]];
mu = 0.1;
ans = NDSolve[{
S'[t] == -beta[t] S[t] Inf[t],
Inf'[t] == beta[t] S[t] Inf[t] - mu Inf[t],
R'[t] == mu Inf[t],
S[0] == Pop - 1,
R[0] == 0,
Inf[0] == 1}, {S[t], Inf[t], R[t]}, {t, 0, 10}];
Sus[t_] = S[t] /. First@ans;
Infected[t_] = Inf[t] /. First@ans;
Rec[t_] := R[t] /. First@ans;
Plot[{Sus[t], Infected[t], Rec[t]}, {t, 0, 10}]