Matlab忽略了我的if条件

时间:2015-03-23 22:02:34

标签: matlab if-statement

仍然遇到Matlab工作方式的麻烦......

我建立了一个由微分方程组成的模型,由ode45求解器调用。 ode45求解器本身将v0的函数传递给系统。

这是我的模特:

%chemostat model, based on:
%DCc=-v0*Cc/V + umax*Cs*Cc/(Ks+Cs)-rd -->Change of cell concentration over time
%Dcs=(v0/V)*(Cs0-Cs) - Cc*(Ys*umax*Cs/(Ks+Cs)-m) -->Change of substrate concentration over time

function dydt=sys(t,y,v0,V,umax,Ks,rd,Cs0,Ys,m)
 dydt=[-(v0(t,y)/V)*y(1)+(umax*y(1)*y(2))/(Ks+y(2))-rd; 
       (v0(t,y)/V)*(Cs0-y(2))-(Ys*umax*y(2)*y(1))/(Ks+y(2))];

这是我的v0的功能:     `

    function v0 = funV0( t,y )
    persistent i
    if isempty(i)
        i=0;
    end

    if y(1) > 5 || i==1
        v0=20
        v0 = 20+200*t % As an example, if [Y1] > 5, then set v0 = [Y2]
        i=1
    else 
        v0=0
        i=0
    end
end

如果我只是通过,模型就可以正常工作:

v0=20
v0=v0+200*t

但是,上面的代码与if条件不起作用。即使y(1)最初为1(并且随时间缓慢增加),if条件也会被忽略。

有人可以解释这种行为并指出解决方案吗?

提前致谢并特别感谢Rollen D'Souza,他们首先帮助我完成了代码。

2 个答案:

答案 0 :(得分:0)

我在这里看到两个问题。

  1. 您将v0视为标量
  2. 时的函数
  3. 不符合if语句的条件
  4. 功能与标量

    当您定义function v0 = funV0( t,y )时,此语句的含义是函数调用funV0(t,y)返回值v0

    funV0功能中,您可以将v0设置为v0 = 20+200*tv0=0,具体取决于条件。除非t是向量或矩阵,否则v0将是标量值。

    sys函数中,您传入v0。我假设这指的是与上面相同的值。然后你做v0(t,y)。如果v0是矩阵,则会在(t,y)处检索元素。但是,它不会调用我认为你想要做的函数funV0(t,y)

    而不是v0(t,y),您应该使用函数调用funV0(t,y)

    如果声明条件

    这是我为funV0函数观察到的行为。

    你描述y(1)最初是1,所以我设置y=1来测试你的功能。

    我调用了funV0(1,1)并设置了断点,以便我可以浏览代码。这是发生了什么。

    function v0 = funV0( t,y )
        % breakpoint here
    
        %i is initialized to []
        persistent i
    
        % enter this if statement
        if isempty(i)
            i=0; % i is now 0
        end
    
        %Here y(1)==1 and i==0 so we skip the if statement and enter the else statement
        if y(1) > 5 || i==1
            v0=20
            v0 = 20+200*t
            i=1
        else 
            % We end up here
            v0=0 
            i=0
        end
    end
    

    在函数结束时,返回v0,其值为0.

    如果我再次使用funV0(1, 6)调用该函数,我将输入if语句,因为y(1)>5

    如果要在y(1)==1时输入if语句,则应更改if语句的条件。按原样,未输入if语句,因为不满足条件。

答案 1 :(得分:0)

最后回到这里,对所有贡献的人抱歉!不过,谢谢大家。所有建议都帮助我找到了正确的方向。

所以,我认为MatLab忽略了我的if语句。根据patrik的建议使用调试器后,结果证明这是错误的。正确调用了该函数,并且正确输入了if语句。

我遇到了三个导致问题的问题:

  • 变量i被定义为"持久性"。这需要清除每次新运行的功能。在我发布问题时我不知道的事情以及导致奇怪结果的原因。
  • if语句中的
  • 必须是y(1,1)而不是y(1)
  • 我原来的代码中的
  • 依赖于t。我希望v0依赖于t减去第一次y(1,1)大于阈值时的时间点。

另外还有一件事让我质疑代码: 当y(1,1)首先大于阈值时,ode-solver会在某些时间点跳回。这导致了v0的负值,使模型偏斜。这是通过v0函数中的其他代码行解决的。

您可以在下面找到更新的代码:

微分方程:

%chemostat model, based on:
%DCc=-v0*Cc/V + umax*Cs*Cc/(Ks+Cs)-rd
%Dcs=(v0/V)*(Cs0-Cs) - Cc*(Ys*umax*Cs/(Ks+Cs)-m)
function dydt=systemEquations(t,y,funV0,V,umax,Ks,rd,Cs0,Ys,m)

        v=funV0(t,y);          
           dydt=[-(v/V)*y(1)+(umax*y(1)*y(2))/(Ks+y(2))-rd; 
           (v/V)*(Cs0-y(2))-(Ys*umax*y(2)*y(1))/(Ks+y(2))];
end

v0的功能:

function v0 = funV0( t,y )

    persistent i %has to be persistent to be carried over for the next function call
    persistent j %has to be persistent to be carried over for the next function call

    if isempty(i) %for initial assignment of i
        i=0;
    end

    if y(1,1) > 5.00 || i==1 %y(1,1) reads value if y-matrix
        if isempty(j) %initial assignment of j, reads t value from system equations
            j=t
        end

       v0=20   
       a=t-j
       v0=v0+a*2000
           if v0<0 %ode-solver jumps to time points before Cc>threshold --> negative values for v0 --> skews model
            v0=0
           end
        i=1
    else 
        v0=0
        i=0
    end
end

致电代码:

%ODE solver for model
%first brackets determine timespan (e.g. [0 20] means hour 0 to 20)
[t,y]=ode23(@systemEquations, [0 5],[Cc0 Cs0],[],@funV0,V,umax,Ks,rd,Cs0,Ys,m);

%plotting
plot(t,y);

%clearing of persistent variables
clear funV0;