我在MatLab中有一个“超级嵌套”循环来创建数组gamma
。执行该循环需要很长时间。我希望你能帮我把环路矢量化。
以下是带有解释的代码:
rng default
clear
%%%%%%%%%%%%%%%%%Parameters
L=2;
K=3;
n_draws=10^6;
mu_V=zeros(1, L+1);
Sigma_V=eye(L+1);
v_draws=mvnrnd(mu_V,Sigma_V,n_draws); %n_drawsx(L+1)
payoff=randn(n_draws, L+1); %n_drawsx(L+1)
v_upp=5;
v_low=-5;
%%%%%%%%%%%%%%%%Fill the array gamma
gamma=zeros(K+1,K+1,K+1,L+1,L+1); %allocate space for the array gamma
for k1=1:K+1
for k2=1:K+1
for k3=1:K+1
for y=1:L+1
for y1=1:L+1
tic
integr=((nchoosek(K, (k1-1))*(((v_draws(:,1)-v_low).^(k1-1).*(v_upp-v_draws(:,1)).^(K-(k1-1)))./((v_upp-v_low).^K))).*...
(nchoosek(K, (k2-1))*(((v_draws(:,2)-v_low).^(k2-1).*(v_upp-v_draws(:,2)).^(K-(k2-1)))./((v_upp-v_low).^K))).*...
(nchoosek(K, (k3-1))*(((v_draws(:,3)-v_low).^(k3-1).*(v_upp-v_draws(:,3)).^(K-(k3-1)))./((v_upp-v_low).^K)))).*...
mvnpdf(v_draws,mu_V,Sigma_V).*...
(payoff(:,y)-payoff(:,y1)); %n_drawsx1
gamma(k1,k2,k3,y,y1)=sum(integr)/n_draws; %average of elements of integr
toc
end
end
end
end
end
例如,对于K=3
,执行时间大约为20秒。在我的实际锻炼中,K=50
和它永远花费。
1条答案
按热度按时间afdcj2ne1#
通过应用两种主要类型的改进,您可以从我的测试中节省约95%的运行时间
1.尽可能在最外层的循环中计算东西,这样等价的项就不会被多次计算。
1.向量处理内部的
y1
循环以删除它v_upp
、v_low
和v_draws
之间的所有增量都是恒定的,因为这些向量在循环中不会改变,因此都可以在循环之外计算。mvnpdf
也可以。然后,代码如下所示:
您可以通过注意如下内容来进一步改进这一点
nchoosek
的1:K+1
,如果预先计算nchoosek
值的数组,并在循环时只对其进行索引,可能会更快。n_draws
,再乘以mvnpdf
项,这样做会不会更快?然而,看着这样的事情,你会得到越来越少的回报。