create multiple vectors in a loop

Hello,

I am running Gauss 12 and would like to  create multiple vectors in a loop. For simplicity, assume the following situation, the code of which is obviously not working:

for i (1,4,1);

x _i = zeros(10,1);

endfor;

The goal would thus be to get four (10,1) zero-vectors labeled as x_1,x_2,.... Is there an easy way to fix this in Gauss?

Thank you for your support!

Etiënne

3 Answers



1



You can create new GAUSS global variables with the GAUSS function varput. Let's first go through a simple example of varput usage. If we want to create a new GAUSS global variable named phi and set it equal to 3, we would usually write this line of GAUSS code:

phi = 3;

We can also accomplish the same thing using the varput function. varput will create (or "put") a new variable in your GAUSS workspace.

//alternative to: phi = 3;
ret = varput(3, "phi");

Now that we can create a new GAUSS variable from a string, we need a way to turn the loop counter from a number into a string and then combine strings. In GAUSS 14 and newer, you can use ntos to turn a number into a string, like this:

i = 1;
i_string = ntos(i);

In older versions of GAUSS, you will need to use a combination of ftocv and cvtos, or ftos which is slightly more complicated. Here is an example:

i = 1;
i_string = cvtos(ftocv(i, 0, 0));

Now that we have converted our number to a string, we can combine it with another string using the GAUSS string combination operator, $+:

var_name = "x_" $+ i_string;

Putting all of this together, would look like this (for GAUSS 14 or newer):

for i(1, 4, 1);
    ret = varput(zeros(10,1), "x_" $+ ntos(i));
endfor;

or like this (for older versions of GAUSS):

for i(1, 4, 1);
    ret = varput(zeros(10,1), "x_" $+ cvtos(ftocv(i, 0, 0)));
endfor;

However, I would strongly recommend that you simply create one x matrix and reference the different columns using indexing, like this:

x = zeros(10, 4);

//reference the first column of 'x'
first_var = x[.,1];

The code will almost always be much simpler to read and also execute faster. If you are not sure how you might incorporate this second method into your specific code, I would encourage you to post that as a question. Thinking about your model in terms of a matrix and indexing can sometimes seem less straightforward at first. However, it is not difficult and (I am alsmost certain) you will be glad that you did.

aptech

1,773


0



Thank you for your very elaborate answer. I will put this to the test immediately.

As for your comment on indexing variables as matrices, I absolutely agree this normally makes programming clearer and faster to execute, but I ran across a problem that seems to prevent me from using matrices all the way through. I am using the "shiftr" command to generate series with different lags, which I will eventually use in an AR(p) model where I will let the lag length be determined on the basis of the minimum AIC. My amateur code that I used before (really inefficient) looks as follows:

p=12

l = seqa(1,1,p);
m_garch = ones(p,1).*.yd_garch';
m_sv = ones(p,1).*.yd_sv';
m_stv = ones(p,1).*.yd_stv';
m_rsv = ones(p,1).*.yd_rsv';
lags_yd_garch = shiftr(m_garch,l,0)';
lags_yd_sv = shiftr(m_sv,l,0)';
lags_yd_stv = shiftr(m_stv,l,0)';
lags_yd_rsv = shiftr(m_rsv,l,0)';

The rest of the code is not relevant, as this shows what I eventually want to achieve. So I have to do OLS for 4 different series. I have now started combining all the different series (yd_...) in a matrix "yd". Using the kronecker product on this matrix will change the usefulnedd of the shiftr command I think. The ideal solution would be:

for i(1,4,1);

m_(i) = ones(p,1).*.yd[.,i]';   //(i) is obviously not a valid command//

lags_yd_(i) = shiftr(m_(i),1,0)';

endfor;

So I hope I can do something like this using the code you proposed above.

Any further suggestions are always welcome of course!

Thanks again



0



I do have a couple of suggestions for you. The GAUSS function, lagn, will create multiple lags for you in one call. For example, you could change these two lines:

p=12
l = seqa(1,1,p);

m_garch = ones(p,1).*.yd_garch';
lags_yd_garch = shiftr(m_garch,l,0)';

to this:

p = 12;
l = seqa(1, 1, p);

lags_yd_garch = lagn(yd_garch, p);

The one difference between the lagn procedure and yours is that lagn fills in the empty matrix elements with GAUSS missing values, while yours fills them in with zeros. For example:

 lagn output         your method
