exponenta event banner

Система решения ОДУ с несколькими исходными условиями

В этом примере сравниваются два метода решения системы обыкновенных дифференциальных уравнений с несколькими наборами начальных условий. Методы:

  • Использовать for-контур для выполнения нескольких моделирований, по одному для каждого набора исходных условий. Этот метод прост в использовании, но не обеспечивает лучшую производительность для больших систем.

  • Векторизируйте функцию ОДУ для решения системы уравнений для всех наборов исходных условий одновременно. Этот метод является более быстрым методом для больших систем, но требует перезаписи функции ОДУ, чтобы она правильно изменила форму входных данных.

Уравнения, используемые для демонстрации этих техник, являются хорошо известными уравнениями Лотки - Вольтерры, которые являются нелинейными дифференциальными уравнениями первого порядка, описывающими популяции хищников и добычи.

Описание проблемы

Уравнения Лотки - Вольтерры представляют собой систему двух нелинейных ОДУ первого порядка, описывающих популяции хищников и добычи в биологической системе. Со временем популяции хищников и добычи меняются в соответствии с уравнениями

dxdt = αx-βxy, dydt = δxy-γ y.

Переменные в этих уравнениях:

  • x - размер популяции добычи;

  • y - размер популяции хищников

  • t - время

  • α, β, δ и γ - постоянные параметры, которые описывают взаимодействия между двумя видами. В этом примере используются значения параметров α = γ = 1, β = 0,01 и δ = 0,02.

Для этой проблемы начальные значения для x и y являются начальными размерами совокупности. Затем решение уравнений предоставляет информацию о том, как популяции меняются с течением времени по мере взаимодействия видов.

Решение уравнений с одним начальным условием

Для решения уравнений Лотка-Вольтерра в MATLAB напишите функцию, которая кодирует уравнения, укажите временной интервал для интегрирования и укажите начальные условия. Затем можно использовать один из решателей ОДУ, например: ode45, для моделирования системы во времени.

Функция, которая кодирует уравнения

function dpdt = lotkaODE(t,p)
% LOTKA Lotka-Volterra predator-prey model
delta = 0.02;
beta = 0.01;

dpdt = [p(1) .* (1 - beta*p(2));
        p(2) .* (-1 + delta*p(1))];
end

(Эта функция включена в качестве локальной функции в конце примера.)

Поскольку в системе существует два уравнения, dpdt - вектор с одним элементом для каждого уравнения. Кроме того, вектор решения p имеет один элемент для каждого компонента решения: p(1) представляет x в исходных уравнениях, и p(2) представляет y в исходных уравнениях.

Затем задайте интервал времени для интегрирования как [0,15] и установите начальные размеры совокупности для x и y равными 50.

t0 = 0;
tfinal = 15;
p0 = [50; 50];

Решение системы с помощью ode45 путем задания функции ОДУ, временного интервала и начальных условий. Постройте график зависимости полученных популяций от времени.

[t,p] = ode45(@lotkaODE,[t0 tfinal],p0);
plot(t,p)
title('Predator/Prey Populations Over Time')
xlabel('t')
ylabel('Population')
legend('Prey','Predators')

Figure contains an axes. The axes with title Predator/Prey Populations Over Time contains 2 objects of type line. These objects represent Prey, Predators.

Поскольку решения показывают периодичность, постройте график решений друг против друга на фазовом графике.

plot(p(:,1),p(:,2))
title('Phase Plot of Predator/Prey Populations')
xlabel('Prey')
ylabel('Predators')

Figure contains an axes. The axes with title Phase Plot of Predator/Prey Populations contains an object of type line.

Полученные графики показывают решение для заданных начальных размеров совокупности. Для решения уравнений для различных начальных размеров совокупности измените значения в p0 и повторно запустите моделирование. Однако этот метод решает только уравнения для одного начального условия одновременно. Следующие два раздела описывают методы решения для множества различных начальных условий.

Метод 1: Вычисление нескольких начальных условий с помощью for-петля

