Надеюсь, я здесь по теме. Я спрашиваю здесь, так как он сказал на странице часто задаваемых вопросов: вопрос, касающийся (среди прочего) программного алгоритма :) Итак, вот оно:
Мне нужно решить систему ODE (например, $ \ dot x = A (t) x $. Матрица A может измениться и задается в виде строки в вызове функции (Calc_EDS_v2 ('Sys_EDS_a', ... )
Затем я использую ode45 в цикле, чтобы найти мой x:
function [intervals, testing] = EDS_calc_v2(smA,options,debug)
[..]
for t=t_start:t_step:t_end)
[Te,Qe]=func_int(@intQ_2_v2,[t,t+t_step],q);
q=Qe(end,:);
[..]
end
[..]
с func_int как ode45 и @ intQ_2_v2 мой m-файл. q возвращается к вызову как начальный вектор. Как вы видите, я просто использую ode45 на интервале [t, t + t_step]. Это потому, что моя системная матрица A может заставить ode45 выполнять много шагов, что приводит к быстрому попаданию в AbsTol или RelTol.
Теперь мой A - это что-то вроде B (t) * Q (t), поэтому в m-файле intQ_2_v2.m мне нужно оценить и B, и Q в моменты времени t.
Сначала я сделал это так: (v1 -файл, поэтому имя функции другое)
function q=intQ_2_v1(t,X)
[..]
B(1)=...; ... B(4)=...;
Q(1)=...; ...
чем это, естественно, только при условии, что A является матрицей 2x2. При такой настройке базовая система вычислялась где-то между 10 и 15 секундами.
Вместо вышеизложенного я теперь использую файлы B1.m до B4.m и Q1.m до B4.m (я знаю, что это не элегантно, но мне нужно использовать quadgk для B позже, и quadgk не поддерживает матричные функции.)
function q=intQ_2_v2(t,X)
[..]
global funcnameQ, funcnameB, d
for k=1:d
Q(k)=feval(str2func([funcnameQ,int2str(k)]),t);
B(k)=feval(str2func([funcnameB,int2str(k)]),t);
end
[..]
funcname (строка), ссылающаяся на B или Q (с добавленным k), а d - это размерность системы.
Теперь я знал, что это будет стоить мне больше времени, чем первая версия, но я вижу, что время вычислений в десять раз выше! (получая от 150 до 160 секунд) Я понимаю, что открытие 4 файлов и оценка примерно 40 раз в цикле ode обходится дорого ... и я также не могу предварительно оценить B и Q, так как ode45 использует адаптивные размеры шагов ...
Есть ли способ не использовать этот последний цикл?
В основном меня интересует решение, позволяющее сократить время вычислений. У меня есть ощущение, что я что-то упускаю ... но не могу понять, как это сделать. Так как это занимает почти три минуты вместо 10 секунд, я могу выпить кофе между каждым тестом сейчас ... (пожалуйста, не говорите мне, чтобы получить более быстрый компьютер)
(простите за такой длинный вопрос)