Как я могу решить оду без использования вложенных функций?

StackOverflow https://stackoverflow.com/questions/1572268

  •  21-09-2019
  •  | 
  •  

Вопрос

У меня есть несколько дифференциальных уравнений, которые мне нужно решить, используя решатели ODE Matlab. Хотя сами дифференциальные уравнения довольно просты, они зависят от многих «константов». Эти константы не универсальны и должны быть предоставлены абонентом.

Примером такого рода будет:

dx/dt = -j * (k + x) ./ (l + x)

Где j, k и l постоянные, а x - переменная.

То, как я решаю их до сих пор, - это использовать функцию, которая принимает все начальные значения и все значения констант (из которых есть около 10) в качестве аргументов, а затем вызывает внутреннюю функцию «шаг», которая принимает Вектор формы, которую Matlab ожидает его решателей ODE. Так...

function [outputVector] = someFunction(x, y, j, k, l, m, n, o)
    function [output] = someFunctionStep(t, inputVector)
        x = inputVector(1);
        y = inputVector(2);
        dx = -j .* (k + x) ./ (l + x);
        dy = -m .* (n + y) ./ (o + y);
        output = [dx;dy]
    end
    outputVector = ode15s(@someFunctionStep, [0, endTime], [x,y]);
end

Однако по мере увеличения количества переменных и размер кода это становится все менее и менее элегантным и приводит к чертовски новому нечитаемому беспорядку кода. Итак, что я хотел бы сделать, так это переместить функцию шага для каждой системы в собственный файл без необходимости а) передавать константы в функцию шага во входном векторе или б) использовать глобальные переменные. Есть ли какой -нибудь разумный способ сделать это, или я должен просто смирить его и написать уродливый код?

Это было полезно?

Решение

Я бы предложил создать конкретные функции «генератора» для каждой системы ODE, которые вы хотите решить (на основе Предложение Лорен использовать анонимные функции) Вот как можно было бы выглядеть для вашего примера:

function odeFcn = makeODE(j,k,l,m,n,o)
  odeFcn = @(t,y) [-j*(k+y(1))/(l+y(1)); -m*(n+y(2))/(o+y(2))];
end

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

outputVector = ode15s(makeODE(a,b,c,d,e,f), [0,endTime], [x,y]);

Другие советы

Я не вижу, как ваш код, как написано, может работать, так как никто никогда не звонит и не указывает на некоторую функцию. Должен ли это быть первым входом в ODE15s?

В любом случае, вы можете написать отдельную функцию FunctionStep, которая принимает Varargin или входы. А затем создайте анонимную функцию с константами. Передайте это в ODE15.

-Лорен

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top