我在 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它需要永遠。
uj5u.com熱心網友回復:
通過應用兩種主要型別的改進,您可以從我的測驗中節省約 95% 的運行時間
- 盡可能在最外層的回圈中計算事物,這樣就不會多次計算等價項。
- 將內部
y1回圈矢量化以將其洗掉
v_upp、v_low和之間的所有增量v_draws都是常數,因為這些向量在回圈中不會改變,因此都可以在回圈之外計算。也可以mvnpdf。
然后代碼看起來像這樣:
gamma=zeros(K 1,K 1,K 1,L 1,L 1); %allocate space for the array gamma
v_delta = v_upp-v_low;
v_delta_upp1 = v_upp-v_draws(:,1);
v_delta_upp2 = v_upp-v_draws(:,2);
v_delta_upp3 = v_upp-v_draws(:,3);
v_delta_low1 = v_draws(:,1)-v_low;
v_delta_low2 = v_draws(:,2)-v_low;
v_delta_low3 = v_draws(:,3)-v_low;
MVN = mvnpdf(v_draws,mu_V,Sigma_V);
y1=1:L 1;
for k1=1:K 1
term1 = (nchoosek(K, (k1-1))*((v_delta_low1.^(k1-1).*v_delta_upp1.^(K-(k1-1)))./(v_delta.^K)));
for k2=1:K 1
term2 = (nchoosek(K, (k2-1))*((v_delta_low2.^(k2-1).*v_delta_upp2.^(K-(k2-1)))./(v_delta.^K)));
for k3=1:K 1
term3 = (nchoosek(K, (k3-1))*((v_delta_low3.^(k3-1).*v_delta_upp3.^(K-(k3-1)))./(v_delta.^K)));
integr = term1 .* term2 .* term3 .* MVN;
for y=1:L 1
integrp = integr .* (payoff(:,y)-payoff(:,y1)); %n_drawsx1
gamma(k1,k2,k3,y,y1)=sum(integrp)/n_draws; %average of elements of integr
end
end
end
end
您可以通過注意以下事項來進一步改善這一點
- 您在每個回圈內部進行計算
nchoosek,1:K 1預先計算一個值陣列nchoosek并在回圈時對其進行索引可能會更快。 - 您在每次回圈迭代時都除以
n_draws并乘以mvnpdf術語,在回圈之后執行這些操作是否更快?
盡管如此,你會得到遞減的回報。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/514964.html
標籤:matlab
