MATLAB Answers

How to make my code more concise and efficient ?

42 views (last 30 days)
azza mansour
azza mansour on 20 Dec 2020
Commented: Les Beckham on 23 Dec 2020
Hello, I am pretty new to matlab and so not totally efficient and professional at writing codes on it. I have a panel data of a group of countries and the following I am suppose to perform on each country. Is there a way on matlab like defining a variable with names of countries such that it will be able to implement the code on each country?. Also as you notice from the code I am providing can I define another loop for h =1:4 such that I get the output exactly the same way I get when I cut and paste the same code for each country.
I appreciate any feedback and output thank you
Example of my code :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cty 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DM11_cty1=[];
DM21_cty1=[];
for T=1:8%the forcast sample
h=1;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty1=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty1=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM11_cty1=[DM11_cty1 DM1h_cty1];
DM21_cty1=[DM21_cty1 DM2h_cty1];
end
DM12_cty1=[];
DM22_cty1=[];
for T=1:8%the forcast sample
h=2;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty1=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty1=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM12_cty1=[DM12_cty1 DM1h_cty1];
DM22_cty1=[DM22_cty1 DM2h_cty1];
end
DM13_cty1=[];
DM23_cty1=[];
for T=1:8%the forcast sample
h=3;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty1=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty1=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM13_cty1=[DM13_cty1 DM1h_cty1];
DM23_cty1=[DM23_cty1 DM2h_cty1];
end
DM14_cty1=[];
DM24_cty1=[];
for T=1:8%the forcast sample
h=4;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty1=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty1=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM14_cty1=[DM14_cty1 DM1h_cty1];
DM24_cty1=[DM24_cty1 DM2h_cty1];
end
DM1_cty1=[DM11_cty1;DM12_cty1;DM13_cty1;DM14_cty1];
DM2_cty1=[DM21_cty1;DM22_cty1;DM23_cty1;DM24_cty1];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%cty2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DM11_cty2=[];
DM21_cty2=[];
for T=1:8%the forcast sample
h=1;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty2=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty2=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM11_cty2=[DM11_cty2 DM1h_cty2];
DM21_cty2=[DM21_cty2 DM2h_cty2];
end
DM12_cty2=[];
DM22_cty2=[];
for T=1:8%the forcast sample
h=2;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty2=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty2=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM12_cty2=[DM12_cty2 DM1h_cty2];
DM22_cty2=[DM22_cty2 DM2h_cty2];
end
DM13_cty2=[];
DM23_cty2=[];
for T=1:8%the forcast sample
h=3;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty2=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty2=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM13_cty2=[DM13_cty2 DM1h_cty2];
DM23_cty2=[DM23_cty2 DM2h_cty2];
end
DM14_cty2=[];
DM24_cty2=[];
for T=1:8%the forcast sample
h=4;
[e1h, e2h,e3h] = forcasterror(h,T,GVARs,Actual,FRWM,FRWMD);
DM1h_cty2=dmtest(e1h,e2h,h);%this is the DM test for h=2 between GVAR and RW
DM2h_cty2=dmtest(e1h,e3h,h);%this is the DM test for h=2 between GVAR and RWD
DM14_cty2=[DM14_cty2 DM1h_cty2];
DM24_cty2=[DM24_cty2 DM2h_cty2];
end
DM1_cty2=[DM11_cty2;DM12_cty2;DM13_cty2;DM14_cty2];
DM2_cty2=[DM21_cty2;DM22_cty2;DM23_cty2;DM24_cty2];

  2 Comments

