|
<< Click to Display Table of Contents >> FOR |
![]() ![]()
|
The FOR statement initiates a loop over strings, dates or values. Parallel loops (tandem) over lists are also possible. Like procedure and function definitions, Gekko demands that the variable type is stated explicitly.
Guide: loops For an easier introductory guide on Gekko loops, see this page. |
This elements loop loops through the list of elements on the right-hand side of =.
for [type] %x = items ;
statements... ;
end ;
[type] |
The type must be indicated |
%x |
The loop variable %x |
items |
Any list of items. For a simple list of strings, you may use the naked list a, b, c instead of ('a', 'b', 'c'), similar to how a list may be defined using short form. You may also use for instance lists (#mylist) or wildcards (e.g. fx*). You may also use a list of values, for instance (1, 2, 3), or a list of dates, for instance (2001q1, 2001q2, 2001q3). |
Note that you may use parentheses, for instance for([type] %x = items), like the IF statement. |
|
This parallel string loop loops through the items in parallel/tandem. So in the i'th iteration, %s1 is equal to the i'th item in items1, %s2 is equal to the i'th item in items2, etc. The number of items must be the same in all the lists on the right-hand sides of the =. And the names on the left-hand sides of the = must be different. The type must be stated.
for type1 %s1=items1 type2 %s2=items2 type3 %s3=items3 ... ;
statements... ;
end ;
%s1, %s2, ... |
The loop variables (for instance: strings). |
items1, items2, ... |
Any list of items. |
Note that you may use parentheses for( %s1=items1 %s2=items2 ... ), like the IF statement. |
|
A date loop loops through dates from a start date to an end date, with an optional stepsize. (To use logical conditions on individual observations inside timeseries, see the iif() function)
for date %d = date1 TO date2 BY step ;
statements... ;
end ;
%d |
The loop variable d (of date type). |
date1 |
Start date (inclusive), can be expression (including integer value). |
date2 |
End date (inclusive), can be expression (including integer value). |
step |
(Optional). An optional stepsize (default step: 1). Must be integer, and may be negative. You may omit BY step if not needed. |
TO |
You may use .. (range) instead: for instance for date %d = 2015q1 .. 2020q4; |
Note that you may use parentheses for(date %d = date1 TO date2 BY step), like the IF statement. If one or both of date1 and date2 are positive integers, they will be interpreted as annual dates. You cannot combine parallel looping with FOR ... TO syntax, but in that case consider using the seq() function (cf. "Examples (parallel loops)"). |
|
A value loop loops through values from a start value to an end value, with an optional stepsize. If the stepsize is negative, the values will decrement.
for val %v = val1 TO val2 BY step ;
statements... ;
end ;
%v |
The loop variable %v. |
val1 |
Start value. Can be any number or expression. |
val2 |
End value. Can be any number or expression. |
step |
An optional stepsize (default step: 1). Can be any number or expression, and may be negative. Omit BY step if not needed. |
TO |
You may use .. (range) instead: for instance for val %v = 1 .. 100; |
Note that you may use parentheses for(val %v = val1 TO val2 BY step), like the IF statement. You cannot combine parallel looping with FOR ... TO syntax, but in that case consider using the seq() function (cf. "Examples (parallel loops)"). |
|
You may wish to use some sector codes to print out production values easily:
xa = 1; xb = 2; xc = 3; |
This will print out the variables xa, xb, xc (one by one). You may use a pre-defined list after the = in the for statement for string %i = #mylist;, or a wild-card list (for string %i = ['fx*'];), or combinations of these.
Nested loop:
xayc = 1; xayd = 2; xbyc = 3; xbyd = 4; for string %i = a, b; //or: ('a', 'b') |
The loop prints 4 variables xayc, xayd, xbyc, xbyd. Note that you can easily pre- and suffix list items, cf. the LIST statement.
Gekko can also loop over a list of values or dates, for instance:
option freq q; |
This will set the period 2020q1-2020q2, and afterwards 2020q3-2020q4. Note the parenthesis in the first line. Without it, the list will be understood as ('2020q1', '2020q3'), that is, two strings and not two dates.
You may loop two or more lists in parallel, cf. the examples in the section "Examples (parallel loops)".
To compute the largest number of the variable fX{%i}, for the sectors a, b, nf, qf, over the period %d1 to %d2:
%d1 = 1990; |
After this loop, the string %imax will contain the sector name with the highest number, the date %dmax will contain the period containing that number, and the value %max will contain the max number. It is assumed that the values are all positive, so that %max can safely start out with value 0.
The following example sets the timeseries y, depending upon two timeseries x1 and x2, over the period 2001-2003. For the observations where x1 > x2, y is set to x0, else to %v (a scalar).
for (date %d = 2001 to 2003); |
Note that such conditional setting of values via time-looping can be done much easier with the iif() function:
<2001 2003> y = iif(x1, '>', x2, x0, %v); |
You may loop over frequencies like this:
for string %i = a, q, m; |
After this, there will be series x!a, x!q and x!m, corresponding to each of the frequencies a, q and m. Looping over days includes possible leap days (February 29):
for date %d = 2020m2d27 to 2020m3d2; |
A value loop is similar to date loops
for val %v = 10 to 0 by -2.5; |
This will print out the numbers 10, 7.5, 5, 2.5 and 0.
for (val %v = 10 to 0 by -2.5) |
Equivalently, using parentheses (the semicolon in the first line may be omitted in this case). This is just to avoid an error if the user assumes the same syntax as the IF statement (which has mandatory parentheses).
You may use parallel lists like this:
#m1 = a, b, c; //or: ('a', 'b', 'c') |
The above loop only runs 3 times in all. Parallel loops are an easy way to loop two (or more) lists in tandem. It is much easier than doing the same loop 'manually', like the code below (produces the same output):
#m1 = a, b, c; |
Parallel looping only works over two or more lists of same length, and parallel loops do not allow the FOR ... TO syntax. However, for sequences, you may consider using the seq() function to easily create the lists:
for val %i = seq(0, 2) date %j = seq(2020q3, 2021q1); |
If you need to use fractions or other values than integers, you could just define for instance %i2 = %i/100 inside the loop to get 0.00, 0.01, 0.02.
You may sometimes need to use an explicit type conversion from one scalar variable type to another. In that case, use the conversion functions val(), date() or string().
seq()