How to make my code more concise and efficient ?

6 Ansichten (letzte 30 Tage)
azza mansour
azza mansour am 20 Dez. 2020
Kommentiert: Les Beckham am 23 Dez. 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 Kommentare
Stephen23
Stephen23 am 21 Dez. 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 am 21 Dez. 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.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Les Beckham
Les Beckham am 20 Dez. 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 Kommentare
azza mansour
azza mansour am 22 Dez. 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 am 23 Dez. 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.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Matrices and Arrays finden Sie in Help Center und File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by