how can I speed up this code?

3 ビュー (過去 30 日間)
Marco Della Ciana
Marco Della Ciana 2017 年 1 月 17 日
コメント済み: James Wiken 2017 年 2 月 15 日
the following code computes daily Value at Risk, from 03/01/2013 to 12/12/2016, but it takes 3 days.How can I speed up?
Dati=xlsread('port_banche','portafoglio');
VaR95=zeros(1000,1);
VaR99=zeros(1000,1);
VaR999=zeros(1000,1);
for t=1395:size(Dati,1)
SottoDati=Dati(1:t,:);
T=size(SottoDati,1);
model=arima('AR',NaN,'Distribution','t','Variance',garch(1,1));
nAzioni=size(SottoDati,2);
residui=NaN(T,nAzioni);
varianza=NaN(T,nAzioni);
fit=cell(nAzioni,1);
options=optimset('fmincon');
options=optimset(options,'Display','off','Diagnostics','off','Algorithm','sqp','TolCon',1e-07);
for i=1:nAzioni
fit{i}=estimate(model,SottoDati(:,i),'print',false,'options',options);
[residui(:,i),varianza(:,i)]=infer(fit{i},SottoDati(:,i));
end
residui=residui./sqrt(varianza);
soglia=0.05;
code=cell(nAzioni,1);
for i=1:nAzioni
code{i}=paretotails(residui(:,i),soglia,1-soglia,'kernel');
end
U=zeros(size(residui));
for i=1:nAzioni
U(:,i)=cdf(code{i},residui(:,i));
end
[R]=copulafit('Gaussian',U,'Method','ML');
s=RandStream.getGlobalStream();
reset(s)
nProve=10000;
orizzonte=1;
Z=zeros(orizzonte,nProve,nAzioni);
U=copularnd('Gaussian',R,orizzonte*nProve);
for j=1:nAzioni
Z(:,:,j)=reshape(icdf(code{j},U(:,j)),orizzonte,nProve);
end
Y0=SottoDati(end,:);
Z0=residui(end,:);
V0=varianza(end,:);
RendSimulati=zeros(orizzonte,nProve,nAzioni);
for i=1:nAzioni
RendSimulati(:,:,i)=filter(fit{i},Z(:,:,i),'Y0',Y0(i),'Z0',Z0(i),'V0',V0(i));
end
RendSimulati=permute(RendSimulati,[1 3 2]);
RendCumulati=zeros(nProve,1);
pesi=repmat(1/nAzioni,nAzioni,1);
for i=1:nProve
RendCumulati(i)=sum(log(1+(exp(RendSimulati(:,:,i))-1) *pesi));
end
VaR95(t-1394,:)=quantile(RendCumulati, 0.05);
VaR99(t-1394,:)=quantile(RendCumulati, 0.01);
VaR999(t-1394,:)=quantile(RendCumulati, 0.001);
end

採用された回答

Jyotish Robin
Jyotish Robin 2017 年 1 月 20 日
Hi Marco,
I would suggest you to use the Profiler to track execution time. Knowing the execution time of your MATLAB code helps you to optimize it. Thereby you can understand which parts of your computation are slow.
Also, Vectorizing your code is worthwhile. Vectorized code often runs much faster than the corresponding code containing loops.
To know more about vectorization, you can take a look at the following link: https://www.mathworks.com/help/matlab/matlab_prog/vectorization.html
Some other suggestions:
  • preallocating a chunk of memory for arrays before entering into a loop in loops can significantly speed up your code by . The zeros() and ones() functions are the most common way to do this.
  • Since "bsxfun" is multithreaded and can take advantage of multiple CPUs ,using it may be good for performance improvement.
  • Try to implement the algorithm more efficiently.
  • Try to use most recent versions of MATLAB.
Hope this helps!
  3 件のコメント
James Wiken
James Wiken 2017 年 2 月 15 日
Hi Marco,
Looking at your profiler results, I have a few suggerstions.
1) Look through your code and see if you have any lines in a loop that do not change over iterations. Take these lines and move them outside of the loop. This helps reduce repeated calculations. On a quick look through I found the following lines:
model=arima('AR',NaN,'Distribution','t','Variance',garch(1,1));
options=optimset('fmincon');
options=optimset(options,'Display','off','Diagnostics','off','Algorithm','sqp','TolCon',1e-07);
soglia=0.05;
nProve=10000;
orizzonte=1;
2) Your code is calling 'optimset' a huge amount of times. Looking at the 'estimate' function I saw that the options you were manually setting were identical to the defaults. Comment out the following lines to remove these calls. If I am guessing right, this should roughly half the runtime of your code:
options=optimset('fmincon');
options=optimset(options,'Display','off','Diagnostics','off','Algorithm','sqp','TolCon',1e-07);
3) If you have access to the parallel computing toolbox, it may be worth trying to parallelize this code. The first thing I would try is changing
for i=1:nAzioni
fit{i}=estimate(model,SottoDati(:,i),'print',false,'options',options);
[residui(:,i),varianza(:,i)]=infer(fit{i},SottoDati(:,i));
end
to
parfor i=1:nAzioni
fit{i}=estimate(model,SottoDati(:,i),'print',false,'options',options);
[residui(:,i),varianza(:,i)]=infer(fit{i},SottoDati(:,i));
end

サインインしてコメントする。

その他の回答 (0 件)

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by