Передача переменных потока в функцию событий в Matlab ODE

Я разрабатываю динамическую модель, описывающую динамику растений и микробов. Рост растений может быть ограничен углеродом (светом), азотом или фосфором, и модель имеет различную динамику в зависимости от того, какой из этих трех элементов является лимитирующим. Растения могут получать азот либо из почвы, либо из атмосферы, и я хочу определить количество питательных веществ, получаемых каждым путем. Итак, на каждом временном шаге я хочу рассчитать, какое питательное вещество ограничивает, а затем рассчитать соответствующие потоки и изменения в пулах. Моя конечная цель — иметь таблицу с данными для всех пулов, потоков и ограничений.

До сих пор для решения этого вопроса я использовал ode45 в MATLAB. Моя функция имеет как события, так и ряд дополнительных значений, которые вычисляются в моем ODE (т. е. я хочу извлечь различные потоки с течением времени, а не только значения dY). Есть ли способ экспортировать все потоки/переменные и использовать функцию событий?

Код, который я использую для передачи дополнительных переменных (xvt, yvt, limvt), имеет форму ниже

(на основе этой публикации MATLAB Central):

function [dydx xvt yvt limvt] = myode(t,input,ps)
persistent xv yv limv

condition=input*ps;

if condition>1: lim=1; x=x*1; y=y/1;
elseif condition==1: lim=2; x=x*2; y=y/2;
elseif condition<1: lim=3; x=x*3; y=y/3;
end

limv = [limv; lim];
yv = [yv; y];
xv = [xv; x];

dydx = x + y;

if nargout>1
      xvt = xv; yvt = yv; limvt = limv;
end

Решение ОДУ можно решить с помощью команд:

[X Y] = ode45(@myode, [0 5], 1);

Затем xv, yv и limv можно получить с помощью:

[dY, xv, yv, limv]=myode([], input,ps);

Чтобы использовать функцию событий, где изменения в limv являются событиями, я установил параметры следующим образом (events_functions выполняет математические операции, чтобы события выдавали правильные значения в нужное время):

options = odeset('Events',@(t0,y,ps)events_function(t0,input,ps,limv,years));

Итак, я могу запустить функцию с событиями (в цикле while, чтобы запускать и останавливать всякий раз, когда происходят события):

[t,xx] = ode23(@myode,[t0:years],input,options,ps);

Однако приведенное выше позволяет мне выполнять либо события на основе limv, либо вычислять limv, но не то и другое одновременно. Я считаю, что этот плакат пытался сделать то же самое. Вы знаете, возможно ли это?


person Alison Rachel    schedule 10.11.2015    source источник
comment
xv и yv не являются параметрами. Это просто значения времени (независимой переменной) и вектора состояния на каждом временном шаге. Ваши функции событий имеют доступ к этим двум входам. Я не вижу никаких параметров в вашем примере кода, который, кажется, взят из вопроса Matlab Central. Пожалуйста, отредактируйте свой вопрос, чтобы предоставить код того, что вы на самом деле пытаетесь выполнить (или более четкий пример).   -  person horchler    schedule 10.11.2015
comment
Спасибо за ваш комментарий. Я уточнил, что имел в виду переменные, а не параметры. Я изменил вопрос, чтобы он был более конкретным для моей проблемы. Пожалуйста, дайте мне знать, если я должен быть еще более ясным. Спасибо!   -  person Alison Rachel    schedule 10.11.2015
comment
Нет необходимости вычислять limv — это просто зависит от переменной состояния input и параметра ps, к которым у вашей функции событий уже есть доступ. Также нет необходимости сохранять xv и yv, так как это просто X и Y output from ode23/ode45` (плюс некоторые дополнительные значения из-за неудачных шагов, которые вам не нужны). Кроме того, обычно плохая идея помещать разрывы в функцию ОДУ (например, в ваш оператор if/elseif) — это делает уравнение очень жестким и может привести к неточности и даже к совершенно неверным решениям. Используйте события для решения этих переходов.   -  person horchler    schedule 10.11.2015
comment
Мои реальные уравнения сложнее, чем эти. input на самом деле является вектором из 11 переменных состояния, а ps — 42 параметра. Каждое dY представляет собой комбинацию различных потоков, которые я хочу различать (например, dY[3]= f(вход[6], ввод[9] и ввод[12]; я хочу знать, какая доля dY исходит из каждой из других переменных состояния). f зависит от значения lim, которое зависит от значения ввода [1], ввода [11] и ввода [12] на каждом временном шаге. Я пытался чтобы использовать события для решения переходов, которые зависят от lim.Вы можете уточнить ваше предложение?Спасибо.   -  person Alison Rachel    schedule 10.11.2015
comment
Немного сложно точно следовать тому, что вы хотите сделать... во-первых, опубликованный вами код не работает (что такое x?), и, как указал @horchler, вычисление limv не нужно, и его лучше выполнять внутри функция событий. Более того, постоянные переменные внутри функции ОДУ, используемой в решателе с переменным шагом, не дадут ожидаемого результата; многие шаги интеграции будут отклонены, промежуточные значения, которые не отображаются в решении и т. д., по-прежнему будут собираться постоянными переменными.   -  person Rody Oldenhuis    schedule 12.11.2015
comment
У меня такое ощущение, что мы имеем дело с проблемой XY. Можете ли вы, возможно, добавить объяснение к вашему вопросу в абстрактных терминах (так что без кода!) именно что вы хотите выполнить?   -  person Rody Oldenhuis    schedule 12.11.2015
comment
Я обновил вопрос, чтобы описать свои цели.   -  person Alison Rachel    schedule 13.11.2015