Я изо всех сил пытаюсь получить решение этой проблемы рекурсии в разумные сроки выполнения.
Здесь я показываю рекурсивную функцию, которая в основном вычисляет коэффициенты многочлена.
function [ coeff ] = get_coeff( n, k, tau, x )
if(n == 0) % 1st exit condition
coeff = 0;
else
if(k == 0) % 2nd exit condition
coeff = max(0, n*tau-x)^n;
else % Else recursion
total = 0;
for l = k-1:n-2
total = total + nchoosek(l, k-1)*tau^(l-k+1)*get_coeff(n-1, l, tau, x);
end
coeff = (n/k) * total;
end
end
end
% This symbolic summation solution gives numerical errors, probably due to rounding
% effects.
% syms l;
% f = nchoosek(l, k-1)*tau^(l-k+1)*get_coeff(n-1, l, tau, x);
% coeff = (n/k) * symsum(f, l, k-1, n-2);
И это основной сценарий, в котором я использую рекурсивную функцию:
Tau = 1;
ns = [3];
%delays = 0:0.25:8;
delays = [0];
F_x = zeros(1, size(delays, 2));
rho = 0.95;
tic
for ns_index = 1: size(ns, 2)
T = Tau*(ns(ns_index)+1)/rho;
% Iterate delays (x)
for delay_index = 1:size(delays, 2)
total = 0;
% Iterate polynomial.
for l = 0:ns(ns_index)-1
total = total + get_coeff(ns(ns_index), l, Tau, delays(delay_index))*(T - ns(ns_index)*Tau + delays(delay_index))^l;
end
F_x(1, delay_index) = T^(-ns(ns_index))*total;
end
end
toc
Я упростил векторы "ns" и "delays", чтобы они содержали одно значение, чтобы их было легче отслеживать. Таким образом, для фиксированного значения «ns» мне нужно вычислить все коэффициенты многочлена, используя рекурсивную функцию, и вычислить его окончательное значение при «задержках». Увеличивая количество точек в «задержках», я вижу кривую для фиксированного «ns». Мой вопрос: для любых «нс» от 1 до 10 вычисление выполняется очень быстро, порядка 0,069356 секунды (даже для всего вектора «задержек»). И наоборот, для ns = [15] или [20] время вычислений увеличивается НАМНОГО (мне даже не удалось увидеть результат). Я не увлекаюсь оценкой вычислительной сложности, поэтому я не знаю, есть ли проблема в моем коде (может быть, функция nchoosek? Или циклы for?) или, может быть, так и должно быть, имея в виду эту рекурсию. проблема.
EDIT: я вижу, что это действительно факторный рост количества вычислений, как заявил Адриан. Как вы думаете, может ли какая-либо аппроксимация nchoosek
быть полезной для решения этой проблемы? Что-то вроде: en.wikipedia.org/wiki/Stirling%27s_closed
Последняя формула в этой статье — это то, что я пытаюсь реализовать (обратите внимание, что я изменил дельту для тау):
15! = 1.3077e+12
, так что если это количество вычислений, конечно, это займет много времени, даже если время расчета составляет около микросекунды для одной итерации. Напротив:12! = 4.8e8
, что в 10 000 раз меньше, поэтому я не очень удивлен, что дляns>15
требуется очень много времени. - person Adriaan   schedule 28.02.2018ns!
раз. Вычислите первую точку, вторую из этой и т. д., сохраните, когда закончите, затем умножьте на правильный префактор (это деление перед суммированием), и это должно быть так. Я не уверен, почему ваш код имеет факторный рост итераций, но этого не должно быть. - person Adriaan   schedule 28.02.2018[ns+1 x ns+1]
и сохранить в них предварительно вычисленные результатыnchoosek
иget_coeff
. - person rahnema1   schedule 01.03.2018