Обновите переменные ODE в Matlab

Я пытаюсь воспроизвести результаты статьи (Immune Response). Короче говоря, он смотрит на концентрацию патогенов, антител и плазматических клеток, а также на влияние иммунного ответа на орган. В зависимости от состояния органа будет меняться показатель, влияющий на концентрацию плазматических клеток.

Я смоделировал это в Matlab. Моя проблема в том, что условные операторы для переменной, влияющей на концентрацию плазмы, игнорируются. Комментируя части кода и просматривая графики, независимо от второго условия, вывод соответствует только начальному условию.

Как я могу обновить значения, чтобы они интерпретировались ode45 (или ode23), и есть ли лучший подход к решению этой проблемы?

Мой код ниже.

function dx = iir_2(t, x)
dx = [0; 0; 0; 0];
a11 = 1;
a31 = 1;
a41 = 1;
a12 = 1;
a22 = 3;
a32 = 1.5;
a42 = 1;
a23 = 1;
a33 = 0.5;

b1 = -1;
b2 = 1;
b3 = 1;
b4 = -1;

u1 = 0;
u2 = 0;
u3 = 0;
u4 = 0;

tau = 0.1;

if x(4) >= 0.5
    a21x4 = 0;
else
    a21x4 = cos(pi * x(4));
end

if x(4) > 1
    x(4) = 1;
end

dx(1) = (a11 - a12 * x(3)) * x(1) + b1 * u1;
dx(2) = a21x4 * a22 * x(1) * (t - tau) * x(3) * (t - tau) - a23 * (x(2) - 2) + b2 * u2;
dx(3) = a31 * x(2) - (a32 + a33 * x(1)) * x(3) + b3 * u3;
dx(4) = a41 * x(1) - a42 * x(4) + b4 * u4;

Этот второй скрипт, который вызывает вышеуказанную функцию, это..

    Case = ['Subclinical' 'Clinical' 'Chronic' 'Lethal'];
x1_0 = [1.5 2 2.57 3];
x2_0 = 2;
x3_0 = (1*x2_0)/1.5;
x4_0 = 0;

for i = 1:4
    if i == 1
        state = 'Subclinical';
    elseif i == 2
        state = 'Clinical';
    elseif i == 3
        state = 'Chronic';
    else
        state = 'Lethal';
    end

    options = odeset('RelTol', 1e-3, 'NonNegative', [1 2 3 4]);
    [t,x] = ode45(@iir_2, [0 10], [x1_0(i) x2_0 x3_0 x4_0], options); % use ode23???
    figure 
    plot(t,x);
    str = sprintf('Case Number = %d\nx(0) = %d\n%s', i, x1_0(i), state);
    title(str);
    axis([0,10,0,10])
    legend('Pathogen', 'Plasma Cell', 'Antibody', 'Organ');
end

Условные операторы находятся в функции.

if x(4) >= 0.5
        a21x4 = 0;
    else
        a21x4 = cos(pi * x(4));
    end

    if x(4) > 1
        x(4) = 1;
    end

person cer    schedule 24.08.2013    source источник


Ответы (1)


Есть два способа сделать это.

В любом случае вы должны понимать, что вы не можете просто установить x(4) равным 1 и надеяться, что все получится наилучшим образом. Matlab не будет заботиться о предыдущих значениях x (4), поскольку все они хранятся в памяти. Кроме того, предстоящее значение x(4) определяется dx(4) и ранее сохраненными значениями x(4) (которые вы не можете установить).

У вас есть два возможных решения вашей проблемы:

A) установите dx (4) = 0, когда ваше условие выполнено

if x(4) > 1
    dx(4) = 0;
else
    dx(4) = a41 * x(1) - a42 * x(4) + b4 * u4;
end

Однако это не приведет к идеальному x(4) = 1, скорее будет небольшая ошибка.

Б) Вызов функции события, о которой можно узнать здесь и здесь, где случае вы можете прервать для нового вызова функции.

person Rasman    schedule 24.08.2013