Stephen Cobeldick
Stephen Cobeldick on 21 Dec 2020
"Is there a way on matlab like defining a variable with names of countries such that it will be able to implement the code on each country?"
Yes, there are ways to do this, but forcing meta-data (e.g. country names) into variable names will force you into writing slow, complex, inefficient, buggy, difficult-to-debug code. Meta-data (e.g. country names) is data, and data belongs in variables, not in variable names. The best approach would be to use a cell array, string array, table array, etc. to store the names (and possibly other (meta-)data as well, much like Les Beckham showed in their answer.
"... when I cut and paste the same code for each country."
Computers are only really good at one thing: repeating simple tasks many many times in loops. So when you copy-and-paste code, you are just doing the computer's job for it (only much much slower and less accurately). Much better is to use a loop and indexing.
azza mansour
azza mansour on 21 Dec 2020
Thank you so much I am brand new to coding using matlab so I will try to see how to incorporate using the cell array in my code to make it more efficient.

Sign in to comment.

Accepted Answer

Les Beckham
Les Beckham on 20 Dec 2020
I suggest using cell arrays. See documentation here: https://www.mathworks.com/help/matlab/ref/cell.html
Replace "_cty1" with {1}, etc.
It looks like your code could also benefit from putting a lot of your data into numeric arrays. DM11 could be DM(1, 1), for example. This should allow you to fold your code up into a nested loop so you don't have to keep copying the code over and over and changing those numbers in the variable names which really should be array indices.
You can also define a cell array to hold the city names. For example cities = {'Amsterdam', 'Beirut', 'Copenhagen', 'Denver'};

  5 Comments

Show 2 older comments
Stephen Cobeldick
Stephen Cobeldick on 21 Dec 2020
If you have a version that supports them, you might also like to consider using a string array for the country names.
azza mansour
azza mansour on 22 Dec 2020
Hi,
I really want to thank you. I learned about the cell array and updated the code. It really work so fine and I was able to do for all the countries without needing to cut and paste so really thank you I appreciate your help. I provided the updated code so that you can provide any feedback.
clear all
[~,cty]=xlsfinfo('~.xlsx');
v={'GVARs', 'Actual', 'FRWM', 'FRWMD'};%just for my own reference of how variables are organized
for k=1:numel(cty)
data{k}=xlsread('forcast and actual.xlsx',cty{k});
end
for i=1:k
GVARs=data{i}(:,1);
Actual=data{i}(:,2);
FRWM=data{i}(:,3);
FRWMD=data{i}(:,4);
for h=1:4
n=8;
[e1h{i}, e2h{i},e3h{i}] = forcasterror(h,n,GVARs,Actual,FRWM,FRWMD);
T = size(e1h{i},1);
d1{i}=e1h{i}.^2 - e2h{i}.^2;
d2{i}=e1h{i}.^2 - e3h{i}.^2;
dMean1{i}= mean(d1{i});
gamma01{i} = var(d1{i});
dMean2{i} = mean(d2{i});
gamma02{i} = var(d2{i});
if h > 1
gamma1{i}= zeros(h-1,1);
gamma2{i} = zeros(h-1,1);
for j = 1:h-1
gamma1{i}(j) = (d1{i}(1+j:T)' * d1{i}(1:T-j)) ./ T; % bugfix
gamma2{i}(j)= ( d2{i}(1+j:T)' * d2{i}(1:T-j)) ./ T; % bugfix
end
varD1{i} = gamma01{i} + 2*sum(gamma1{i});
varD2{i} = gamma02{i} + 2*sum(gamma2{i});
else
varD1{i}= gamma01{i};
varD2{i}= gamma02{i};
end
D1{i}(:,h)=d1{i};%I have to introduce a new variable in order to save
the variable resulting from the h loop
D2{i}(:,h)=d2{i};
dmean1{i}(:,h)=dMean1{i};
dmean2{i}(:,h)=dMean2{i};
vard1{i}(:,h)=varD1{i};
vard2{i}(:,h)=varD2{i};
DM1{i}(:,h)= dMean1{i} / sqrt ( (1/T)*varD1{i} );
DM2{i}(:,h)= dMean2{i} / sqrt ( (1/T)*varD2{i} );
end
end
Les Beckham
Les Beckham on 23 Dec 2020
This looks like a much more efficient and maintainable (if you need to add a city, for example), way to code this.
I'm glad I was able to help.
Keep learning! The only stupid question is the one you are too embarrassed to ask.

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by