1.1    .    .        1.1    0    0
3.5  1.1    .        3.5  1.1    0
2.8  3.5  1.1        2.8  3.5  1.1
3.1  2.8  3.5        3.1  2.8  3.5

What is nice about filling the missing elements with GAUSS missing values is that you can easily remove all of the rows that contain a missing value with the GAUSS packr function. However, if you want to use zeros instead, you can modify the lagn code to do that.

My second suggestion would be to make a procedure do most of the work and then call that 4 times instead of doing all the work for all 4 vectors. Instead of doing something like this:

p=12

l = seqa(1,1,p);

lags_yd_garch = lagn(yd_garch, l);
lags_yd_sv = lagn(yd_sv, l);
lags_yd_stv = lagn(yd_stv, l);
lags_yd_rsv = lagn(yd_rsv, l);

//remove missing value rows for ols regression
lags_yd_garch = packr(lags_yd_garch);
lags_yd_sv = packr(lags_yd_sv);
lags_yd_rsv = packr(lags_yd_rsv);
lags_yd_stv = packr(lags_yd_stv);

//calculate OLS parameter estimates
b_hat_yd_garch = lags_yd_garch[.,1]/lags_yd_garch[.,2:cols(lags_yd_garch)];
b_hat_yd_sv = lags_yd_sv[.,1]/lags_yd_sv[.,2:cols(lags_yd_sv)];
b_hat_yd_rsv = lags_yd_rsv[.,1]/lags_yd_rsv[.,2:cols(lags_yd_rsv)];
b_hat_yd_stv = lags_yd_stv[.,1]/lags_yd_stv[.,2:cols(lags_yd_stv)];

do this instead:

p=12
bhat_yd_garch = olsLagN(yd_garch, p);
bhat_yd_sv = olsLagN(yd_sv, p);
bhat_yd_rsv = olsLagN(yd_rsv, p);
bhat_yd_stv = olsLagN(yd_stv, p);

proc (1) = olsLagN(y, p);
local l, lags_y, b_hat;
   l = seqa(1,1,p);

   lags_y = lagn(y, l);

   //remove missing value rows for ols regression
   lags_y = packr(lags_y);

   //calculate OLS parameter estimates
   b_hat = lags_y[.,1]/lags_y[.,2:cols(lags_y)];
retp(b_hat);
endp;

This version is a bit shorter and easier to read. It will also scale to more vectors much easier. I am not certain exactly what you are trying to do, so maybe it will not be exactly as simple to apply as this, but it is something to keep in mind at least.

aptech

1,773

Your Answer

3 Answers

1

You can create new GAUSS global variables with the GAUSS function varput. Let's first go through a simple example of varput usage. If we want to create a new GAUSS global variable named phi and set it equal to 3, we would usually write this line of GAUSS code:

phi = 3;

We can also accomplish the same thing using the varput function. varput will create (or "put") a new variable in your GAUSS workspace.

//alternative to: phi = 3;
ret = varput(3, "phi");

Now that we can create a new GAUSS variable from a string, we need a way to turn the loop counter from a number into a string and then combine strings. In GAUSS 14 and newer, you can use ntos to turn a number into a string, like this:

i = 1;
i_string = ntos(i);

In older versions of GAUSS, you will need to use a combination of ftocv and cvtos, or ftos which is slightly more complicated. Here is an example:

i = 1;
i_string = cvtos(ftocv(i, 0, 0));

Now that we have converted our number to a string, we can combine it with another string using the GAUSS string combination operator, $+:

var_name = "x_" $+ i_string;

Putting all of this together, would look like this (for GAUSS 14 or newer):

for i(1, 4, 1);
    ret = varput(zeros(10,1), "x_" $+ ntos(i));
endfor;

or like this (for older versions of GAUSS):

for i(1, 4, 1);
    ret = varput(zeros(10,1), "x_" $+ cvtos(ftocv(i, 0, 0)));
endfor;

However, I would strongly recommend that you simply create one x matrix and reference the different columns using indexing, like this:

x = zeros(10, 4);

//reference the first column of 'x'
first_var = x[.,1];

The code will almost always be much simpler to read and also execute faster. If you are not sure how you might incorporate this second method into your specific code, I would encourage you to post that as a question. Thinking about your model in terms of a matrix and indexing can sometimes seem less straightforward at first. However, it is not difficult and (I am alsmost certain) you will be glad that you did.

0

Thank you for your very elaborate answer. I will put this to the test immediately.

