Wolfram mathematica NDSolve中的递归函数未更新

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

下面的代码在Mathematica中为一个简单的SIR模型(用于疾病控制)建模。(我直接从笔记本上抄的)

可以使用
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&)] := ...
    

  • 选项3通过强制
    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}]