Возможно, вы основываете свой подход на понимании явного метода Эйлера. В этом случае вам лучше всего реализовать (экспоненциальный) явный метод Эйлера.
Решатель 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
(Всегда думайте об использовании механизма опций для установки взвешенных, специфичных для проблемы погрешностей.)