Functions

<< Click to Display Table of Contents >>

Navigation:  Gekko User Manual > Gekko functions >

Functions

Previous pageReturn to chapter overviewNext page

Gekko has a number of in-built functions, listed below. Note that all Gekko functions implement so-called UFCS so that a function like for instance f(x, y) can generally be written as x.f(y), and f(x) can generally be written as x.f().

 

Mathematical functions:

 

Function name

Description

Examples

abs(x)

Returns the absolute value of x (series, val or matrix).

Returns: series/value/matrix

%v1 = abs(%v2);

avg(x1, x2, ...)

Returns the average of x1, x2, ... etc. The input parameters may be series or value.

Returns: series/value

= avg(x1, x2, x3);
%= avg(%v1, %v2, %v3);

avgt(x)

avgt(<t1 t2>, x)

Returns the time-average of the observations of the timeseries x over the local/global time period (or over t1 to t2, if indicated)

Returns: series

= avgt(x);
= avgt(<2020 2025>, x);
= x.avgt(<2020 2025>);  //same as above

ceiling(x)

Returns the the smallest integer which is greater than or equal to x (series, val or matrix). See also int(), floor() and round().

Returns: series/value/matrix

prt ceiling(-2.2);

dif(x) or diff(x)

Absolute time-difference of  series x: can also be used on left side of '='. Does not work on value.

Returns: series

= dif(x);
dif(y) = 100;

dify(x) or diffy(x)

Yearly difference. Same as dif(x), but will use 4 lags for quarterly data, and 12 lags for monthly data.

Returns: series

= dify(x);

dlog(x)

Logarithmic time-difference of series x: can also be used on left side of '='. Does not work on value.

Returns: series

= dlog(x);
dlog(y) = 0.02;

dlogy(x)

Yearly logarithmic time-difference. Same as dlog(x), but will use 4 lags for quarterly data, and 12 lags for monthly data.

Returns: series

= dlogy(x);

exp(x)

Returns the exponential value of x (series, value or matrix).

Returns: series/value

= exp(x);
%v1 = exp(%v2);

floor(x)

Returns the largest integer which is less than or equal to x (series, val or matrix). See also int(), ceiling() and round().

Returns: series/value/matrix

prt floor(-2.2);

iif(in1, op, in2, out1, out2)

 

Conditional, works like an if statement. Think of it like if in1 op in2 then out1 else out2, where op is a string containing the operator ==, <>, <, <=, >=, >. The function can be used to avoid explicit time looping for timeseries. The op input must be a string, and the rest of the inputs must be of math type (there is another iif()-example here). If needed, you can use == (or <>) together with m() to test for the presence of missing values, see example.

 

You may alternatively use $-conditionals, see examples under SERIES. See also the replace() and isMiss() functions for series.

Returns: series/value

time 2010 2012;
in1 = 1, 2, 3;
in2 = 3, 2, 1;
y1 = iif(in1, '<=', in2, 50, 100);
//Result: y1 = 50, 50, 100.
 
 
in3 = 100, m(), 300;
y2 = iif(in3, '==', m(), 1000, in3);
//Result: y2 = 100, 1000, 300

int(x)

Returns the integer value of x (series, val or matrix), discarding the fractional part (after the .). See also floor(), ceiling() and round().

Returns: series/value/matrix

prt int(-2.2);

isMiss(x)

isMiss(x, 'all')

The input parameter may be series or value, and the function returns 1 or 0 (or 1's and 0's).

 

If x is a series, the first variant of the function returns 1, else 0, over the period that contains data (cf. fromSeries(x, 'dataStart') and fromSeries(x, 'dataEnd')). With option 'all', the local or global period is used instead.

 

An example is provided regarding how to replace missing values inside series, but note that this can also be done with the iif() or replace() functions.

 

See also allMiss().

 

Returns: series/value

prt isMiss(1); prt isMiss(miss());
time 2020 2023;
= 1, m(), 3, m();
prt <n> z, z.isMiss(), z.isMiss('all');
//Note that for 2023, the function returns a
//missing value. The function only finds missing
//values between non-missing values.
//With 'all' option, missing values that are not
//enclosed between non-missing values will be 
//set to 1, too.
prt sumt(z.isMiss('all'));
//Prints the number of missings over 2020-23.
 
time 2021 2025;
= 1, 2, m(), 4, 5;
= 100;
= y $ (x.isMiss()) + x $ (not x.isMiss());
//y becomes 1, 2, 100, 4, 5. See also iif() function.
 
time 2021 2026;
= 1, m(), m(), 4, m(), 6;
x $ (x.ismiss('all')) %= 0;
//x becomes 1, 1, 1, 4, 4, 6, 
//filling out missing "holes"

lag(x, lag)

Lags series x a number of periods. Note the sign of the lag: lag(x, 2) = x[-2]. Can be used if x is an expression.

Returns: series

= lag(x, 2);  //same as x[-2]

log(x)

Returns the natural logarithmic value of x (series, value or matrix). Can also be used on the left side of '='.

Returns: series/value/matrix

= log(x);
%v1 = log(%v2);

log(y) = a * log(b);

max(x1, x2, ... )

Finds the largest value. Arguments may be value, series or date.

Returns: value/series/date.

[New in 3.1.6]

prt max(2, 4, 1, 3);
prt max(2000q1, 2000q4);
time 2001 2003;
x1 = 1, 2, 3;
prt max(x1, 2);

min(x1, x2, ... )

Finds the lowest value. Arguments may be value, series or date.

Returns: value/series/date.

[New in 3.1.6]

prt min(2, 4, 1, 3);
prt min(2000q1, 2000q4);
time 2001 2003;
x1 = 1, 2, 3;
prt min(x1, 2);

mod(x1, x2)

Modulo, the remainder of the division x1/x2.

Returns: value/series.

[New in 3.1.12]

%= mod(7, 4); //3
%= mod(8, 4); //0
%= mod(9, 4); //1

 

 

movavg(x1, lags)

Moving average of series x1.

Returns: series

= movavg(x, 3);
= (+ x[-1] + x[-2])/3;  //same

movsum(x1, lags)

Moving sum of series x1, cf. movavg().

Returns: series

= movsum(x, 3);
= x + x[-1] + x[-2];  //same

pch(x)

Percentage growth in series x: can also be used on left side of '='. Does not work on value.

Returns: series

= pch(x);
pch(y) = 2;

pchy(x)

Yearly growth. Same as pch(x), but will use 4 lags for quarterly data, and 12 lags for monthly data.

Returns: series

= pchy(x);

pow(x, y)

The exponent must be a value or number, not a series. The function pow(x, y) is equal to x**y or x^y, that is, a in the y'th power. You may use power(x, y) as synonym.

Returns: series/value

= pow(x1, %x2);
%= pow(%x1, %x2);

rnorm(mean, var)

rnorm(mean, vcov)

Returns a random number from a normal distribution with mean and variance provided. If fed with a n x 1 matrix of averages, and a n x n covariance matrix, the function will return a n x 1 matrix of values. See also rseed() and runif().

Returns: value/matrix

%= rnorm(0, 1);
%= rnorm(-100, 25**2);
#= rnorm(#mean, #vcovar);

rseed(x)

Given value x, it sets a random seed for runif() and rnorm() functions. The function returns the seed as a value, but can be used without return value.

Returns: value

rseed(12345);
 

round(x, d)

Rounds x (series, val or matrix) to d decimal places. See also int(), floor() and ceiling().

Returns: series/value/matrix

%v1 = round(%v2, 3);

runif()

Returns a random number from a uniform distribution between 0 and 1. See also rseed() and rnorm().

Returns: value

%= runif();

seq(start, end)

Returns a list of integer values or dates between start and end (both included). Start and end must be two values or two dates.

Returns: list

#= seq(1, 100);
#= seq(2001q1, 2005q4);

sqrt(x)

Returns the square root of x (series, value or matrix).

Returns: series/value/matrix

= sqrt(x);
%v1 = sqrt(%v2);

sum(x1, x2, ...)

sum(list, x)

Returns the sum of x1, x2, ... etc. The input parameters may be series or value.

If the first argument is a list name (or a list of list names), the sum function will sum the second argument over these lists.

Returns: series/value

= sum(x1, x2, x3);
%= sum(%v1, %v2, %v3);

 

= sum(#j, x[a, #j]);
= sum((#i, #j), x[#i, #j]);
= sum(#j, xa{#j});
= sum((#i, #j), x{#i}{#j});

 

To sum a simple list #j of series names, you may use this:

 

= sum({#j}); //shorter than sum(#j, {#j})

 

Note that for PRT/PLOT etc., you should use the more explicit PRT sum(#j, {#j}); because PRT/PLOT auto-unfolds 'uncontrolled' lists into columns/lines.

sumt(x)

sumt(<t1 t2>, x)

Returns the time-sum of the observations of the timeseries x over the local/global time period (or over t1 to t2, if indicated)

Returns: series

= sumt(x);
= sumt(<2020 2025>, x);
= x.sumt(<2020 2025>);  //same as above

tanh(x)

Returns the hyperbolic tangens of x (series, value or matrix). Returns: series/value/matrix

%= tanh(0.5);

 

 

Conversions

 

Function name

Description

Examples

date(x)

Tries to convert the scalar x to date type. See also under "date combining functions".

Returns: date

%= date(2000+15);
Result: %= 2015.

dates(x)

Tries to convert each element of the list x into a date.

Returns: list

#m1 = (2001, 2002, 2003);
#m2 = dates(#m1);  //or: #m1.dates()

data(x)

Converts a string x containing blank-separated numbers to a list of values.

Returns: list of values

#= data('1 2 3');
= data('1 2 3');

format(x, code)

 

Formats the value/date/string x by means of the formatting code. The formatting code is as follows for values:

 

'[width]:[format]'
'[width]:[format]=[culture]'

 

The width specifies that the string will be at least [width] characters wide. If the [width] is positive, the number is right-aligned within the field, and if it is negative, it is left-aligned.

 

The [format] follows the conventions shown here or here, so you may either use a pattern like 0.000 or 0.### (exactly three digits or at most three digits), or you may use a description like F3 (floating point, three digits). So 12:0.000 or 12:F3 are both a 12 characters wide field, and a number with three decimals.

 

The [culture] argument after an optional = symbol changes how thousands and decimal operators look like. For instance, en-US is English (US variant), da-DK is Danish, see the possible cultures here. So format(1234567.8987, '0,0.00=da-DK') will return 1.234.567,90. Without culture, it would return 1,234,567.90.

 

A value format can be set globally with option string interpolate format val = ... ;. This can be practical when printing out for instance a table of values with the same value formatting.

 

You may also format strings or dates: in that case only [width] can be used (positive or negative). In this way, table-like alignment is quite straightforward.

 

Returns: string.

%= 12.3456;

%= 2020q1;
%= 'abc';
 
tell;
tell '123456789012' + '|';
tell '------------' + '|';
tell %v.format('0.000') + '|';
tell %v.format('12:0.000') + '|';
tell %d.format('12') + '|';
tell %s.format('12') + '|';
tell %v.format('-12:0.000') + '|';
tell %d.format('-12') + '|';
tell %s.format('-12') + '|';
tell '------------' + '|';
 
// 123456789012|
// ------------|
// 12.346|
//       12.346|

//       2020q1|
//          abc|
// 12.346      |

// 2020q1      |
// abc         |
// ------------|

string(x)

Tries to convert the scalar x to string type. See also under "string combining functions".

If x is a list of strings, the string() function returns a comma-separated list of strings.

Returns: string

%= string(12) + string(34);
Result: %= '1234'.

strings(x)

Tries to convert each element of the list x into a string.

Returns: list

#m1 = (1, 2, 3);
#m2 = strings(#m1); //or: #m1.strings()

val(x)

Tries to convert the scalar x to value type.

Returns: value

%= val('12' + '34');
Result: %= 1234.

vals(x)

Tries to convert each element of the list x into a value.

Returns: list

#m1 = ('1', '2', '3');
#m2 = vals(#m1);  //or: #m1.vals()

 

Date combining functions

 

Function name

Description

Examples

date(d, f, opt)

date(d, f)

Converts the date d into a new date with frequency f (string). The optional option can be omitted, or be 'start' or 'end'. Using 'start' or 'end' is only relevant when converting from a lower to a higher frequency.

 

Beware that week numbers are special around New Year.

 

Returns: date

%= 2021q1;
prt %d.date('a'); //2021

prt %d.date('m'); //error!
prt %d.date('m', 'start'); //2021m1
prt %d.date('m', 'end');   //2021m3
prt %d.date('w', 'start'); //2020w53 !!
prt %d.date('w', 'end');   //2021w13
//Note that the first week that fully 
//contains the first quarter of 2021 starts
//in 2020!

date(y, f, sub)

date(y, 'm', m, 'd', d)

Constructs a new quarterly/monthly/weekly date from y (integer), frequency (string), and subperiod (integer). You may also construct a daily date with a similar syntax.

 

Note: you may also use date(x), where x can be a value or a string, and Gekko will try to convert the argument into a date.

 

Returns: date

%= date(2020, 'q', 2);  //2020q2
%= date(2020, 'w', 42);  //2020w42
%= date(2020, 'm', 12, 'd', 24);  //2020m12d24

fromExcelDate(v)

Converts an Excel date (the val v, counting the number of days since January 1, 1900) to a date with daily frequency.

 

Returns: date (daily)

See examples regarding the toExcelDate() function.

getFreq(d)

Extracts the frequency of a date

Returns: string

%= 2020q2;
prt %d.getfreq();  //'q'

getDay(d)

Extracts the day number from a date. Will fail if the date is not daily.

Returns: value (integer)

%= 2020m3d25;
prt %d.getday(); //25

getSpecialDay(year, name)

Finds a special day by year and name, and returns its daily date. Mostly used for holidays. If you input a wrong name, Gekko will provide a link showing all possible special days. Current possible holiday names (English, and equivalent Danish names):

 

New_Years_Day            

Nytaarsdag

Leap_Day

Skuddag

Maundy_Thursday          

Skaertorsdag

Good_Friday              

Langfredag

Easter_Sunday            

Paaskedag

Easter_Monday            

Anden_paaskedag

Labour_Day              

Foerste_maj

General_Prayer_Day      

Store_bededag

Ascension_Day            

Kristi_himmelfartsdag

Whit_Sunday              

Pinsedag

Whit_Monday              

Anden_pinsedag

Constitution_Day        

Grundlovsdag

Christmas_Eve            

Juleaften

Christmas_Day            

Foerste_juledag

Boxing_Day              

Anden_juledag

New_Years_Eve            

Nytaarsaften

 

Note that getSpecialDay(%year, 'Leap_Day') may return a null value, else it returns February 29 in leap years). The leap day is not a holiday, but is nevertheless kept in this list of special days. See example.

prt 2021.getSpecialDay('Easter_Sunday'); //2021m4d4
prt 2021.getSpecialDay('Paaskedag');     //same day
 
for(val %year = 2021 to 2025);
  %day = %year.getSpecialDay('Christmas_Eve');
  %= %day.getWeekday('en');
  tell 'In {%year}, Christmas Eve is on a {%s}';
end;
//Result:
//In 2021, Christmas Eve is on a Friday
//In 2022, Christmas Eve is on a Saturday
//In 2023, Christmas Eve is on a Sunday
//In 2024, Christmas Eve is on a Tuesday
//In 2025, Christmas Eve is on a Wednesday
 
prt 2020.getSpecialDay('Leap_Day');
prt 2021.getSpecialDay('Leap_Day');
 
%= 2020;
if(not %y.getSpecialDay('Leap_Day').isNull());
  //code to handle if %y is a leap year
end;

getMonth(d)

getMonth(d, lang)

Extracts the month number from a date. More specific than getSubPer(), and will fail if the date is not monthly or daily.

 

You may input a language ('en' = English, 'da' = Danish), in which case a string is returned.

 

Returns: value (integer) or string

%= 2020m2;
prt %d.getmonth();  //2
prt %d.getmonth('en');  //'February'
prt %d.getmonth('en').lower()[1..3]; //'feb'

getQuarter(d)

Extracts the quarter number from a date. More specific than getSubPer(), and will fail if the date is not quarterly.

Returns: value (integer)

%= 2020q2;
prt %d.getquarter();  //2

getSubPer(d)

Extracts the sub-period from a date (1 if annual or undated, the quarter if quarterly, the month if monthly or daily, and the week if weekly).

Returns: value (integer)

%= 2020q2;
prt %d.getsubper();  //2

getWeek(d)

Get the week number from a date of weekly frequency. Does not accept daily frequency as argument, but the conversion date('w') can be used as intermediary for this (see examples). Beware that the year may change when converting from daily to weekly frequency.

Returns: value (integer)

[New in 3.1.13]

%= 2020w20;
%d.getWeek(); //20
%d.getYear(); //2020
 
%= 2019m12d31;

%d.getWeek(); //error!
%d.date('w').getWeek(); //1
%d.date('w').getYear(); //2020!
 
%= 2021m1d1;
%d.date('w').getWeek(); //53
%d.date('w').getYear(); //2020!

getWeekday(d)

getWeekday(d, lang)

Extracts the weekday number from a date. Will fail if the date is not daily. The numbers are as follows:

Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7.

 

You may input a language ('en' = English, 'da' = Danish), in which case a string is returned.

 

Returns: value (integer) or string.

[New in 3.1.12]

%= 2020m3d25;
prt %d.getweekday();     //3
prt %d.getweekday('en'); //Wednesday
prt %d.getweekday('en').lower()[1..3]; //wed
prt %d.getweekday('da'); //Onsdag

getYear(d)

Extracts the year from a date.

Returns: value (integer)

%= 2020q2;
prt %d.getyear();  //2020

max(d1, d2, ... )

Finds the largest of any number of dates. (max() can also be used with value arguments).

Returns: date

[New in 3.1.6]

prt max(2002q1, 2001q4);

min(d1, d2, ... )

Finds the smallest of any number of dates. (min() can also be used with value arguments).

Returns: date

[New in 3.1.6]

prt min(2002q1, 2001q4);

observations(d1, d2)

Counts the number of observations (periods), with both start and end date included. The date difference using - is always the same as the number of observations minus 1.

prt observations(2020q2, 2023q3); //14
prt 2023q3 - 2020q2;              //13

toExcelDate(d)

Converts a daily date into an Excel date (counting the number of days since January 1, 1900). See also fromExcelDate(). Excel dates can be subtracted to obtain day spans. [New in 3.0.7]

 

Returns: value.

%v1 = toExcelDate(2019m11d12);
%v2 = toExcelDate(2019m12d3);
prt %v1, %v2; //43781 and 43802
prt %v2 - %v1; //21 days (span)
%= fromExcelDate(%v1 + 100);
prt %d; //100 days from 2019m11d12

truncate(d1, d2)

Finds overlap between two different time periods. The period d1 to d2 is compared with the global time period (if no local period is indicated), or with the local time period (if such a period is indicated in the <...> fields). Use a local time period if you need to find the overlap between two arbitrary time windows.

 

Returns: a list of two elements, start and end date of the resulting period. If the two elements are both null, there is no overlap.

 

[New in 3.1.6]

time 2010 2020;
#= truncate(2000, 2030);  //(2010, 2020)
#= truncate(2000, 2015);  //(2010, 2015)
#= truncate(2000, 2005);  //(null, null)
time 1980 1990;
#= truncate(<2010 2020>, 2000, 2030);  //(2010, 2020)
#= truncate(<2010 2020>, 2000, 2015);  //(2010, 2015)
#= truncate(<2010 2020>, 2000, 2005);  //(null, null)

//

// The overlapping period (z) can be visualized as

// the overlap of these time windows/periods:     

//                                                

// period1    . x x x x x . . .                   

// period2    . . . y y y y y .                   

// truncate() . . . z z z . . .                   

 

 

 

String combining functions

 

Function name

Description

Examples

[x]-index

Index: returns the character at position x.

Returns: string

%= 'abcd';
prt %s[2];  //'b'

[x1..x2]-index

Index: returns the range of characters from position x1 to x2 (both inclusive). You may omit x1 or x2.

Returns: string

%= 'abcd';
prt %s[2..3];  //'bc'

concat(s1, s2)

Appends the two strings: same as s1 + s2.

Returns: string

%= concat('He', 'llo'); Result: 'Hello'.

endswith(s1, s2)

 

Returns 1 if the string s1 starts with the string s2, else 0. The comparison is case-insensitive.

Returns: val

%= endswith('abcde', 'cde');
Returns: 1

includes(s1, s2)

Returns 1 if the string s2 is found inside (as a part of) string 1, else 0 is returned. The search is case-insensitive. Note that the contains() function is not useful regarding such in-string searches.

Returns: val

[New in 3.1.17].

%= 'abCd';
prt %s.includes('bc');  //1

index(s1, s2)

Searches for the first occurrence of string s2 in string s1 and returns the position. It returns 0 if the string is not found. The search is case-insensitive

Returns: val

%= index('onetwothreetwo', 'two'); 

Returns: 4. 
%= index('oneTWO', 'two'); 

Returns: 4.

isAlpha(s)

Returns 1 if all the characters are letters (alphabet). [New in 3.0.5].

%= isAlpha('aBc');
Returns: 1

isLower(s)

Returns 1 if the string contains no uppercase characters. [New in 3.0.5].

%= isLower('abc12');
Returns: 1

isNumeric(s)

Returns 1 if all the characters are of numeric value. [New in 3.0.5].

%= isNumeric('123');
Returns: 1

isUpper(s)

Returns 1 if the string contains no lowercase characters. [New in 3.0.5].

%= isUpper('ABC12');
Returns: 1

length(s)

 

 

The length of the string (number of characters). You may use len() instead of  length().

Returns: val

%= %s.length();

lower(s)

The string in lower-case letters.

Returns: string

%= lower('aBcD'); 

Result: 'abcd'.

nl()

A system newline/linebreak. Computerwise, nl() is equal to the C# string "\n", but beware that you cannot use the Gekko string '\n' instead of nl(), because the former is equal to the C# string "\\n".

Returns: string

%= 'a' + nl() + 'b'; //string with newline
tell %s;
#= %s.split(nl()); //list with 2 elements
#m;

prefix(s1, s2)

If s1 is a string, it has the string s2 prefixed (prepended).

Returns: string

%s1 = %s2.prefix('a');

replace(s1, s2, s3)

replace(s1, s2, s3, max)

In the string s1, the function replaces all occurrences of s2 with s3. Replacement is case-insensitive.

 

If max > 0, the replacement is performed at most max times.

 

Returns: string

%= replace(%s1, %s2); 

//or: replace(%s, %s1, %s2)

split(s1, s2)

split(s1, s2, removeempty)

split(s1, s2, removeempty, strip)

Splits the string s1 by means of the delimiter s2. Empty elements are removed per default, and the resulting strings are stripped (blanks are removed from the start and end of the strings). The last two options are 1 and 1, if omitted. [New in 3.0.6]

%= 'a, b,c,,d, , e';
#m1 = %s.split(','); 
//--> ('a', 'b', 'c', 'd', 'e')
#m2 = %s.split(',', 1, 1); 
//--> ('a', 'b', 'c', 'd', 'e');
#m3 = %s.split(',', 0, 1);'); 
//--> ('a', 'b', 'c', '', 'd', '', 'e')
#m4 = %s.split(',', 1, 0);'); 
//--> ('a', ' b', 'c',  'd', ' ', ' e')
#m5 = %s.split(',', 0, 0);'); 
//--> ('a', ' b', 'c', '', 'd', ' ', ' e')
 
%= 'a' + nl() + 'b'; //string with newline
#= %s.split(nl(), 0); //--> ('a', 'b')
//Note: the 0 argument keeps empty lines

startswith(s1, s2)

Returns 1 if the string s1 starts with the string s2, else 0. The comparison is case-insensitive.

Returns: val

%= 'abcde';
%= %s.startswith('abc');
Returns: 1

strip(s)

Removes blank characters from the start and end of the string.

Returns: string

%s1 = %s2.strip();  //or: strip(%s1)

stripstart(s)

Removes blank characters from the start of the string.

Returns: string

%s1 = %s2.striptart();  //or: stripstart(%s1, %s2)

stripend(s)

Removes blank characters from the end of the string.

Returns: string

%s1 = %s2.stripend();  //or: stripend(%s1, %s2)

substring(s, start, length)

The piece of the string between character number start and length (these must be integer values).

 

You can alternatively use a 'slice', using []-notation, see example.

 

Returns: string

%= %s1.substring(3, 2);  

//or: substring(%s1, 3, 2)
%= %s1[.. 5];  

//a slice from pos 3 to 5 (both inclusive)

suffix(s1, s2)

If s1 is a string, it has the string s2 suffixed (appended)

Returns: string

%s1 = %s2.suffix('a');

upper(s)

The string with upper-case letters.

Returns: string

%= upper('aBcD'); Result: 'ABCD'.

 

 

 

List functions:

 

Note that some of the functions assume that the lists are lists of strings. This will be fixed regarding values and dates.

 

Function name

Description

Examples

[x]-index

Index: picks out a single element. In contrast to R, this does not return a 1-element list containing the variable. If you need that, use for instance #m[3..3].

Returns: var

#m[3];  //the third element

[x1..x2]-index

Index: picks out a range of elements. You may omit x1 or x2.

Returns: list

#m[3..5];  //the third to fifth elements

[x1, x2]-index

For a nested list of lists, #m[3, 5] will return the same element as #m[3][5], so this is just convenience to make a nested list accessible like a matrix. See more here.

Returns: variable

 

[New in 3.0.6].

#= ((1, 2), (3, 4));
prt #m[2, 1], #m[2][1];  //same

[x1..y1, x2..y2]-index

[x1..y1, x2]-index

[x1, x2..y2]-index

For a nested list of lists, #m[2..3, 2..4] will select the given 'rows" and "columns", corresponding to selecting a submatrix from a matrix. Beware that in general, #m[2..3, 2..4] is completely different from #m[2..3][2..4].  See more here.

Returns: list

[New in 3.0.6].

//  1  2  3
//  4  5  6
//  7  8  9
// 10 11 12
#= ((1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12));
prt #m[2, 2..3];
prt #m[2][2..3]; //same as above
prt #m[2..4, 2]; //matrix-like selection
prt #m[2..4][2]; //different from above!
prt #m[2..4, 2..3]; //matrix-like selection
prt #m[2..4][2..3]; //different from above!

 

 

 

append(x1, x2)

append(x1, i, x2)

Adds variable x2 as it is at the end of list x1. Note that if x2 is a list of for instance 3 items, only 1 element is added (the list itself). If you need to add the 3 elements individually, use extend().

 

If used with i argument, x2 is inserted at index i, instead of at the end. See also extend().

 

To prepend, use append(x1, 1, x2).

 

Returns: list

#= #x1.append(#x2);  //or: append(#x1, #x2)
#= #x1.append(2, #x2);  //insert at position 2

contains(x1, x2)

Checks if the list of strings x1 contains the string x2. Returns 1 if true, 0 otherwise. You may alternatively use x2 in x1, see the last example. See also the count() and index() functions. The comparisons are case-insensitive.

Returns: val

%= #x1.contains(%s);
if(#x1.contains(%s) == 1); tell 'yes'; end;
if(%s in #x1); tell 'yes'; end;

count(x1, x2)

Counts the number of times the string x2 is present in the list of strings x1. See also the contains() and index() functions.

 

 

Note: to obtain the number of elements in a list, use the length() function. The comparisons are case-insensitive.

 

Returns: val

%= #x1.count(%s);  //or: count(#x1, %s)

data(x)

Accepts a string of blank-separated values x and turns them into a list of values. This is handy for long sequences of blank-separated numbers, instead of manually setting the commas.

Returns: list

#= data('1.0  2.0  1.5');

dates(x)

Tries to convert each element of the list x to a date.

Returns: list

#= dates(#x);

except(x1, x2)

 

clip0051

The except() function subtracts x2 from x1. You may alternatively use the operator -. Only works for lists of strings. See also intersect() and union().

 

Was called difference() in Gekko 2.0. See also extend().

 

Returns: list

#= #x1.except(#x2);  //or: except(#x1, #x2)
#= #x1 - #x2;        //same
 
#-= #x1;  //subtract from itself

extend(x1, x2)

extend(x1, i, x2)

The arguments x1 and x2 must be lists. The function inserts the elements of list x2 one by one at the end of (or at position i in) the list x1. The resulting list may contain dublets.

 

For two lists x1 and x2, you may alternatively use the + operator. See also except() and append().

 

To pre-extend, use extend(x1, 1, x2).

 

Returns: list

#= #x1.extend(#x2);  //or: extend(#x1, #x2)
#= #x1 + #x2; //same as above
#= #x1.extend(2, #x2);  //insert at position 2
 
#+= #x1; //add to itself

flatten(x)

For at list x, the function returns a flattened version of the list. For instance, the list (1, (2, 3)) is transformed into a non-recursive list of non-list elements: (1, 2, 3).

 

Returns: list

 

#m1 = (1, (2, 3));
#m2 = #m1.flatten(); //or: flatten(#m1).

index(x1, x2)

Returns the index of the first occurrence of the string x2 in the list of strings x1. Returns 0 if x2 is not found in x1. See also the count() and contains() functions. The comparisons are case-insensitive.

Returns: val

%= #x1.index(%s);  //or: index(#x1, %s)

intersect(x1, x2)

 

clip0050

The intersect() function finds the common elements of the two list of strings x1 and x2. The resulting list will not contain dublets. You may alternatively use the operator &&. Only works for lists of strings. See also except() and union().

Returns: list

#= #x1.intersect(#x2);  //or: intersect(#x1, #x2)
#= #x1 && #x2;

length(x)

Returns the number of elements in the list x. You may use len() instead of length().

Returns: val

%= #x.length();  //or: length(#x).
%= #x.len(); //the same

list(x1, x2, ...)

Returns a list of the variables x1, x2, etc. The function is handy for lists with only 0 or 1 elements. See examples.

Returns: list

#= ();      //will fail
#= list();  //ok: empty list

#= (1, 2);  //easy
#= (1);     //will fail
#= (1,);    //is ok
#= list(1); //is ok

lower(x)

Returns string elements in the list as lower-case.

Returns: list

#= #x1.lower();  //or: lower(#x1)

pop(x1, i)

pop(x1)

Removes the element at position i in the list x1. Removes the last element if called with pop(x).

Returns: list

#= #x1.pop(2);  //or: pop(#x1, 2)
#= #x1.pop();  //last element
#= #x1.pop(1);  //first element

preextend(x1, x2)

Same as extend(x1, 1, x2), putting the elements of x2 in the first position of x1.

#= #x1.preextend(#x2);  //insert at position 1

prefix(x1, x2)

If x1 is a list of strings, each element has the string x2 prefixed (prepended)

Returns: list

#= #x1.prefix(%s);  //or: prefix(#x1, %s);

prepend(x1, x2)

Same as append(x1, 1, x2), putting x2 in the first position of x1.

#= #x1.prepend(#x2);  //insert at position 1

sort(x)

sort(x, 'natural')

Returns a sorted list of strings, provided that x is a list of strings. Sorting is case-insensitive.

When the 'natural' argument is used, strings containing numbers will sort naturally, for instance returning a8, a9, a10, instead of a10, a8, a9.

Returns: list

Natural sort: [New in 3.1.10].

#= #x.sort();  //or: sort(#x)
#= #x.sort('natural');

remove(x1, x2)

Removes any string x2 from the list of strings x1. See also the except() function.

Returns: list

#= #x1.remove(%s);  //or: remove(#x1, %s);

#= #x1 - %s;        //also legal

replace(x1, x2, x3)

replaceinside(x1, x2, x3)

replaceinside(x1, x2, x3, max)

replace(): In the list of strings x1, if this string element is the same as x2, x3 is inserted instead.

 

replaceinside(): the string element has any occurences of x2 inside the string replaced with x3. The replacements may be limited via the max argument.

 

Returns: list

#= #x1.replace(%x2, %x3); //or: replace(#x1, %x2, %x3)
 
#= #x1.replaceinside(%x2, %x3); //or: replace(#x1, %x2, %x3, 'inside')

reverse(x)

To be done


split(x, s)

To be done


strings(x)

Tries to convert each element of the list x to a string

Returns: list

#= strings(#x);

suffix(x1, x2)

If x1 is a list of strings, each element has the string x2 suffixed (appended)

Returns: list

#= #x1.suffix(%s);  //or: suffix(#x1, %s);

t(x)

For a nested list of lists, the t() function returns the transpose, similar to transposing a matrix. [New in 3.0.6].

Returns: list (of lists)

#= ((1, 2), (3, 4));
#m, t(#m);

union(x1, x2)

 

clip0049

The union() function finds the union of the two lists. Alternatively use the operator ||. The resulting list will not introduce dublets, in contrast to the similar + operator (simple concatenation). Only works for lists of strings. See also except() and intersect().

Returns: list

#= #x1.union(#x2);  //or: union(#x1, #x2)
#= #x1 || #x2;

unique(x1)

Retains only those elements of list x1 that are unique (list of strings only).

Returns: list

#= #x1.unique();  //or: unique(#x1)

upper(x)

Returns string elements in the list as upper-case.

Returns: list

#= #x1.upper();  //or: upper(#x1)

vals(x)

Tries to convert each element of the list x to a value

Returns: list

#= vals(#x);

venn(x1, x2)

 

 

For two lists of strings, this function prints out lists corresponding to a Venn diagram.

 

clip0150

 

That is, intersection and two differences. For instance, venn(#m1, #m2) corresponds to printing out the following:

 

#m1 && #m2

#m1 - #m2

#m2 - #m1

 

See also intercept(), except() and union().

Returns: nothing.

#m1 = a, b, c, d, e;
#m2 = c, d, e, f, g;
venn(#m1, #m2);
 

//Results:

 
//The following 3 strings are in both lists:
//'c', 'd', 'e'
 
//The following 2 strings are in list #1, but not in list #2:
//'a', 'b'
 
//The following 2 strings are in list #2, but not in list #1:
//'f', 'g'

 

 

 

 

Bank/name/frequency/index manipulations

 

Function name

Description

Examples

addBank(x, bank)

If x does not have a bankname, a bankname is added. The input x may be string or list.

Returns: string or list

%name = addBank('x!q', 'b2');
Result: 'b2:x!q'

addFreq(x, freq)

If x does not have a freq, a freq is added. The input x may be string or list.

Returns: string or list

%name = addFreq('x', 'q');
Result: 'x!q'

getBank(x)

Returns the bank part of x. The input x may be series, string or list.

Returns: string or list

%bank = getBank('b2:x!q');
Result: 'b2'

getFreq(x)

Returns the freq part of x. The input x may be series, string or list.

Returns: string or list

%bank = getFreq('b2:x!q');
Result: 'q'

getFullName(bank, name, freq)

Returns the full name corresponding to the input, where bank, name and freq are strings.

Returns: string

%name = getFullName('b2', 'x', 'q');
Result: 'b2:x!q'

getFullName(bank, name, freq, index)

Returns the full name corresponding to the input, where bank, name and freq are strings, and index is a list (of strings)

Returns: string

%name = getFullName('b2', 'x', 'q', ('a', 'b'));
Result: 'b2:x!q[a,b]'

getIndex(x)

Returns the index part of x. The input x may be string or list.

Returns: list

#index = getIndex('b2:x!q[a, b]');
Result: ('a', 'b')
If the input is a list, the output will be a list of lists.

getName(x)

Returns the name part of x. The input x may be series, string or list.

Returns: string or list

%name = getName('b2:x!q');
Result: 'x'

getNameAndFreq(x)

Returns the name part of x. The input x may be series, string or list.

Returns: string or list

%name = getNameAndFreq('b2:x!q');
Result: 'x!q'

removeBank(x)

Removes any bank in x. The input x may be string or list.

Returns: string or list

%name = removeBank('b2:x!q');
Result: 'x!q'

removeBank(x, bank)

Removes any banks in x with the indicated bankname. The input x may be string or list.

Returns: string or list

%name = removeBank('b2:x!q', 'b2');
Result: 'x!q'
%name = removeBank('b3:x!q', 'b2');
Result: 'b2:x!q'

removeFreq(x)

Removes any freq in x. The input x may be string or list.

Returns: string or list

%name = removeFreq('b2:x!q');
Result: 'b2:x'

removeFreq(x, freq)

Removes any freq in x with the indicated freqname. The input x may be string or list.

Returns: string or list

%name = removeFreq('b2:x!q', 'q');
Result: 'b2:x'
%name = removeFreq('b3:x!q', 'm');
Result: 'b2:x!q'

removeIndex(x)

Removes any index in x. The input x may be string or list.

Returns: string or list

%name = removeIndex('b2:x!q[a, b]');
Result: 'b2:x!q'

replaceBank(x, b1, b2)

Replaces any banks in x having name b1 with name b2. The input x may be string or list.

Returns: string or list

%name = replaceBank('b2:x!q', 'b2', 'b3');
Result: 'b3:x!q'
%name = replaceBank('b2:x!q', 'b3', 'b4');
Result: 'b2:x!q'

replaceFreq(x, f1, f2)

Replaces any freq in x having freq b1 with freq b2. The input x may be string or list.

Returns: string or list

%name = replaceFreq('b2:x!q', 'q', 'm');
Result: 'b3:x!m'
%name = replaceFreq('b2:x!q', 'm', 'a');
Result: 'b3:x!q'

setBank(x, bank)

The indicated bankname is set, even if it exists already. The input x may be string or list.

Returns: string or list

%name = setBank('b3:x!q', 'b2');
Result: 'b2:x!q'

setFreq(x, freq)

The indicated freq is set, even if it exists already. The input x may be string or list.

Returns: string or list

%name = setFreq('b2:x!q', 'm');
Result: 'b2:x1!m'

setName(x, name)

The indicated name is set. The input x may be string or list.

Returns: string or list

%name = setName('b2:x!q', 'y');
Result: 'b2:y!m'

setNamePrefix(x, p)

The name of x has prefix p added.The input x may be string or list.

Returns: string or list

%name = setNamePrefix('b2:x!q', 'a');
Result: 'b2:ax!m'

setNameSuffix(x, s)

The name of x has suffix s added.The input x may be string or list.

Returns: string or list

%name = setNameSuffix('b2:x!q', 'b');
Result: 'b2:xb!m'

 

 

Timeseries functions

 

Function name

Description

Examples

allMiss(x)

On a timeseries x, the function returns 1 if all observations are missing values ("no data at all"), else it returns 0. See also isMiss(), and fromSeries('dataStart'), and fromSeries('dataStart').

 

[New in Gekko 3.1.20].

time 2021 2023;
x1 = m();
prt x1.allMiss();  //1
x1 <2022 2022> = 1;
prt x1.allMiss();  //0

arrayPack(name, lname)

This function finds all non-array ("normal") timeseries in the first-position databank and puts them into a single 1-dimensional array-series called name. In addition, a list lname is created, containing the names of the "packed" timeseries.

 

Note that after the function is called, the first-position databank only contains the array-series and the list. See also arrayUnpack().

 

[New in 3.1.16]

read adambank.gbk;
arraypack('adam', '#adamvars');
write <gdx> adambank.gdx;
//Creates the 1-dimensional array-series adam,
//with elements corresponding to the normal timeseries
//inside adambank.gbk. For instance, adambank.gbk may
//contain the series fY, which is mirrored in the element
//adam[fY]. Also, the list #adamvars will contain the
//element 'fY' (and more).

//When writing the gdx file, the adam variable will

//have domain names 'adamvars' and 't'.
//(You may use arraypack('adam', '*'), in which case
//the Gekko list is not created).

arrayUnpack(name)

This function takes the 1-dimensional array-series called name from the first-position databank and transforms ("unpacks") all the elements of the array-series into normal timeseries. The function deletes the array-series before it returns. See also arrayPack().

 

[New in 3.1.16]

read <gdx> adambk.gdx; //has adam variable inside
arrayunpack('adam');
//Now the first-position databank contains normal
//timeseries corresponding to the elements of the
//array-series adam.

bankFlatten(t)

bankFlatten(bank, t)

 

For the global (or locally given) period, all series and array-series are flattened. This means that over the global (or local) period, all values are set to their value in t. A bank name may be provided: if not, the first-position databank is used.

 

[New in 3.1.16]

time 1960 2022;
bankFlatten(2000);
//All series and array-series are set to
//their 2000 value, over the global period
//1960-2022.
bankFlatten(<1970 2010>, 2000);
//same, but now flattened over 1970-2010.
bankFlatten('Ref', 2000);
//for the Ref databank

bankReplace(x1, x2)

bankReplace(bank, x1, x2)

For the global (or locally given) period, in all series and array-series, the value x1 is replaced with x2. A bank name may be provided: if not, the first-position databank is used.

 

[New in 3.1.16]

time 1960 2022;
bankReplace(m(), 0);
//All series and array-series have missing value replaced with 0, over the global period 1960-2022.
bankReplace(<1970 2010>, m(), 0);
//same, but now over 1970-2010.
flatten('Ref', m(), 0);
//for the Ref databank

binary(x)

Converts a table-like nested list of strings into a corresponding array-series where the present elements (that is, the 'rows' of the nested list) are represented with value 1. The nested list must contain time info as the last element of each sublist. The function can be used to tranform a multidimensional GAMS set into a corresponding array-series. This can be convenient for printing, etc.

 

[New in 3.1.14]

time 2001 2002;
#= (('a', 'b', '2001'), ('a', 'c', '2002'));
x1 = #m.binary();
x2 = #m.binary().replace(m(), 0); //set missing to 0
prt #m; //try also prt <view> #m;
prt <n> x1;  //1 or missing
prt <n> x2;  //1 or 0
 
//         x1[a, b]    x1[a, c] 
// 2001      1.0000           M 
// 2002           M      1.0000 
//
//         x2[a, b]    x2[a, c] 
// 2001      1.0000      0.0000 
// 2002      0.0000      1.0000 

collapse(x)

collapse(x, method)

collapse(x, freq)

collapse(x, freq, method)

 

Function variant of the COLLAPSE statement, converting from higher to lower frequency. Note possible differences compared to COLLAPSE regarding the use of databanks and time periods.

 

You may input a frequency (freq), choose from 'a', 'q', 'm', 'w'. If frequency is not indicated, the function will per default collapse from d to m, w to m, m to q, or q to a.

 

The method argument can be 'total', 'avg', 'first', 'last', 'strict' or 'flex'. The last two of these indicate how missing values are handled. You may combine the first four and the last two of these with -, for instance 'avg-flex' to choose method 'avg' combined with missing handling 'flex'. Note that missing handling 'flex' is currently only available for collapse of daily (!d) series. Regarding these options, see the COLLAPSE statement.

 

You may use option collapse method = ... ; and option collapse missing d = ... ; to control default values for the method and missing handling. See OPTION.

 

Returns: series.

 

[New in 3.1.11]

time 2020 2020;
option freq q;
= 1, 3, 2, 6;
<n> x, x.collapse();
//same: x.collapse('total')
//same: x.collapse('a')
//same: x.collapse('a', 'total')
 
//Result:
//                   x   x.collapse() 
// 2020                               
// q1           1.0000                
// q2           3.0000                
// q3           2.0000                
// q4           6.0000                
// a                          12.0000 
 
//Nested collapse, d --> m --> q --> a
time 2020 2025;
option freq d;
x!= 1;
<n> x!d.collapse().collapse().collapse();
 
//          x!d.collap 
//       se().collapse 
//       ().collapse() 
// 2020       366.0000 
// 2021       365.0000 
// 2022       365.0000 
// 2023       365.0000 
// 2024       366.0000 
// 2025       365.0000 
 
//x!d.collapse('a') could be used instead

flatten(x, d)

Transforms 1 array-timeseries x into n normal timeseries with names reflecting the array-series dimensions and delimiter corresponding to the string argument d. For instance, an array-series npop defined over the two dimensions #sex and #age could contain the element (sub-series) npop[m, 40], which flatten() would turn into the normal series npop_m_40.

 

[New in 3.1.16]

npop = series(1);
npop[m, 40] = 60000;
npop[f, 40] = 62000;
npop[m, 41] = 59000;
npop[f, 41] = 61000;
npop.flatten('_');
delete npop;
<n dec=0 width=10> {'*'};
 
//Output:
//       npop_f_40   npop_f_41   npop_m_40   npop_m_41 
//2014       62000       61000       60000       59000 
//2015       62000       61000       60000       59000 
//...

getDomains(x)

Returns a list of strings containing the domains for each dimension of the array-series x. Returns an empty list if there are no domains given. See also getFixType(), setFixType(), setDomains().

Returns: list

#= getdomains(x); //or: #d = x.getdomains();

getElements(x)

Returns a nested list of strings, which for each dimension of the array-series shows which elements occur (in all sub-series). In the example on the right, the first dimension only contains a's, whereas the second dimension contains b and c. The returned list has as many elements as the dimensionality of the array-series. See also subseries().

 

[New in 3.1.10]

= series(2);
x[a, b] = 1;
x[a, c] = 2;
prt x.getelements();
// ('a',), ('b', 'c')

prt x.getelements()[2];

// 'b', 'c'

prt x.getelements()[2][1];

// 'b'

getFixType(x)

Returns the "fix" type of an array-timeseries x, where the return value can be 'variable' or 'parameter'. Array-series imported from GAMS gdx can be of variable or parameter type. See also setFixType(), getDomains(), setDomains().

Returns: string.

 

[New in 3.1.14]

//See example under setFixType()

hpfilter(x, lambda)

hpfilter(<t1 t2>, lambda)

hpfilter(x, lambda, log)

hpfilter(<t1 t2> x, lambda, log)

Returns a HP-filtered version of series x. Lambda is normally 6.25 for annual, 1600 for quarterly, and 129600 for monthly series. An additional argument 0 or 1 may be added (1 if log-transforms are to be used inside the calculation). Time period may be indicated with t1-t2.

Returns: series

= hpfilter(x, 6.25);
= hpfilter(x, 6.25, 1);  //log-transforms
= hpfilter(<1970 2015>, x, 6.25);
= x.hpfilter(<1970 2015>, 6.25); //alternative syntax

interpolate(x)

interpolate(x, method)

interpolate(x, freq)

interpolate(x, freq, method)

Function variant of the INTERPOLATE statement, converting from lower to higher frequency. Note possible differences compared to INTERPOLATE regarding the use of databanks and time periods.

 

Method must be 'total' or 'avg' (optionally combined with Olsette/Cholette/Denton, for instance 'total-olsette' or 'avg-cholette').

 

Destination freq must be 'q', 'm', 'w', or 'd'. Per default, interpolate() will transform from a to q, q to m, m to d and w to d.

 

Returns: series.

 

[New in 3.1.11]

time 2020 2021;
= 1, 3;
<n> x, x.interpolate();
 
//                                 x. 
//                   x  interpolate() 
// 2020                               
// q1                          1.0000 
// q2                          1.0000 
// q3                          1.0000 
// q4                          1.0000 
// a            1.0000                
//                                    
// 2021                               
// q1                          3.0000 
// q2                          3.0000 
// q3                          3.0000 
// q4                          3.0000 
// a            3.0000   

isArraySeries(x)

Returns 1 if the variable is an array-series, and 0 otherwise.

 

[New in 3.1.14]

= series(1);
x[a] = 100;
prt isArraySeries(x);

isTimelessSeries(x)

Returns 1 if the variable is a timeless series, and 0 otherwise.

 

[New in 3.1.14]

= timeless(100);
prt isTimelessSeries(x);

laspchain(plist, qlist, t)

laspchain(<t1 t2>, plist, qlist, t)

laspchain(<t1 t2>, plist, qlist, t, option)

 

laspchain(vals, valsLag, t)

laspchain(<t1 t2>, vals, valsLag, t)

Laspeyres chain index for quantities. Can be used with either (a) two lists of strings, or (b) two timeseries. In both cases the result is a map containing two consistent aggregated series p and q (price and quantity). The price is set = 1 in the t period. A period can be indicated in the <t1 t2> field. The function is robust regarding missing values at the start or end of the time period.

 

(a): Two lists of strings (names)

 

The names inside the two lists indicate the series that are to be aggregated.

 

See also the bottom of the LIST help page.

 

(b): Two series (accumulation)

 

A different way to use the function is to input one series (vals) with values in current prices, and one series (valsLag) with values in the previous period's prices. From this, Gekko will compute the aggregate price and quantity.

 

If you need to fill out holes (missings) between non-missings, for instance in prices series, you can use the smooth() function or SMOOTH statement.

 

Quarterly data

 

For quarterly data, using two lists of strings, option 'annualoverlap' must be indicated. When quarterly data are input, the so-called annual overlap method is used, where the algorithm starts out collapsing the quarterly data into annual data, then computes a "normal" annual chain index for the aggregate price, and lastly uses this annual price index to compute the quarterly indexes.

 

Returns: map

time 2017 2020;
p1 = 1.02, 1.03, 1.04, 1.05;
p2 = 1.12, 1.13, 1.14, 1.15;
q1 = 2, 3, 4, 5;
q2 = 12, 13, 14, 15;
#= p1, p2;
#= q1, q2;
//(a): With lists of strings
#= laspchain(#p, #q, 2020);
prt #a.p, #a.q;
= p1*q1 + p2*q2;
vlag = p1[-1]*q1 + p2[-1]*q2;
//(b): With series (accumulation)
#= laspchain(v, vlag, 2020);
prt #b.p, #b.q;
 
//With explicit time indication:
//laspchain(<2017 2020>, #p, #q, 2020);
//laspchain(<2017 2020>, v, vlag, 2020);

laspfixed(plist, qlist, t)

laspfixed(<t1 t2>, plist, qlist, t)

laspfixed(<t1 t2>, plist, qlist, t, option)

Laspeyres fixed-price index. As laspchain(), but with fixed prices. Cannot be used with series input.

 

Returns: map

//See example regarding laspchain()

percentile(x, %v)

Computes the %v percentile for the series x, for the global time period. Any missing values within that sample are ignored. Setting %v = 0.5 results in the median.

Returns: val

%= percentile(y, 0.25);
%= percentile(y, 0.50);

rebase(x, t)

rebase(x, t, index)

Function variant of the REBASE statement. Note possible differences compared to REBASE regarding the use of databanks and time periods.

 

You cannot use start/end dates with this function, only a single date (alternatively, use REBASE statement).

 

Returns: series.

 

[New in 3.1.11]

time 2020 2022;
= 10, 11, 12;
prt <n> x, x.rebase(2021), x.rebase(2021, 1);
//                                  x           x.re 
//                   x  .rebase(2021)  base(2021, 1) 
// 2020        10.0000        90.9091         0.9091 
// 2021        11.0000       100.0000         1.0000 
// 2022        12.0000       109.0909         1.0909 

rename(x, cfg)

For an array-series x: renames and reorders dimension elements, according to a cfg nested list.

 

[New in 3.1.16]

TODO

reorder(x, ord)

For array-series x, this function reorders the dimensions according to the list ord. The list must contain the integers 1..n, where n is the dimensionality of the array-series.

 

Note: for an array-series dimension of size n, if reorder() is fed with the list (1, 2, 3, ... , n), the function returns an identical array-series.

 

[New in 3.1.16]

= series(3);
x[a, c, e] = 1; x[a, c, f] = 2;
x[b, d, e] = 3; x[b, d, f] = 4;
= x.reorder((2, 3, 1));
prt y;
//Will print subseries y[c, e, a], y[c, f, a], 
//y[d, e, b] and y[d, f, b]. The first dimension of x

//has been moved to the last dimension of y, and

//the other two dimensions are moved forwards.

replace(x, v1, v2)

For the series or array-series x, the function replaces the value v1 with the value v2, over the given sample.

 

See also iif(), isMiss(), and the $-conditional.

 

Returns: series

 

time 2001 2003;
= (1, m(), 3);  //m() is missing value
//result is (1, 0, 3):
= x.replace(m(), 0);  //or: replace(x, m(), 0)
//the replacement is done for the sample:
<2000 2004> = x.replace(m(), 0);
//result is (0, 1, 0, 3, 0)

rotate(x, d)

Transforms the array-series x to a new array-series, where the time dimension and dimension number d swap places.

For instance, the array-series pop may contain sub-series for each age group 0 to 100, that is, pop['0'], pop['1'], ... , pop[100']. These 101 sub-series are all defined over a time period, say 2020-2050. Then profile = rotate(pop, 1) will be a new array-series containing sub-series for each time period 2020 to 2050, that is, profile['2020'], profile['2021'], ... , profile['2050']. These 31 sub-series are all defined over an undated time period 0 to 100, corresponding to the age dimension. Hence, plot <0u 100u> profile['2020']; will plot the age profile of the population in the year 2020.

See example under PLOT (age profiles section).

Returns: series

//pop is a 1-dimensional array-series 
//with ages 0-100 in its dimension.
//note: 'u' indicates undated frequency
 
profile!= rotate(pop, 1);
#= ('2020', '2030', '2040', '2050');
plot <0u 100u> profile!u[#t];
 
 
 

series(freq, n)

Constructs a series or array-series of the given frequency and with the given dimensions (n). You can skip some of these options, see examples.

 

See also isArraySeries().

 

Returns: series

 

= series('q', 3);  //quarterly array-series, 3-dim
= series('q');  //quarterly normal series
= series(3);  //3-dim array-series with current frequency
= series();  //normal series with current frequency
 
= series(1);
y['a'] = 100;  //or: y[a] = ...
 

setDomains(x, d)

Sets a list of strings (d) containing the domains for each dimension. You may use '*' to indicate a domain-free dimension (in GAMS called the universal set), but otherwise each element should start with symbol # (to indicate that it is a list). See also getFixType(), setFixType(), getDomains().

Returns: nothing

#= ('#b', '#x');
setdomains(x, #d);  //or: x.setdomains(#d);

setFixType(x, type)

Sets the "fix" type of an array-timeseries x, where type can be 'variable' or 'parameter'. When exporting an array-series to a GAMS gdx file, this difference is of significance. See also getFixType(), getDomains(), setDomains().

 

[New in 3.1.14]

= series(1);
x[a] = 100;
p x.getFixType();
//returns: 'variable', which is default
write <gdx> data1; //variable in GAMS
x.setFixType('parameter');
p x.getFixType();
write <gdx> data2; //parameter in GAMS

smooth(x)

smooth(x, method)

smooth(x, y)

smooth(x, method, y)

Function variant of the SMOOTH statement to fill holes (missing values). Note possible differences compared to SMOOTH regarding the use of databanks and time periods.

 

Method must be 'linear', 'geometric', 'repeat', 'spline', or 'overlay'. If method is not stated, 'linear' is default. The y variable can be a series, value or 1x1 matrix (it is only used for 'overlay' smoothing).

 

Returns: series.

 

[New in 3.1.13]

= x.smooth('linear');     //user linear smoothing
= x.smooth();             //short for the above
= x.smooth('overlay', y); //use y series to fill holes
= x.smooth(y);            //short for the above
= x.smooth(0);            //use 0 value as overlay

splice(x1, x2, ...)

splice(x1, t1, x2, ...)

splice(x1, t1, t2, x2, ...)

splice(type, x1, ...)

Function variant of the SPLICE statement to splice two or more overlapping timeseries into one resulting timeseries. Note possible differences compared to SPLICE regarding the use of databanks and time periods.

 

Type can be 'rel1', 'rel2', 'rel3', 'abs' for the method, or 'first', 'last', '1', '2', '3', etc. for indicating the "primary" series number (such numbers must be strings). You may combine the method and "primary" indication with -, for instance 'rel3-first' or 'abs-2'. Default is 'rel1-last'. See many more details under SPLICE.

 

Returns: series.

 

[New in 3.1.15]

time 2001 2005;
x1 <2001 2003> = 1, 2, 3;
x2 <2003 2005> = 11, 12, 13;
= splice(x1, x2);
prt y, x1, x2;

 

//Regarding the left-hand side series,

//note that splice() never inserts
//values outside of the given 
//local or global time period.

//So this time period is respected,

//in contrast to the SPLICE statement.

 

subseries(x, option)

Helper function for array-series.

 

option = 'elements': nested list of strings with element combinations for each sub-series.

option = 'names': list of sub-series names (as strings). You may remove the frequency part of these names with removefreq(), see example.

option = 'length': the number of sub-series inside the array-series.

option = 'dimensions': the number of dimensions of the array-series.

 

See also getelements().

 

[New in 3.1.10]

 

= series(2);
x[a, b] = 1;
x[a, c] = 2;
prt x.subseries('elements');
// ('a', 'b'), ('a', 'c')
prt x.subseries('names');
// 'x!a[a, b]', 'x!a[a, c]'
prt x.subseries('names').removefreq();
// 'x[a, b]', 'x[a, c]'
prt x.subseries('length');
// 2

prt x.subseries('dimensions');
// 2

timeless(freq, v)

Constructs a timeless series of the given frequency, to value v. You can skip some of these options, see examples.

 

In many cases, you can just use a value scalar with the same functionality. But timeless series can be practical, for instance they can be used as array-series.

 

See also isTimelessSeries().

 

Returns: series

 

= timeless('q', 3);  //quarterly timeless series, with value = 3.
= timeless('q');  //quarterly timeless series, no value set.
= timeless(3);  //timeless series with current frequency, with value = 3.
= timeless();  //timeless series with current frequency, no value set.
 
= series(1);
y['a'] = timeless(100);  //or: y[a] = ...

 

 

Time, databank and other environment info

 

Function name

Description

Examples

bankfilename(s)

bankfilename(s, p)

OBSOLETE: use fromBank(%s, 'filename') or fromBank(%s, 'fullpath').

 

bankname(s)

Returns the name of the bank. Input can be the string 'first' or 'ref', or a val designating the number in the databank list.

Returns: string

%b1 = bankname('first');
%b0 = bankname('ref');
%b2 = bankname(2);

currentDateTime()

Returns current date and time.

Returns: string

%= currentDateTime(); 
//Returns: '15-09-2014 12:34:58' (for instance).
tell currentDateTime();

currentDate()

currentDate2()

Returns current date, either as a string, or as a date with daily frequency. [New in 3.1.1]

currentDate() returns: string

currentDate2() returns: daily date. You may convert to other frequencies with the date() function, cf. examples.

%= currentDate(); 
//Returns: '15-09-2014' (for instance).
%= currentDate2();           //daily 
%= currentDate2().date('m'); //monthly
%= currentDate2().date('a'); //annual

currentDay()

Returns the current day (between 1 and 31). [New in 3.0.5].

Returns: val

%= currentDay();

currentFolder()

Returns the current working folder (cf. option folder working = ...). [New in 3.0.6].

Returns: string.

%= currentFolder();

currentFreq()

Returns the current frequency, for instance a, q, m, d or u.

Returns: string

%= currentFreq(); 
//Returns: 'a' (depending upon frequency setting, cf. option freq).

currentHour()

Returns the current hour. [New in 3.0.5].

Returns: val

%= currentHour();

currentMinute()

Returns the current minute. [New in 3.0.5].

Returns: val

%= currentMinute();

currentMonth()

Returns the current month. [New in 3.0.5].

Returns: val

%= currentMonth();

currentPerStart()

Returns the start of the global time period.

Returns: date

%= currentPerStart(); 
//Returns: 2012q1 (for instance).

currentPerEnd()

Returns the end of the global time period.

Returns: date

%= currentPerStart(); 
//Returns: 2015q4 (for instance).

currentSecond()

Returns the current second. [New in 3.0.5].

Returns: val

%= currentSecond();

currentTime()

Returns current time.

Returns: string

%= currentTime(); 
//Returns: '12:34:58' (for instance).

currentYear()

Returns the current year. [New in 3.0.5].

Returns: val

%v = currentYear(); 

exist(s)

Returns 1 if the variable corresponding to the string s exists, else 0. The input must be of string type. For timeseries, you do not have to add frequency to the name (for instance !q), if the series is of current frequency. The function respects the option databank search setting (that is, in sim-mode it will only look in the first-position databank, if a databank name is not provided).

 

The exist() function can also check if an array-subseries exists, cf. example.

 

Returns: val

= 1;
prt exist('x');
prt exist('work:x');
 
= series(2);
y[a, a] = 1; y[a, b] = 2; y[b, b] = 4;
prt exist('y[a, a]'); prt exist('y[b, a]');
#= y.getelements()[1];
#= y.getelements()[2];
for string %= #i;
  for string %= #j;
    if(exist('y[{%i},{%j}]'));
      y[%i,%j] *= 100;
    end;
  end;
end;
prt y;

filteredperiods(d1, d2)

Returns the number of filtered periods between d1 and d2 (these are dates).

Returns: val

%v = filteredperiods(%d1, %d2);

fromDatabank(x, type)

Accesses meta-information from the databank x (string). Type (string) can be:

 

'filename' (only file, returns string)

'fullpath' (file and path, returns string)

'label' (cf. HDG, returns string)

'stamp' (last time written, returns string)

'stamp2' (last time written, returns daily date)

'format' ("1.0"/"1.1" or "1.2", returns string)

'count' (number of variables, returns val)

 

[New in 3.1.15].

TODO: EXAMPLES

fromSeries(x, type)

Accesses meta-information from the timeseries x. Type can be

 

'name' (returns string)

'bank' (returns string)

'freq' (returns string)

'label' (returns string)

'source' (returns string)

'units' (returns string)

'stamp' (returns string)

'stamp2' (returns date)

'dataStart' or 'dataEnd' (returns date: period with actual data). See also isMiss() and allMiss().

'dataStartTruncate' or 'dataEndTruncate' (returns date: period with actual data, truncated with global or local time period). May return null/empty. [New in 3.1.6]

 

The x argument can be either a series name or string.

%= ref:gdp.fromSeries('label'); 
//Returns 'Gross domestic product' (for instance).
%= gdp.fromSeries('dataStart'); 
//Returns 1980q1 (for instance). Same logic regarding 'dataEnd' argument.
%= gdp.fromSeries('freq'); 
//Returns 'q' (for instance).
 
time 2011 2015;
= 1, 2, 3, 4, 5;
time 2013 2017;
prt x.fromSeries('dataStartTruncate'); //2013
time 2011 2015;
prt x.fromSeries(<2013 2017>, 'dataStartTruncate'); //2013

 

gekkoBitness()

Returns bitness of Gekko (either "32" or "64").

Returns: string. [New in 3.1.11]

tell 'Gekko {gekkoVersion()} ({gekkoBitness()}-bit)';
//Gekko 3.0.1 (64-bit) --> for instance

gekkoInfo(x)

Returns a string with info on Gekko. Choose between:

 

'short1' = Gekko-version

'short2' = Gekko-version + bitness

'short3' = Gekko-version + bitness + period

'short4' = Gekko-version + bitness + working folder

'short5' = Gekko-version + bitness + period + working folder

 

Returns: string. [New in 3.1.11]

tell gekkoInfo('short1');
//Gekko 3.0.1

 

gekkoVersion()

Returns the Gekko version number ('xx.yy.zz'). See also gekkoVersionDate().

Returns: string

tell 'Gekko ' + gekkoVersion();
//Gekko 3.1.16    (for instance)

gekkoVersionDate()

Returns the daily date corresponding to the gekko.exe file of the currently executing Gekko. Beware the file systems, version control systems, etc. may tamper with file dates (like the date of gekko.exe). See also gekkoVersion().

Returns: daily date

tell 'Gekko ' + gekkoVersion() + ' ' gekkoVersionDate();
//Gekko 3.1.16 2024m3d11    (for instance)

getEndoExo()

Returns a list with names of those variables that start with 'endo_' or 'exo_'. This is used with GAMS models, when fixing equations.

Returns: list of strings.

#= getEndoExo();

isLibraryLoaded(x)

Returns 1 if the library with the name x (a string) is loaded, and 0 otherwise.

Returns: val

%= islibraryloaded('lib1');

isOpen(x)

Returns 1 if the databank with the name x (a string) is open, and 0 otherwise.

Returns: val

 

%= isopen('mybank');

root()

root('root')

root('gekko')

Returns the name of the root folder as a string (without any closing backslash). The root folder is defined as a folder that contains a file with the name root.ini or gekko.ini (root() or root('root') will look for root.ini, whereas root('gekko') will look for gekko.ini).

 

To find the root directory, Gekko first looks for a root.ini/gekko.ini file in the working folder. If not found, it looks in the parent folder of the working folder, and so on upwards. If no root.ini/gekko.ini file is found, or if more than one is found, Gekko aborts with an error. NOTE: the root.ini/gekko.ini file must also be consistent with the folder where the running gcm file is residing, else an error is issued (change the working folder if this is an issue). This is to avoid confusion.

 

Using this root function makes it easier to refer to files inside a larger folder structure, without hard-coding the name of the root folder. This also makes it easier to copy or move a folder structure. See also rootify(). [New in 3.1.13].

open g:\update\data\scenario5\bank; //hard-coded root
open {root()}\data\scenario5\bank;  //using root()

// In the latter OPEN, it is presupposed that the 

// folder g:\update contains a file with the

// name root.ini. The contents of this file has

// no significance, but could contain a remark that

// the file should not be deleted or moved.

// If the system of folders inside g:\update is

// later on moved to a new location, for instance

// to g:\update2, the latter OPEN statement still works

// in the new location.

// You could alternatively use relative paths to 

// the same effect, but then you would have to use

// paths like open ..\..\..\data\scenario5\bank;.

 

//To use a gekko.ini file instead of

//root.ini as root, use:

open {root('gekko')}\data\scenario5\bank;

 

//The contents of a root.ini file could be for instance:

//  Do not delete or move. Used by the Gekko root() 

//  function to provide an "anchor" for relative paths.

 

tell root(); //to see what the current root is

rootify(folder, rootpath)

This function can be used to replace path names with {root()} in a sysem of .gcm files. This can be useful if you are using a system with a lot of hardcoded paths that you want to make easier to copy or move. The folder argument designates the folder (including subfolders) for which rootify() is done. The rootpath argument is the path you want to have replaced with {root()}.

 

For textfiles other than .gcm Gekko will also look at these and report if any contain the rootpath. Gekko will not alter file dates in rootify().

 

See also root().

 

[New in 3.1.19].

//Example: consider a gcm file residing in the folder 

//g:\common\data:
 
  read g:\common\data\b1.gbk;
  x1 = x1 + 1;
  write g:\common\data\b2.gbk;
  tell 'created g:\common\data\b2.gbk';
 
//After rotify('g:\common\data', 'g:\common\data') 

//the file looks like this:
 
  read {root()}\b1.gbk;
  x1 = x1 + 1;
  write {root()}\b2.gbk;
  tell 'created {root()}\b2.gbk';
 
//For this to work, you need to place a 
//g:\common\data\root.ini (with arbitrary contents) 

time()

time(<t1 t2>)

Returns the current time period as a series where the dates are represented as values. Works with quarters and months, too. The function may for instance be practical for creating trend variables.

 

If you need a quarterly or monthly time() to average-collapse into an annual time(), you should use time()-0.5.

 

Returns: series

option freq q;
time 2010q1 2011q4;
p time();
p time(<2010q3 2011q3>);  //truncated
//the first one prints 2010.125, 2010.375, 2010.625, 2010.875, ...

 

 

 

 

Matrix functions:

 

Function name

Description

Examples

avgc(x)

Average over cols.

Returns: matrix

#m2 = avgc(#m1);

avgr(x)

Average over rows

Returns: matrix

#m2 = avgr(#m1);

chol(x)

chol(x, type)

Cholesky decomposition of matrix x. Accepts type (string), either 'upper' or 'lower'.

Returns: matrix

#m2 = chol(#m1, 'upper');

cols(x)

Returns the number of colums of x

Returns: val

%= cols(#m);

design(x)

Returns a "design" matrix, equivalent to the same Gauss function. The function is practical for aggregating rows or columns.

 

Input: is a n x 1 column matrix

Returns: n x k matrix of 0's and 1's. The input numbers specify the columns in which the 1's should be placed.

 

In the example, a 4 x 5 matrix #x of 1's is defined, and by means of the aggregation matrix #m, it is aggregated from size 4 x 5 to 4 x 3. In this case, the new column 1 is the old columns 2 and 3, the new column 2 is the old column 5, and the new column 3 is the old columns 1 and 4.

#= [3; 1; 1; 3; 2];
#= design(#a);
#= ones(4, 5);
#m, #* #d;
 
#m
                   1              2              3 
    1         0.0000         0.0000         1.0000 
    2         1.0000         0.0000         0.0000 
    3         1.0000         0.0000         0.0000 
    4         0.0000         0.0000         1.0000 
    5         0.0000         1.0000         0.0000 
 
#* #d
                   1              2              3 
    1         2.0000         1.0000         2.0000 
    2         2.0000         1.0000         2.0000 
    3         2.0000         1.0000         2.0000 
    4         2.0000         1.0000         2.0000 

det(x)

Determinant of a matrix.

Returns: val

%= det(#m);

diag(x)

Diagonal. If x is a n x n symmetric matrix, the method returns the diagonal as a n x 1 matrix. If x is a n x 1 column vector, the method returns a n x n matrix with this column vector on the diagonal (and zeroes elsewhere).

Returns: matrix

#m2 = diag(#m1);

divide(x1, x2)

Element by element division of the two matrices. If x2 is a row vector, each x1 column will be divided with the corresponding value from the row vector.  And if x2 is a column vector, each x1 row will be divided with the corresponding value from the column vector.

Returns: matrix

#= divide(#x1, #x2);

i(n)

Returns a n x n identity matrix.

Returns: matrix

#= i(10);

inv(x)

Inverse of matrix x

Returns: matrix

#m2 = inv(#m1);

maxc(x)

Max over cols

Returns: matrix

#m2 = maxc(#m1);

maxr(x)

Max over rows

Returns: matrix

#m2 = maxr(#m1);

minc(x)

Min over cols

Returns: matrix

#m2 = minc(#m1);

minr(x)

Min over rows

Returns: matrix

#m2 = minr(#m1);

m(r, c) or miss(r, c)

Returns a n x k matrix filled with missing values. Cf. also m() function for values.

Returns: matrix

#= m(5, 10);

multiply(x1, x2)

Element by element multiplication of the two matrices. If x2 is a row vector, each x1 column will be multiplied with the corresponding value from the row vector.  And if x2 is a column vector, each x1 row will be multiplied with the corresponding value from the column vector.

Returns: matrix

#= multiply(#x1, #x2);

ones(n, k)

Returns a n x k matrix filled with 1's

Returns: matrix

#= ones(5, 10);

pack(v1, v2, ...)

pack(<t1 t2>, v1, v2, ...)

Using period t1-t2, the timeseries v1, v2, ... are packed into a n x k matrix, where n is the number of observations and k is the number of variables. If the period is omitted, the global time period is used.

Returns: matrix

#= pack(<2020 2030>, x, y, z); Returns: a 11 x 3 matrix #m with the values.

rows(x)

Returns the number of rows of x.

Returns: val

%= rows(#m);

sumc(x)

Sum over cols

Returns: matrix

#m2 = sumc(#m1);

sumr(x)

Sum over rows

Returns: matrix

#m2 = sumr(#m1);

t(x)

Returns the transpose of a matrix.

Returns: matrix

#m2 = t(#m1);

trace(x)

Returns the trace of a matrix.

Returns: val

%= trace(#m);

unpack(m)

unpack(<t1 t2>, m)

The column matrix m (with only one column) is unpacked into a timeseries spanning the period t1-t2. If the period is omitted, the local/global time period is used.

The unpack() function is not strictly necessary: you may alternatively assign a nx1 matrix directly to a series (see example).

Returns: series

//This picks out the second column of #m (and all the rows).

= #m[.., 2].unpack(<2020 2030>);  
<2020 2030> = #m[.., 2].unpack();  //same
<2020 2030> = #m[.., 2]; //also works

zeros(n, k)

Returns a n x k matrix filled with 0's. Zeroes() can be used as alias.

Returns: matrix

#= zeros(5, 10);

 

 

Modelling

 

Function name

Description

Examples

modelRawEqs()

Returns a list of strings corresponding to the equation names used by the loaded raw GAMS model. Note: the so-called GAMS scalar model is not used in this function.

 

Returns: list of strings. [New in Gekko 3.1.16]

model <gms> mymodel.zip;
sim <res>; //residuals
#eqs = modelRawEqs();
for string %= #eqs;
  p <n nomax> {%s};
end;
//prt {#eqs} may print too wide

modelRawVars()

Returns a list of strings corresponding to the variable names used by the loaded raw GAMS model. Note: the so-called GAMS scalar model is not used in this function.

 

Returns: list of strings. [New in Gekko 3.1.16]

#vars = modelRawVars();
for string %= #vars;
  p <n nomax> {%s};
end;
//prt {#vars} may print too wide

 

 

Data trace handling:

 

Function name

Description

Examples

traceDelete2()

traceDelete2(x)

Deletes all trace references in the first-position databank (or use x for an optional databank name). After this, a traceStats2() will show 0 traces.

 

[New in Gekko 3.1.16]

tracedelete2();
tracedelete2('Work');

traceStats2()

traceStats2(x)

For now, only a simple overview of the number of traces can be shown (x is an optional databank name). Depth = 0 means traces that are directly assigned to existing timeseries, whereas depth = n > 0 indicate traces that are not assigned to existing timeseries, but are instead assigned to other traces with depth = n-1. Traces with depth > 0 can be thought of as remnants of timeseries that do not (or do no longer) exist in the particular databank.

 

[New in Gekko 3.1.16]

tracestats2();
tracestats2('Work');

 

Miscellaneous functions:

 

Function name

Description

Examples

compareFolders(f1, f2)

compareFolders(f1, f2, filter)

compareFolders(f1, f2, filter, options)

The function compares two folders f1 and f2 (including subfolders), a bit like COMPARE for files.

 

With default settings, two files with the same name, in the same subfolder, with same size, and with same date (within 2 seconds) are considered equal. If dates differ, the files are compared by contents: byte for byte for binary files, and line for line for text files (differing whitespace at the start or end of a single text line will not count as a difference). The function outputs three files: comparefolders.txt with file info, comparefolders1.zip with differing common text files for easy comparison, and comparefolders2.zip with Gekko code to update folder1 or folder2.

 

You may use a wildcard filter like for instance '*.gcm, !*_bak.gcm', which means all .gcm files except those ending with _bak (use prefix ! for patterns to omit). The last argument can be 'text' if you only want to compare text files (Gekko 'tastes' the files to see if they are binary or text), and/or 'strict' to always compare files by content.

 

Note that in comparefolders1.zip, folder delimiters are represented as --, and extension dot is represented as ,. Sort the files by name when opening the .zip. You may drag and drop a folder from a file manager like Total Commander into the Gekko input window, to paste the folder path as a string. Total Commander is also convenient for comparing the files in comparefolders1.zip.

 

[New in Gekko 3.1.16].

comparefolders('c:\update\newdata', 'c:\update\olddata');

comparefolders('c:\update\newdata', 'c:\update\olddata', '*.gcm, !*_bak.gcm');

comparefolders('c:\update\newdata', 'c:\update\olddata', '', 'text strict');

existFile(x)

Returns value 1 if the file exists, 0 otherwise. If the file is stated without path, Gekko will also look in loaded libraries for it. See also readFile() and writeFile().

 

[New in Gekko 3.1.9]

if(existfile('c:\data\scenario5.gbk'));
  //do something;
end;

flush()

Removes all cache files (can also be done from the Gekko menu File --> Delete cache files...). This forces Gekko to re-read datafiles and models rather than using cached versions. At start up, Gekko performs flushing automatically every 14 days, or when the cache files take up more than 50 GB of file space.

 

The function is intended for occasional manual use, and Gekko will refuse using it from a Gekko program. Using it too often will just slow down reading datafiles and models.

 

[New in Gekko 3.1.14]

flush();

gamsscalar(x)

This function can be called with gamsscalar('pack'), which creates a zip file with the GAMS scalar model, suitable for a MODEL statement. The function uses a settings file gamsscalar.json. The scalar model can be used for DECOMP and SIM<res>. More info on this soon.

gamsscalar('pack');

isNull(x)

Returns value 1 if x is a null variable, 0 otherwise. See also null().

[New in Gekko 3.1.13]

#= ((1, 2, 3), (4, null(), 6));
if(isNull(#m[2, 2]));
  //do something if cell [2, 2] is null
end;

isUtf8File(x)

Check if the text file x (string path) seems to be in UTF-8 format or not (if not, the format may be ANSI). If the file is stated without path, Gekko will also look in loaded libraries for it. See also existFile(), readFile() and writeFile().

Returns: value 0 or 1.

[New in Gekko 3.1.16]

%= isUtf8File('rawdata.txt');
 
//The checking is done by 'tasting' the file.
//See also 'option system read encoding = ...' and 

//'option system write encoding = ...'

lhsRhs(file)

lhsRhs(file, version)

Experimental function that analyzes a Gekko gcm file syntactically and returns lists of timeseries names that appear on left-hand or right-hand sides of assignments ("series statements"). Input is filename (string) and version (value) -- value must be 2 (Gekko 2) or 3 (Gekko 3), default is 3.

[New in Gekko 3.1.19]

lhsRhs('data.gcm');
lhsRhs('data.gcm', 2);

m() or miss()

Returns a missing value. Useful in some series or matrix  expressions. Cf. also the m(r, c) function for matrices.

Returns: value

<2020 2020> = m();
#= [1, 2; m(), 4];

map()

Returns an empty map.

#= map();

null()

Returns a null variable. At the moment, null variables are mostly used to indicate empty "cells" in lists. You cannot perform calculations on null variables, but you can use the type() function to see the type of a given variable/cell (see example). See also isNull(). [New in 3.0.6].

Returns: null variable

#= ((1, 2, 3), (4, null(), 6));
prt #m;
prt #m[2, 2].type(); //'null'

readFile(x)

Reads the file x (string) into a string. If the file is stated without path, Gekko will also look in loaded libraries for it. See also existFile(), writeFile() and readScreen().

Returns: string

%= readFile('rawdata.txt');

 

//See also 'option system encoding ...'

readScreen()

Reads the Gekko output screen (the upper part) into a string. See also readFile(). You may use the split() and nl() functions to split the string into lines.

Returns: string

#= readscreen().split(nl(), 0);
//This list contains the lines
//shown on the screen. The 0 argument

//makes sure empty lines are retained.

tic()

Starts a timer, see toc(). Used to time Gekko programs.

tic();

toc()

Returns the number of seconds elapsed since a timer was started with tic(). Used to time Gekko programs.

tic();
PRT toc();
//Prints seconds elapsed since tic().

type(x)

Returns the type of a given variable x. The type is 'val', 'date', 'string', 'series', 'list', 'map', 'matrix' or 'null'. See examples. At the moment, null variables are mostly used to indicate empty "cells" in lists. [New in 3.0.6].

Returns: string

#= (1, 2021, 2021a, 'cat', null());
#m;
#m[1].type(); //'val'
#m[2].type(); //'val'
#m[3].type(); //'date'
#m[4].type(); //'string'
#m[5].type(); //'null'

writeFile(x, s)

Writes the string s to the file x (string). A newline can be indicated with '\n'.

See also existFile() and readFile().

writeFile('rawdata.txt', '170 121 387');

 

//See also 'option system encoding ...'

yesno(x)

Converts value 1 or 0 into string 'yes' or 'no'. Quite a lot of options accept yes/no, but not 1/0.

[New in Gekko 3.1.9]

tell existfile('c:\data\scenario5.gbk').yesno();