2015-03-23 2 views
0

еще возникли проблемы с тем, как Matlab работает ...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, которые мне помогли с кодом в первую очередь.

+1

вы с помощью ' funV0'? Я не вижу, чтобы его называли. – Memming

+1

'funV0' возвращает' v0'. Я думаю, что вы рассматриваете 'v0' как функцию, когда она фактически является двойной. – Cecilia

+0

@Memming: FunV0 вызывается ode45: [t, y] = ode45 (@ systemEquations2, [0 5], [Cc0 Cs0], [], @ funV0, V, umax, Ks, rd, Cs0 , Ys, м); – Dahlai

ответ

0

Наконец-то возвращаясь к этому, извините всем, кто внес свой вклад! Спасибо вам всем. Все предложения помогли мне найти правильное направление.

Итак, я думал, что MatLab игнорирует мой оператор if. После использования отладчика, предложенного patrik, оказалось, что это было неправильно. Функция была вызвана должным образом, а также корректно введен оператор if.

я столкнулся три проблемы, которые вызывали проблемы:

  • переменного я был определен как «стойкий». Для этого требуется очистка функции для каждого нового запуска. Что-то, чего я не знал в то время, когда я разместил вопрос и что привело к странным результатам.
  • в выражении if он должен быть y (1,1) вместо y (1)
  • в моем исходном коде v0 зависит от t. Я хотел, чтобы v0 зависел от t минус время, когда y (1,1) было больше порога в первый раз.

Кроме того еще одна вещь заставила меня вопрос код: Ода-решатель перескакивает назад в некоторых точках времени, когда у (1,1) является первой больше, чем порог. Это привело к отрицательным значениям 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; 
0

Здесь я вижу две проблемы.

  1. Вы лечите v0 как функция, когда она является скалярной
  2. Ваших условий, если заявление не выполняется

Функции против скаляра

При определении function v0 = funV0(t,y), что это означает, что вызов функции funV0(t,y) возвращает значение v0.

В функции funV0 вы устанавливаете v0 либо v0 = 20+200*t, либо v0=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), я войду, если заявление, потому что y(1)>5.

Если вы хотите ввести оператор if, когда y(1)==1, вы должны изменить условие оператора if. Как бы то ни было, оператор if не вводится, потому что условия не выполняются.

+0

Привет, Сесилия, благодарю вас за ваш ответ, и мне очень жаль, что я не вернулся к вам раньше ... Был застрял в других проектах:/ действительные баллы. Однако при использовании отладчика оказалось, что v0, передаваемый как скаляр, не является проблемой. Кроме того, я использовал ваш код, и результат тот же. Я скоро отправлю сообщение. Приветствия – Dahlai

+0

Я отправил ответ, который показывает решение моей проблемы. В моем случае передача v0 в качестве скаляра не была проблемой. Поскольку для каждой точки времени существует только один v0. Спасибо, хотя за ваш ответ мне помогли понять функции в Matlab немного лучше =) – Dahlai

Смежные вопросы