Самый простой способ решения системы ОДУ для нескольких начальных условий - это for-луп. Этот метод использует ту же функцию ОДУ, что и метод одиночного начального условия, но for-loop автоматизирует процесс решения.

Например, можно сохранить начальный размер заполнения для константы x равным 50 и использовать for-контур для изменения первоначального размера популяции для y между 10 и 400. Создание вектора размеров совокупности для y0, а затем закольцовывать значения для решения уравнений для каждого набора начальных условий. Постройте график фазы с результатами всех итераций.

y0 = 10:10:400;
for k = 1:length(y0)
    [t,p] = ode45(@lotkaODE,[t0 tfinal],[50 y0(k)]);
    plot(p(:,1),p(:,2))
    hold on
end
title('Phase Plot of Predator/Prey Populations')
xlabel('Prey')
ylabel('Predators')
hold off

Figure contains an axes. The axes with title Phase Plot of Predator/Prey Populations contains 40 objects of type line.

На фазовом графике показаны все вычисленные решения для различных наборов начальных условий.

Метод 2: Вычисление нескольких начальных условий с помощью векторизованной функции ОДУ

Другим способом решения системы ОДУ для множества начальных условий является переписывание функции ОДУ так, чтобы все уравнения решались одновременно. Для этого необходимо выполнить следующие шаги:

  • Предоставить все исходные условия ode45 в виде матрицы. Размер матрицы: sоколо-n, где s - количество компонентов решения и n - количество исходных условий, решаемых для. Затем каждый столбец в матрице представляет один полный набор начальных условий для системы.

  • Функция ODE должна принимать дополнительный входной параметр для n, количество начальных условий.

  • Внутри функции ОДУ решатель передает компоненты решения p в виде вектора столбца. Функция ОДУ должна изменить форму вектора в матрицу с размером s-by-n. Затем каждая строка матрицы содержит все начальные условия для каждой переменной.

  • Функция ОДУ должна решать уравнения в векторизированном формате, так что выражение принимает векторы для компонентов решения. Другими словами, f(t,[y1 y2 y3 ...]) должен вернуться [f(t,y1) f(t,y2) f(t,y3) ...].

  • Наконец, функция ОДУ должна изменить форму своего выходного сигнала обратно в вектор так, чтобы решатель ОДУ получал вектор обратно от каждого вызова функции.

При выполнении этих шагов решатель ОДУ может решить систему уравнений с помощью вектора для компонентов решения, в то время как функция ОДУ изменяет форму вектора на матрицу и решает каждый компонент решения для всех начальных условий. В результате можно решить систему для всех начальных условий в одном моделировании.

Чтобы реализовать этот метод для системы Lotka-Volterra, начните с поиска количества начальных условий n, а затем сформировать матрицу начальных условий.

n = length(y0);
p0_all = [50*ones(n,1) y0(:)]';

Затем перезаписайте функцию ОДУ так, чтобы она приняла n в качестве входных данных. Использовать n чтобы изменить форму вектора решения в матрицу, затем решить векторизированную систему и изменить форму выходного сигнала обратно в вектор. Модифицированная функция ОДУ, выполняющая эти задачи:

function dpdt = lotkasystem(t,p,n)
%LOTKA  Lotka-Volterra predator-prey model for system of inputs p.
delta = 0.02;
beta = 0.01;

% Change the size of p to be: Number of equations-by-number of initial
% conditions.
p = reshape(p,[],n);

% Write equations in vectorized form.
dpdt = [p(1,:) .* (1 - beta*p(2,:)); 
        p(2,:) .* (-1 + delta*p(1,:))];

% Linearize output.
dpdt = dpdt(:);
end

Решить систему уравнений для всех исходных условий с помощью ode45. С тех пор ode45 требует, чтобы функция ОДУ принимала два входа, использовала анонимную функцию для передачи значения n из рабочей области в lotkasystem.

[t,p] = ode45(@(t,p) lotkasystem(t,p,n),[t0 tfinal],p0_all);

