Azzera filtri
Azzera filtri

how can I speed up this code?

2 visualizzazioni (ultimi 30 giorni)
Marco Della Ciana
Marco Della Ciana il 17 Gen 2017
Commentato: James Wiken il 15 Feb 2017
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

Risposta accettata

Jyotish Robin
Jyotish Robin il 20 Gen 2017
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 Commenti
Jyotish Robin
Jyotish Robin il 20 Gen 2017
Maybe you could try changing the "fmincon" algorithm. Currently it is set to 'sqp'. Try changing this and see whether there is performance improvements.
Also, there are lot of parameters which you could tune corresponding to different algorithms. Try changing these values (for example, tolerance limits) and see their effect on performance.
See the following link for more details:
James Wiken
James Wiken il 15 Feb 2017
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

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by