Как использовать одно значение матрицы для каждого временного шага внутри ode solver - PullRequest
0 голосов
/ 20 мая 2019

У меня есть вектор x длины N, и я хочу использовать его значения для решения дифференциального уравнения: dy/dt = x - 4*y. Для каждого шага я хочу, чтобы функция решателя од использовала одно значение вектора, а затем использовала следующее значение матрицы для следующего шага.

Я попытался сделать это, объявив вектор глобальной переменной и использовать его следующим образом в решателе ode:

global x
tspan = 0:0.01:10;
[t,filter_coef] = ode45(@ode_filter,tspan,0);

и функция решения, подобная этой:

function dx = ode_filter(t,fil)

    global x 
    dx = x - 4*fil(1);

end

Произошла следующая ошибка

ODE_FILTER returns a vector of length 1002, but the length of initial conditions vector is 1. The vector returned by
ODE_FILTER and the initial conditions vector must have the same number of elements.

Ответы [ 2 ]

1 голос
/ 20 мая 2019

Возможно, вы основываете свой подход на понимании явного метода Эйлера. В этом случае вам лучше всего реализовать (экспоненциальный) явный метод Эйлера.


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

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


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


Используйте расширение решения для решения каждого сегмента, используя гладкую правую сторону, изменяя константу x(k) для каждого сегмента [ tx(k), tx(k+1) ]. Определите функцию, чтобы иметь параметр, избегая хлопот global переменных

function dy = ode_filter(t,y,x)
    dy = x - 4*y;
end

затем вызовите интегратор для инициализации первого сегмента, а затем для всех оставшихся сегментов, используя их константу и конец сегмента.

sol = ode45(@(t,y)ode_filter(t,y,x(1)), [ tx(1) tx(2) ], y0)
for k in 2:N
    sol = odextend(sol,@(t,y)ode_filter(t,y,x(k)),tx(k+1));
end

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

1 голос
/ 20 мая 2019

enter image description here

  • y является функцией t, а не функцией x.
  • ИзПриведенное выше уравнение, если вы сначала не определите значение x, y будет функцией t и x.

  • Также ode45 возвратите только двойные значения, не сама функция y, а это оценка при разных значениях t

  • Что можно сделать, это определить функцию, которая выдает заданное неизвестное значение xдо ode45.Затем вы получите функцию, которую я вычеркнул выше.

  • Далее Просто установите заданное значение x и оцените функцию.Функция оценки дает тип данных структуры, основными полями которой являются x и y.x это ваш t, а у вас остается y

    global x
    tspan = 0:0.01:10;
    f = @(x)ode45(@ode_filter, tspan,0);
    %% Set x Value First
    x = 2;
    var = f(x);
    t = var.x;
    y = var.y;
...