As for your comment on indexing variables as matrices, I absolutely agree this normally makes programming clearer and faster to execute, but I ran across a problem that seems to prevent me from using matrices all the way through. I am using the "shiftr" command to generate series with different lags, which I will eventually use in an AR(p) model where I will let the lag length be determined on the basis of the minimum AIC. My amateur code that I used before (really inefficient) looks as follows:

p=12

l = seqa(1,1,p);
m_garch = ones(p,1).*.yd_garch';
m_sv = ones(p,1).*.yd_sv';
m_stv = ones(p,1).*.yd_stv';
m_rsv = ones(p,1).*.yd_rsv';
lags_yd_garch = shiftr(m_garch,l,0)';
lags_yd_sv = shiftr(m_sv,l,0)';
lags_yd_stv = shiftr(m_stv,l,0)';
lags_yd_rsv = shiftr(m_rsv,l,0)';

The rest of the code is not relevant, as this shows what I eventually want to achieve. So I have to do OLS for 4 different series. I have now started combining all the different series (yd_...) in a matrix "yd". Using the kronecker product on this matrix will change the usefulnedd of the shiftr command I think. The ideal solution would be:

for i(1,4,1);

m_(i) = ones(p,1).*.yd[.,i]';   //(i) is obviously not a valid command//

lags_yd_(i) = shiftr(m_(i),1,0)';

endfor;

So I hope I can do something like this using the code you proposed above.

Any further suggestions are always welcome of course!

Thanks again

0

I do have a couple of suggestions for you. The GAUSS function, lagn, will create multiple lags for you in one call. For example, you could change these two lines:

p=12
l = seqa(1,1,p);

m_garch = ones(p,1).*.yd_garch';
lags_yd_garch = shiftr(m_garch,l,0)';

to this:

p = 12;
l = seqa(1, 1, p);

lags_yd_garch = lagn(yd_garch, p);

The one difference between the lagn procedure and yours is that lagn fills in the empty matrix elements with GAUSS missing values, while yours fills them in with zeros. For example:

 lagn output         your method
1.1    .    .        1.1    0    0
3.5  1.1    .        3.5  1.1    0
2.8  3.5  1.1        2.8  3.5  1.1
3.1  2.8  3.5        3.1  2.8  3.5

What is nice about filling the missing elements with GAUSS missing values is that you can easily remove all of the rows that contain a missing value with the GAUSS packr function. However, if you want to use zeros instead, you can modify the lagn code to do that.

My second suggestion would be to make a procedure do most of the work and then call that 4 times instead of doing all the work for all 4 vectors. Instead of doing something like this:

p=12

l = seqa(1,1,p);

lags_yd_garch = lagn(yd_garch, l);
lags_yd_sv = lagn(yd_sv, l);
lags_yd_stv = lagn(yd_stv, l);
lags_yd_rsv = lagn(yd_rsv, l);

//remove missing value rows for ols regression
lags_yd_garch = packr(lags_yd_garch);
lags_yd_sv = packr(lags_yd_sv);
lags_yd_rsv = packr(lags_yd_rsv);
lags_yd_stv = packr(lags_yd_stv);

//calculate OLS parameter estimates
b_hat_yd_garch = lags_yd_garch[.,1]/lags_yd_garch[.,2:cols(lags_yd_garch)];
b_hat_yd_sv = lags_yd_sv[.,1]/lags_yd_sv[.,2:cols(lags_yd_sv)];
b_hat_yd_rsv = lags_yd_rsv[.,1]/lags_yd_rsv[.,2:cols(lags_yd_rsv)];
b_hat_yd_stv = lags_yd_stv[.,1]/lags_yd_stv[.,2:cols(lags_yd_stv)];

do this instead:

p=12
bhat_yd_garch = olsLagN(yd_garch, p);
bhat_yd_sv = olsLagN(yd_sv, p);
bhat_yd_rsv = olsLagN(yd_rsv, p);
bhat_yd_stv = olsLagN(yd_stv, p);

proc (1) = olsLagN(y, p);
local l, lags_y, b_hat;
   l = seqa(1,1,p);

   lags_y = lagn(y, l);

   //remove missing value rows for ols regression
   lags_y = packr(lags_y);

   //calculate OLS parameter estimates
   b_hat = lags_y[.,1]/lags_y[.,2:cols(lags_y)];
retp(b_hat);
endp;

This version is a bit shorter and easier to read. It will also scale to more vectors much easier. I am not certain exactly what you are trying to do, so maybe it will not be exactly as simple to apply as this, but it is something to keep in mind at least.


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.