Преобразование выходного вектора в матрицу с размером (numTimeSteps*s)около-n. Каждый столбец выходных данных p(:,k) содержит решения для одного набора исходных условий. Постройте график фазы компонентов решения.

p = reshape(p,[],n);
nt = length(t);
for k = 1:n
    plot(p(1:nt,k),p(nt+1:end,k))
    hold on
end
title('Predator/Prey Populations Over Time')
xlabel('t')
ylabel('Population')
hold off

Figure contains an axes. The axes with title Predator/Prey Populations Over Time contains 40 objects of type line.

Результаты сопоставимы с результатами, полученными forметод -loop. Однако существуют некоторые свойства метода векторизованного решения, которые следует иметь в виду:

  • Вычисленные решения могут несколько отличаться от решений, вычисленных на основе одного начального ввода. Разница возникает из-за того, что решатель ОДУ применяет проверки норм ко всей системе для вычисления размера временных шагов, так что поведение временного шага решения несколько отличается. Изменение временных этапов обычно не влияет на точность решения, а скорее на то, в какие моменты времени решение оценивается.

  • Для жестких решателей ОДУ (ode15s, ode23s, ode23t, ode23tb), которые автоматически оценивают численный якобиан системы, указывая узор блочной диагональной разреженности якобиана с помощью JPattern вариант odeset может повысить эффективность расчета. Блок-диагональная форма якобиана возникает из входного переформатирования, выполняемого в переписанной функции ОДУ.

Сравнение результатов синхронизации

Время использования каждого из предыдущих методов timeit. Время для решения уравнений с одним набором начальных условий включается в качестве базового числа, чтобы увидеть, как методы масштабируются.

% Time one IC
baseline = timeit(@() ode45(@lotkaODE,[t0 tfinal],p0),2);

% Time for-loop
for k = 1:length(y0)
    loop_timing(k) = timeit(@() ode45(@lotkaODE,[t0 tfinal],[50 y0(k)]),2);
end
loop_timing = sum(loop_timing);

% Time vectorized fcn
vectorized_timing = timeit(@() ode45(@(t,p) lotkasystem(t,p,n),[t0 tfinal],p0_all),2);

Создайте таблицу с результатами синхронизации. Умножьте все результаты на 1e3, чтобы выразить время в миллисекундах. Включите столбец со временем на решение, которое делится каждый раз на число начальных условий, для которых выполняется решение.

TimingTable = table(1e3.*[baseline; loop_timing; vectorized_timing], 1e3.*[baseline; loop_timing/n; vectorized_timing/n],...
    'VariableNames',{'TotalTime (ms)','TimePerSolution (ms)'},'RowNames',{'One IC','Multi ICs: For-loop', 'Mult ICs: Vectorized'})
TimingTable=3×2 table
                            TotalTime (ms)    TimePerSolution (ms)
                            ______________    ____________________

    One IC                     0.69141               0.69141      
    Multi ICs: For-loop         24.206               0.60516      
    Mult ICs: Vectorized        1.8598              0.046496      

TimePerSolution столбец показывает, что векторизированный метод является самым быстрым из трех методов.

Локальные функции

Здесь перечислены локальные функции, которые ode45 вызывает для вычисления решений.

function dpdt = lotkaODE(t,p)
% LOTKA Lotka-Volterra predator-prey model
delta = 0.02;
beta = 0.01;

dpdt = [p(1) .* (1 - beta*p(2));
        p(2) .* (-1 + delta*p(1))];
end
%------------------------------------------------------------------
function dpdt = lotkasystem(t,p,n)
%LOTKA  Lotka-Volterra predator-prey model for system of inputs p.
delta = 0.02;
beta = 0.01;

% Change the size of p to be: Number of equations-by-number of initial
% conditions.
p = reshape(p,[],n);

% Write equations in vectorized form.
dpdt = [p(1,:) .* (1 - beta*p(2,:)); 
        p(2,:) .* (-1 + delta*p(1,:))];

% Linearize output.
dpdt = dpdt(:);
end

См. также

|

Связанные темы