How to make this code more elegant?

Regarding my code below, you said " There is a way to loop through global variables like you are wanting to do, but I think we can make the code much shorter and simpler if we know a few things about the data. Do all of the ir matrices have the same dimensions? What are they?"

yse ir matrices have the same dimensions.

So how I can convert code much shorter and simpler ?

/**     Compute variance decompositions for horizons 1 to 10    **/
vd1  = ir1.^2;
vd1  = 100*vd1./sumc(vd1′);
vd2  = ir1.^2 + ir2.^2;
vd2  = 100*vd2./sumc(vd2′);
vd3  = ir1.^2 + ir2.^2 + ir3.^2;
vd3  = 100*vd3./sumc(vd3′);
vd4  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2;
vd4  = 100*vd4./sumc(vd4′);
vd5  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2;
vd5  = 100*vd5./sumc(vd5′);
vd6  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2;
vd6  = 100*vd6./sumc(vd6′);
vd7  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2;
vd7  = 100*vd7./sumc(vd7′);
vd8  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2;
vd8  = 100*vd8./sumc(vd8′);
vd9  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2;
vd9  = 100*vd9./sumc(vd9′);
vd10 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2 + ir10.^2;
vd10 = 100*vd10./sumc(vd10′);

sumc(diag(vd1*vd1′) to   sumc(diag(vd10*vd10′)

tr=0;
i=1;
do until i>10;
    tmp = varget("vd"$+ntos(i));
    tr = tr + sumc(diag(tmp*tmp'));
    i=i+1;
endo;

5 Answers



0



Let's start by posting a revised version of your original code. I added repeatable random numbers by setting the rndseed. This will allow us to have a more simple self-contained program to compare with the new one.

rndseed 23423;
r = 8;
c = 4;
ir1 = rndn(r, c);
ir2 = rndn(r, c);
ir3 = rndn(r, c);
ir4 = rndn(r, c);
ir5 = rndn(r, c);
ir6 = rndn(r, c);
ir7 = rndn(r, c);
ir8 = rndn(r, c);
ir9 = rndn(r, c);
ir10 = rndn(r, c);

vd1  = ir1.^2;
vd1  = 100*vd1./sumc(vd1');
vd2  = ir1.^2 + ir2.^2;
vd2  = 100*vd2./sumc(vd2');
vd3  = ir1.^2 + ir2.^2 + ir3.^2;
vd3  = 100*vd3./sumc(vd3');
vd4  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2;
vd4  = 100*vd4./sumc(vd4');
vd5  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2;
vd5  = 100*vd5./sumc(vd5');
vd6  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2;
vd6  = 100*vd6./sumc(vd6');
vd7  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2;
vd7  = 100*vd7./sumc(vd7');
vd8  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2;
vd8  = 100*vd8./sumc(vd8');
vd9  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2;
vd9  = 100*vd9./sumc(vd9');
vd10 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2 + ir10.^2;
vd10 = 100*vd10./sumc(vd10');

tr=0;
for i(1, 10, 1);
    tmp = varget("vd"$+cvtos(ftocv(i, 1, 0)));
    tr = tr + sumc(diag(tmp*tmp'));
endfor;

This code works and is OK, but I think we can make it better by:

  1. Replacing the list of vd assignments to a loop:

    This will make the code much shorter and make it much, much easier and less error prone if you ever want to add more terms to your program.

  2. Remove the need to use varget and string manipulation to get the value of a global variable:

    This will work, but it is not as readable of code as it could be and since we are grabbing the variable from a string made late in the program run, we will not get an error from GAUSS until the end of the program run if we forget to create one of the terms.

There are a couple of ways that we can do this, the first is by creating our own structure that has only one member that is a matrix. We can reshape this structure into an array of structures of any size. This allows us to loop over our variables using rows or cols to find the dimension. The nice thing about that is you can set it once and if you change the number of terms of your model, you only have to change the size of num_mats at the top of the program and the rest of the code will adjust to that.
New version using structures

rndseed 23423;

//Define structure
struct matrices {
    matrix mat;
};

r = 8;
c = 4;
num_mats = 10;

//Declare instance of structure
struct matrices ir;

//Reshape structure into an
//array of 10 structures
ir = reshape(ir, num_mats, 1);

//equivalent to 10 lines
//of ir1 = rndn(r,c)....
for i(1, rows(ir), 1);
    ir[i].mat = rndn(r, c);
endfor;

//Declare first instance of 'matrices' struct
struct matrices vd;

//Reshape to right size
vd = reshape(vd, rows(ir), 1);

//First term
vd[1].mat = ir[1].mat.^2;
tmp = vd[1].mat;

//Remaining terms
for i(2, rows(ir), 1);
    tmp = tmp + ir[i].mat.^2;
    vd[i].mat = 100*tmp./sumc(tmp');
endfor;

If I can get some time, I will post a version that uses multi-dimensional arrays later.

aptech

1,773


0



It's my full code...

please let me konw How I can revise my code...

I'm a beginner of Gauss problem. And I'm user of Gauss 10 version

It'd be very appreciated.

 

 

library maxlik;

maxset;

gausset;

cls;

rndseed 123457;

load returns[500,19] =c:/gauss/spillover.txt; /** Weekly real stock market returns

y = returns; // Choose the data

format /rd 10,5;

/** Estimate a VAR with lag p=2 **/

x = ones(rows(y)-2,1) ~ trimr(y,1,1) ~ trimr(y,0,2);

b = trimr(y,2,0)/x;

mue = trimr(b,0,38)'; /** MUE: Vector of intercepts **/

phi1 = trimr(b,1,19)'; /** PHI1: Lag 1 parameter estimates **/

phi2 = trimr(b,20,0)'; /** PHI2: Lag 2 parameter estimates **/

/** Generate VMA (non-orthogonalized) for horizons 1 to 10 **/

si1 = eye(cols(y));

si2 = phi1;

si3 = phi1*si2 + phi2;

si4 = phi1*si3 + phi2*si2;

si5 = phi1*si4 + phi2*si3;

si6 = phi1*si5 + phi2*si4;

si7 = phi1*si6 + phi2*si5;

si8 = phi1*si7 + phi2*si6;

si9 = phi1*si8 + phi2*si7;

si10 = phi1*si9 + phi2*si8;

/** Generate VMA (orthogonalized) for horizons 1 to 10 **/

v = trimr(y,2,0) - x*b; /** VAR residuals **/

omega = v'v/rows(v);

d = diag(omega);

s = chol(omega)';

 

ir1 = si1*s;

ir2 = si2*s;

ir3 = si3*s;

ir4 = si4*s;

ir5 = si5*s;

ir6 = si6*s;

ir7 = si7*s;

ir8 = si8*s;

ir9 = si9*s;

ir10 = si10*s;

/** Compute variance decompositions for horizons 1 to 10 **/

vd1 = ir1.^2;

vd1 = 100*vd1./sumc(vd1');

vd2 = ir1.^2 + ir2.^2;

vd2 = 100*vd2./sumc(vd2');

vd3 = ir1.^2 + ir2.^2 + ir3.^2;

vd3 = 100*vd3./sumc(vd3');

vd4 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2;

vd4 = 100*vd4./sumc(vd4');

vd5 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2;

vd5 = 100*vd5./sumc(vd5');

vd6 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2;

vd6 = 100*vd6./sumc(vd6');

vd7 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2;

vd7 = 100*vd7./sumc(vd7');

vd8 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2;

vd8 = 100*vd8./sumc(vd8');

vd9 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2;

vd9 = 100*vd9./sumc(vd9');

vd10 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2 + ir10.^2;

vd10 = 100*vd10./sumc(vd10');

format /rd 6,1;

print vd10;

lee

0


0



I almost understand your nice code.

thank you very much.

but when I try to print vd10  error occur...

//Remaining terms
for i(2, rows(ir), 1);
    tmp = tmp + ir[i].mat.^2;
    vd[i].mat = 100*tmp./sumc(tmp');
endfor;

It's your last code.
and

print vd10;

returns this output:

Undefined symbols: 
    vd10                               C:\gauss\revised spillover 2(100) 

vd10 is very important variable for calculating index.

please help me.

lee

0


0



In your original code you had separate matrices, vd1, vd2...vd10. The new code has an array of structures. So instead of printing vd10, you will print the mat member of the 10th element of the vd array of structures. i.e. instead of:

print vd10;

do this:

print vd[10].mat;

Take a look at the first two structures tutorials on the GAUSS tutorials page.

aptech

1,773


0



dear aptech.

I really appreciate it.

have a good time~!

lee

0

Your Answer

5 Answers

0

Let's start by posting a revised version of your original code. I added repeatable random numbers by setting the rndseed. This will allow us to have a more simple self-contained program to compare with the new one.

rndseed 23423;
r = 8;
c = 4;
ir1 = rndn(r, c);
ir2 = rndn(r, c);
ir3 = rndn(r, c);
ir4 = rndn(r, c);
ir5 = rndn(r, c);
ir6 = rndn(r, c);
ir7 = rndn(r, c);
ir8 = rndn(r, c);
ir9 = rndn(r, c);
ir10 = rndn(r, c);

vd1  = ir1.^2;
vd1  = 100*vd1./sumc(vd1');
vd2  = ir1.^2 + ir2.^2;
vd2  = 100*vd2./sumc(vd2');
vd3  = ir1.^2 + ir2.^2 + ir3.^2;
vd3  = 100*vd3./sumc(vd3');
vd4  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2;
vd4  = 100*vd4./sumc(vd4');
vd5  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2;
vd5  = 100*vd5./sumc(vd5');
vd6  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2;
vd6  = 100*vd6./sumc(vd6');
vd7  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2;
vd7  = 100*vd7./sumc(vd7');
vd8  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2;
vd8  = 100*vd8./sumc(vd8');
vd9  = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2;
vd9  = 100*vd9./sumc(vd9');
vd10 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2 + ir10.^2;
vd10 = 100*vd10./sumc(vd10');

tr=0;
for i(1, 10, 1);
    tmp = varget("vd"$+cvtos(ftocv(i, 1, 0)));
    tr = tr + sumc(diag(tmp*tmp'));
endfor;

This code works and is OK, but I think we can make it better by:

  1. Replacing the list of vd assignments to a loop:

    This will make the code much shorter and make it much, much easier and less error prone if you ever want to add more terms to your program.
  2. Remove the need to use varget and string manipulation to get the value of a global variable:

    This will work, but it is not as readable of code as it could be and since we are grabbing the variable from a string made late in the program run, we will not get an error from GAUSS until the end of the program run if we forget to create one of the terms.

There are a couple of ways that we can do this, the first is by creating our own structure that has only one member that is a matrix. We can reshape this structure into an array of structures of any size. This allows us to loop over our variables using rows or cols to find the dimension. The nice thing about that is you can set it once and if you change the number of terms of your model, you only have to change the size of num_mats at the top of the program and the rest of the code will adjust to that.
New version using structures

rndseed 23423;

//Define structure
struct matrices {
    matrix mat;
};

r = 8;
c = 4;
num_mats = 10;

//Declare instance of structure
struct matrices ir;

//Reshape structure into an
//array of 10 structures
ir = reshape(ir, num_mats, 1);

//equivalent to 10 lines
//of ir1 = rndn(r,c)....
for i(1, rows(ir), 1);
    ir[i].mat = rndn(r, c);
endfor;

//Declare first instance of 'matrices' struct
struct matrices vd;

//Reshape to right size
vd = reshape(vd, rows(ir), 1);

//First term
vd[1].mat = ir[1].mat.^2;
tmp = vd[1].mat;

//Remaining terms
for i(2, rows(ir), 1);
    tmp = tmp + ir[i].mat.^2;
    vd[i].mat = 100*tmp./sumc(tmp');
endfor;

If I can get some time, I will post a version that uses multi-dimensional arrays later.

0

It's my full code...

please let me konw How I can revise my code...

I'm a beginner of Gauss problem. And I'm user of Gauss 10 version

It'd be very appreciated.

 

 

library maxlik;

maxset;

gausset;

cls;

rndseed 123457;

load returns[500,19] =c:/gauss/spillover.txt; /** Weekly real stock market returns

y = returns; // Choose the data

format /rd 10,5;

/** Estimate a VAR with lag p=2 **/

x = ones(rows(y)-2,1) ~ trimr(y,1,1) ~ trimr(y,0,2);

b = trimr(y,2,0)/x;

mue = trimr(b,0,38)'; /** MUE: Vector of intercepts **/

phi1 = trimr(b,1,19)'; /** PHI1: Lag 1 parameter estimates **/

phi2 = trimr(b,20,0)'; /** PHI2: Lag 2 parameter estimates **/

/** Generate VMA (non-orthogonalized) for horizons 1 to 10 **/

si1 = eye(cols(y));

si2 = phi1;

si3 = phi1*si2 + phi2;

si4 = phi1*si3 + phi2*si2;

si5 = phi1*si4 + phi2*si3;

si6 = phi1*si5 + phi2*si4;

si7 = phi1*si6 + phi2*si5;

si8 = phi1*si7 + phi2*si6;

si9 = phi1*si8 + phi2*si7;

si10 = phi1*si9 + phi2*si8;

/** Generate VMA (orthogonalized) for horizons 1 to 10 **/

v = trimr(y,2,0) - x*b; /** VAR residuals **/

omega = v'v/rows(v);

d = diag(omega);

s = chol(omega)';

 

ir1 = si1*s;

ir2 = si2*s;

ir3 = si3*s;

ir4 = si4*s;

ir5 = si5*s;

ir6 = si6*s;

ir7 = si7*s;

ir8 = si8*s;

ir9 = si9*s;

ir10 = si10*s;

/** Compute variance decompositions for horizons 1 to 10 **/

vd1 = ir1.^2;

vd1 = 100*vd1./sumc(vd1');

vd2 = ir1.^2 + ir2.^2;

vd2 = 100*vd2./sumc(vd2');

vd3 = ir1.^2 + ir2.^2 + ir3.^2;

vd3 = 100*vd3./sumc(vd3');

vd4 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2;

vd4 = 100*vd4./sumc(vd4');

vd5 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2;

vd5 = 100*vd5./sumc(vd5');

vd6 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2;

vd6 = 100*vd6./sumc(vd6');

vd7 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2;

vd7 = 100*vd7./sumc(vd7');

vd8 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2;

vd8 = 100*vd8./sumc(vd8');

vd9 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2;

vd9 = 100*vd9./sumc(vd9');

vd10 = ir1.^2 + ir2.^2 + ir3.^2 + ir4.^2 + ir5.^2 + ir6.^2 + ir7.^2 + ir8.^2 + ir9.^2 + ir10.^2;

vd10 = 100*vd10./sumc(vd10');

format /rd 6,1;

print vd10;

0

I almost understand your nice code.

thank you very much.

but when I try to print vd10  error occur...

//Remaining terms
for i(2, rows(ir), 1);
    tmp = tmp + ir[i].mat.^2;
    vd[i].mat = 100*tmp./sumc(tmp');
endfor;

It's your last code.
and

print vd10;

returns this output:

Undefined symbols: 
    vd10                               C:\gauss\revised spillover 2(100) 

vd10 is very important variable for calculating index.

please help me.

0

In your original code you had separate matrices, vd1, vd2...vd10. The new code has an array of structures. So instead of printing vd10, you will print the mat member of the 10th element of the vd array of structures. i.e. instead of:

print vd10;

do this:

print vd[10].mat;

Take a look at the first two structures tutorials on the GAUSS tutorials page.

0

dear aptech.

I really appreciate it.

have a good time~!


You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.