我正在努力在合理的执行时间内解决这个递归问题。
这里,我展示了递归函数,它基本上计算了多项式的系数。
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"和#34;延迟"向量包含单个值,以便更容易遵循。总之,对于" ns"的固定值,我需要使用递归函数计算多项式的所有系数,并在"延迟"计算其最终值。通过增加"延迟"中的点数,我可以看到固定" ns"的曲线。 我的问题是:对于任何" ns"在1到10之间,计算速度非常快,大约为0.069356秒(即使是整个"延迟"向量)。相反,对于ns = [15]或[20],计算时间增加A LOT(我甚至没有设法看到结果)。 我并不热衷于评估计算复杂性,因此我不知道我的代码中是否存在问题(可能是nchoosek函数?或者是循环?)或者它可能是它必须具备的方式记住这个递归问题。
编辑:
正如Adriaan所说,我认为这确实是计算量的因子增长。你是否认为nchoosek
的任何近似可能有助于解决这个问题?类似于:en.wikipedia.org/wiki/Stirling%27s_approximation
The last formula in this paper是我尝试实施的内容(注意我为tau更改了delta):
答案 0 :(得分:0)
我在你的代码上运行了个人资料,我明白了:
我看起来大部分时间花在了nchoosek身上,nchoosek以两个整数作为输入。您可以尝试预先计算所需的值并将其存储在矩阵中以便更快地访问!
编辑:我试过预先计算nchoosek:
for i = 0 : ns
for j = 0 : ns
if j < i
nchoosek_(i+1,j+1) = nchoosek(i,j);
else
nchoosek_(i+1,j+1) = NaN;
end
end
end
然后在函数中:
total = total + nchoosek_(l+1, k-1+1)*tau^(l-k+1)*get_coeff(n-1, l, tau, x , nchoosek_);
它似乎有用,我用ns = 12得到了很好的改进:
但是我仍然坚持使用ns = 15 ......
答案 1 :(得分:0)
所以我终于设法在合理的时间内计算系数。基本上,我接受了Adriaan和rahnema1的建议并创建了一个ns by ns矩阵来存储我以递归方式计算的所有系数。因此,当重复递归树的某个叶子时,我能够通过从矩阵中提取值来修剪树。请注意,增益不是基于预计算值(因为我在移动中计算它们),而是基于修剪递归的数量。这里有一些数字: