Data Manipulations with Parameters

# Introduction

Data once initialized may require manipulation in order to bring it to the form required in the model. The first part of this chapter will deal explicitly with parameter manipulation. The rest of the chapter will be devoted to explaining the ramifications: indexed assignment functions, index operations.

# The Assignment Statement

The assignment statement is the fundamental data manipulation statement in GAMS. It may be used to define or alter values associated with any sets, parameters, variables or equations.

A simple assignment is written in the style associated with many other computer languages. GAMS uses the traditional symbols for addition (+), subtraction (-), multiplication (*) and division (/). We will use them in the examples that follow, and give more details in Section Expressions .

## Scalar Assignments

Consider the following artificial sequence:

scalar x  / 1.5/ ;
x = 1.2;
x = x + 2;


The scalar x is initialized to be 1.5. The second statement changes the value to 1.2, and the third changes it to 3.2. The second and third statement assignments have the effect of replacing the previous value of x, if any, with a new one.

Note that the same symbol can be used on the left and right of the = sign. The new value is not available until the calculation is complete, and the operation gives the expected result.

Attention
An assignment cannot start with a reserved word. A semicolon is therefore required as a delimiter before all assignments.

## Indexed Assignments

The syntax in GAMS for performing indexed assignments is extremely powerful. This operation offers what may be thought of as simultaneous or parallel assignment and it provides a concise way of specifying large amounts of data. Consider the mathematical statement, $$DJ_d = 2.75 DA_d$$ for all $$d$$.

This means that for every member of the set $$d$$, a value is assigned to $$DJ$$. This can be written in GAMS as follows,

dj(d) = 2.75*da(d) ;


This assignment is known technically as an indexed assignment and set d will be referred to as the controlling index or controlling set.

Attention
The index sets on the left hand side of the assignment are together called the controlling domain of the assignment

The extension to two or more controlling indices should be obvious. There will be an assignment made for each label combination that can be constructed using the indices inside the parenthesis. Consider the following example of an assignment to all 100 data elements of a.

Set   row        / r-1*r-10 /
col        / c-1*c-10 /
sro(row)   / r-7*r-10 / ;
parameters  a(row,col),
a(row,col)  =  13.2 + r(row)*c(col)  ;


The calculation in the last statement is carried out for each of the 100 unique two-label combinations that can be formed from the elements of row and col. The first of these is, explicitly,

a('r-1','c-1') = 13.2 + r('r-1')*c('c-1').


## Sparse Assignments

A sparse assignment will assign a value to the left hand side(LHS) of the = sign only if the right hand side (RHS) is nonzero. Consider the following example:

*define end-of-line comment symbol: $eolcom !!$eolcom !!
Set       i                                /a,b,c/
Parameter d1(i) Data d1                    /a 1, b 1, c 1/
d2(i) Data used to overwrite d1  /a 2, b 0 /
p1(i) p1(i)=d2(i)         Full replacement
p2(i) p2(i)$(d2(i))=d2(i) Sparse replacement p3(i) p3(i)$=d2(i)        Shorthand for sparse replacement;
p1(i)=d1(i);             !! result: p1('a')=1  p1('b')=1  p1('c')=1
p2(i)=d1(i);             !! result: p2('a')=1  p2('b')=1  p2('c')=1
p3(i)=d1(i);             !! result: p3('a')=1  p3('b')=1  p3('c')=1
p1(i)=d2(i);             !! result: p1('a')=2
p2(i)$(d2(i))=d2(i); !! result: p2('a')=2 p2('b')=1 p2('c')=1 p3(i)$=d2(i);            !! result: p3('a')=2  p3('b')=1  p3('c')=1
Display d1,d2,p1,p2,p3;


In the sparse assignments, the parameters p2(i) and p3(i) are replaced with values from parameter d2(i) only if the entry in d2(i) is nonzero. Hence, the nonzero entry d2('a') replaces entry p2('a') and p3('a').

## Using Labels Explicitly in Assignments

It is often necessary to use labels explicitly in assignments. This can be done as discussed earlier with parameters - by using quotes around the label. Consider the following assignment,

a('r-7','c-4') = -2.36 ;


This statement assigns a constant value to one element of a. All other elements of a remain unchanged. Either single or double quotes can be used around the labels.

## Assignments Over Subsets

In general, wherever a set name can occur in an indexed assignment, a subset (or even alabel) can be used instead if you need to make the assignment over a subset instead of the whole domain.

Consider the following example,

a(sro,'col-10')  =  2.44 -33*r(sro) ;


where sro has already been established to be a proper subset of row.

## Issues with Controlling Indices

Attention
The number of controlling indices on the left of the = sign should be at least as many as the number of indices on the right. There should be no index on the right hand side of the assignment that is not present on the left unless it is operated on by an indexed operator

Consider the following statement,

a(row,'col-2')  = 22 - c(col) ;


GAMS will flag this statement as an error since col is an index on the right hand side of the equation but not on the left.

There would be no error here if col would be a singleton set. Since there is not more than one element in a singleton set it is not required that this index gets controlled by an controlling index on the left or an indexed operator.

Attention
Each set is counted only once to determine the number of controlling indices. If the same set appears more than once within the controlling domain, the second and higher occurrences of the set should be aliases of the original set in order for the number of controlling indices to be equal to the number of indices.

Consider the following statement as an illustration,

b(row,row)  =  7.7 - r(row) ;


This statement has only one controlling index (row). If one steps through the elements of row one at a time assignments will be made only to the diagonal entries in b. This will assign exactly 10 values! None of the off-diagonal elements of b will be filled.

If an additional name is provided for row and used in the second index position, then there will be two controlling indices and GAMS will make assignments over the full Cartesian product, all 100 values. Consider the following example,

alias(row,rowp)  ;
b(row,rowp)  = 7.7 - r(row) + r(rowp) ;


## Extended Range Identifiers in Assignments

The GAMS extended range identifiers can also be used in assignment statements, as in

a(row,'col-10')  =  inf ;  a(row,'col-1')  =  -inf ;


Extended range arithmetic will be discussed later in this Section. The values most often used are NA in incomplete tables, and INF for variable bounds.

## Acronyms in Assignments

Acronyms can also be used in assignment statements, as in

acronym monday, tuesday, wednesday, thursday, friday ;
parameter dayofweek ;
dayofweek = wednesday ;

Attention
Acronyms contain no numeric value, and are treated as character strings only.

# Expressions

An expression is an arbitrarily complicated specification for a calculation, with parentheses nested as needed for clarity and intent. In this section, the discussion of parameter assignments will continue by showing in more detail the expressions that can be used on the right of the = sign. All numerical facilities available in both standard and extended arithmetic will be covered.

## Standard Arithmetic Operations

The standard arithmetic symbols and operations are

**     exponentiation

*,/    multiplication and division

+,-    addition and subtraction (unary and binary)

They are listed above in precedence order, which determines the order of evaluation in an expression without parentheses.

Consider, for example:

x = 5 + 4*3**2 :


For clarity, this could have been written:

x = 5 + (4*(3**2)) ;


In both cases the result is 41.

Attention
• It is better to use parentheses than to rely on the precedence of operators, since it prevents errors and clarifies intentions.
• Expressions may be freely continued over many lines: an end-of-line is permissible at any point where a blank may be used. Blanks may be used for readability around identifiers, parentheses and operator symbols. Blanks are not allowed within identifiers or numbers, and are significant inside the quote marks used to delimit labels.
• x**n is equivalent to the function call rPower(x,y) and is calculated inside GAMS as exp[n*log(x)]. This operation is not defined if x has a negative value, and an error will result. If the possibility of negative values for x is to be admitted and the exponent is known to be an integer, then a function call, power(x,n), is available.

Three additional capabilities are available to add power and flexibility of expression calculations. They are indexed operations, functions and extended range arithmetic.

## Indexed Operations

In addition to the simple operations explained before, GAMS also provides the following four indexed operations.

sum    Summation over controlling index

prod    Product over controlling index

smin    Minimum value over controlling index

smax    Maximum value over controlling index

These four operations are performed over one or more controlling indices. The syntax in GAMS for these operations is,

indexed_op( (controlling_indices), expression)


If there is only one controlling index, the parentheses around it can be removed. The most common of these is sum, which is used to calculate totals over the domain of a set. Consider the following simple example adapted from [ANDEAN] for illustration.

sets i   plants  / cartagena, callao, moron /
m   product / nitr-acid, sulf-acid, amm-sulf /;

parameter capacity(i,m) capacity in tons per day
totcap(m)     total capacity by process ;

totcap(m) = sum(i, capacity(i,m));


This would be written, using normal mathematical representation, as $$totC_m = \sum_i C_{im}$$.

The index over which the summation is done, i, is separated from the reserved word sum by a left parenthesis and from the data term capacity(i,m) by a comma. i is again called the controlling index for this operation. The scope of the control is the pair of parentheses () that starts immediately after the sum. It is not likely to be useful to have two independent index operations controlled by the same index.

It is also possible to sum simultaneously over the domain of two or more sets, in which case more parentheses are needed. Also, of course, an arithmetic expression may be used instead of an identifier;

count = sum((i,j), a(i,j)) ;
emp = sum(t, l(t)*m(t)) ;


The equivalent mathematical forms are:

$count = \sum_i\sum_j A_{ij} \quad and\quad emp = \sum_t L_t M_t$

The smin and smax operations are used to find the largest and smallest values over the domain of the index set or sets. The index for the smin and smax operators is specified in the same manner as in the index for the sum operator. Consider the following example to find the largest capacity,

lrgunit = smax((i,m),capacity(i,m));


## Functions

Functions play an important part in the GAMS language, especially for non-linear models. Similar to other programming languages, GAMS provides a number of built-in (intrinsic) functions. However, GAMS is used in an extremely diverse set of application areas and this creates frequent requests for the addition of new and often sophisticated and specialized functions. There is a trade-off between satisfying these requests and avoiding complexity not needed by most users. The GAMS Function Library Facility (Section Functions) provides the means for managing that trade-off.

### Intrinsic Functions

GAMS provides commonly used standard functions such as exponentiation, and logarithmic, and trigonometric functions. The complete list of available functions is given in the following sections: Mathematical functions, Logical functions, Time and Calendar functions, and GAMS utility and performance functions. There are cautions to be taken when functions appear in equations; these are dealt with in Section Expressions in Equation Definitions, Chapter Equations.

In the following sections, the Endogenous Classification (third column) specifies in which models the function can legally appear. In order of least to most restrictive, the choices are DNLP, NLP, any, none (see Section Classification of Models for details). Functions classified as any are only permitted with exogenous (constant) arguments.

The following conventions are used for the function arguments. Lower case indicates that an endogenous variable is allowed. Upper case indicates that a constant argument is required. The arguments in square brackets can be omitted and default values will be used. Those default values are specified in the function description provided in the second column.

Mathematical functions

Function Description End. Classif.
abs(x) returns the absolute value of an expression or term x DNLP
arccos(x) returns the inverse cosine of the argument x where x is a real number between -1 and 1 and the output is in radians, see MathWorld NLP
arcsin(x) returns the inverse sine of the argument x where x is a real number between -1 and 1 and the output is in radians, see MathWorld NLP
arctan(x) returns the inverse tangent of the argument x where x is a real number and the output is in radians, see MathWorld NLP
arctan2(y,x) four-quadrant arctan function yielding arctangent(y/x) which is the angle the vector (x,y) makes with (1,0) in radians NLP
Beta(x,y) beta function: $$B(x,y) = \frac{\gamma(x)\gamma(y)}{\gamma(x+y)}$$, see MathWorld DNLP
betaReg(x,y,z) regularized beta function, see MathWorld NLP
binomial(n,k) returns the (generalized) binomial coefficient for $$n,k\geq 0$$NLP
ceil(x) returns the smallest integer number greater than or equal to x DNLP
centropy(x,y[,Z]) Centropy: $$x \cdot \ln(\frac{x+Z}{y+Z})$$, default setting: $$Z=0$$NLP
cos(x) returns the cosine of the argument x where x must be in radians, see MathWorld NLP
cosh(x) returns the hyperbolic cosine of x where x must be in radians, see MathWorld NLP
cvPower(X,y) returns $$X^{y}$$ for $$X\geq0$$ NLP
div(dividend,divisor) returns $$\frac{dividend}{divisor}$$, undefined for $$divisor=0$$NLP
div0(dividend,divisor) returns $$\frac{dividend}{divisor}$$, returns $$10^{299}$$ for $$divisor=0$$ NLP
eDist(x1[,x2,x3,...])  Euclidean or L-2 Norm: $$\sqrt{ x_{1}^{2} + x_{2}^{2} + ... }$$, default setting: $$x_{2},x_{3},...=0$$NLP
entropy(x) Entropy: $$-x\cdot\ln(x)$$ NLP
errorf(x) calculates the integral of the standard normal distribution from negative infinity to x, $$errorf(x) = \frac{1}{\sqrt{2\pi}} \int\limits_{-\infty}^x e^{\frac{-t^{2}}{2}}dt$$NLP
execSeed reads or writes the seed for the random number generator none
exp(x) returns the exponential function $$e^{x}$$ of an expression or term x, see MathWorld NLP
fact(N) returns the factorial of N where N is an integer any
floor(x) returns the greatest integer number less than or equal to xDNLP
frac(x) returns the fractional part of x DNLP
gamma(x) gamma function: $$\gamma(x)= \int\limits_{0}^{\infty} t^{x-1}e^{-t}dt$$, see MathWorld DNLP
gammaReg(x,a) regularized gamma function, see MathWorld NLP
log(x) returns the natural logarithm, logarithm base e, see MathWorld NLP
logBeta(x,y) log beta function: $$\log(B(x,y))$$ NLP
logGamma(x) log gamma function as discussed in MathWorld NLP
log10(x) returns the common logarithm, logarithm base 10, see MathWorld NLP
log2(x) returns the binary logarithm, logarithm base 2, see MathWorld NLP
mapVal(x) Function that returns an integer value associated with a numerical result that can contain special values. Possible values are:
0 for all regular numbers
4 for UNDF which means undefined
5 for NA which means not available
6 for INF which means plus infinity
7 for -INF which means minus infinity
8 for EPS which means very close to zero but different from zero
any
max(x1,x2,x3,...) returns the maximum of a set of expressions or terms, the number of arguments is not limitedDNLP
min(x1,x2,x3,...) returns the minimum of a set of expressions or terms, the number of arguments is not limitedDNLP
mod(x,y) returns the remainder of x divided by y DNLP
ncpCM(x,y,Z) function that computes a Chen-Mangasarian smoothing equaling: $$x-Z\cdot \ln(1+e^{\frac{x-y}{Z}})$$ NLP
ncpF(x,y[,Z]) function that computes a Fisher smoothing equaling: $$\sqrt{(x^{2}+y^{2}+2\cdot Z)}-x-y$$, $$Z\geq0$$, default setting: Z=0 NLP
ncpVUpow(r,s[,MU]) NCP Veelken-Ulbrich: smoothed min
ncpVUpow = $$\left\{ \begin{array}{ll}\frac{(r + s - |t|)}{2} & if |t| \geq \mu\\ \frac{(r + s - \frac{\mu}{8} \cdot (- (\frac{t}{\mu})^{4}+6(\frac{t}{\mu})^{2} +3))}{2} & otherwise \end{array} \right.$$
where $$t=r-s$$, default setting: $$MU=0$$
NLP
ncpVUsin(r,s[,MU]) NCP Veelken-Ulbrich: smoothed min
ncpVUsin = $$\left\{ \begin{array}{ll} \frac{(r + s - |t|)}{2} & if |t| \geq \mu\\\frac{(r + s - (\frac{2\mu}{\pi} \sin(\frac{\pi\cdot}{2\mu} +\frac{3\pi}{2})+\mu))}{2} & otherwise \end{array} \right.$$
where $$t=r-s$$,default setting: $$MU=0$$
NLP
normal(MEAN,STDDEV) generates a random number with normal distribution with mean MEAN and standard deviation STDDEV, see MathWorld none
pi value of $$\pi=3.141593...$$ any
poly(x,A0,A1,A2[,A3,...]) computes a polynomial over scalar x where result $$= A_{0}+A_{1}x+A_{2}x^{2}+A_{3}x^{3}+...$$ - this has a maximum of 20 arguments, default setting: $$A_{3},...=0$$NLP
power(x,Y) returns $$x^Y$$ where Y must be an integer NLP
randBinomial(N,P) generates a random number with binomial distribution where n is the number of trials and p the probability of success for each trial, see MathWorld none
randLinear(LOW,SLOPE,HIGH) generates a random number between LOW and HIGH with linear distribution, SLOPE must be greater than $$\frac{2}{\mbox{HIGH}-\mbox{LOW}}$$ none
randTriangle(LOW,MID,HIGH) generates a random number between LOW and HIGH with triangular distribution, MID is the most probable number, see MathWorld none
round(x[,DECPL]) rounding x, DECPL declares the number of decimal places, default setting: $$\mbox{DECPL}=0$$ DNLP
rPower(x,y) returns $$x^{y}$$ for $$x > 0$$, however, if $$x = 0$$ then other restrictions for $$y$$ apply. This function is equal to the arithmetic operation 'x**y' which is explained at Standard Arithmetic Operations NLP
sigmoid(x) Sigmoid calculation: $$\frac{1}{1+e^{-x}}$$, see MathWorld NLP
sign(x) sign of x, returns 1 if $$x > 0$$, -1 if $$x < 0$$, and 0 if $$x = 0$$ DNLP
signPower(x,Y) signed power where Y must be greater than 0, returns $$x^{Y}$$ if $$x\geq 0$$ and $$-1\cdot |x|^{Y}$$ if $$x<0$$ NLP
sin(x) returns the sine of the argument x where x must be in radians, see MathWorld NLP
sinh(x) returns the hyperbolic sine of x where x must be in radians, see MathWorld NLP
slexp(x[,SP]) smooth (linear) exponential function, SP means smoothing parameter, default setting: $$SP=150$$ NLP
sllog10(x[,SP]) smooth (linear) logarithm base 10, SP means smoothing parameter, default setting: $$SP=10^{-150}$$ NLP
slrec(x[,SP]) smooth (linear) reciprocal, SP means smoothing parameter, default setting: $$SP=10^{-10}$$NLP
sqexp(x[,SP]) smooth (quadratic) exponential funtion, SP means smoothing parameter, default setting: $$SP=150$$ NLP
sqlog10(x[,SP]) smooth (quadratic) logarithm base 10, SP means smoothing parameter, default setting: $$SP=10^{-150}$$ NLP
sqr(x) returns the square of an expression or term x NLP
sqrec(x[,SP]) smooth (quadratic) reciprocal, SP means smoothing parameter, default setting: $$SP=10^{-10}$$ NLP
sqrt(x) returns the squareroot of x, see MathWorld NLP
tan(x) returns the tangent of the argument x where x must be in radians, see MathWorld NLP
tanh(x) returns the hyperbolic tangent of x where x must be in radians, see MathWorld NLP
trunc(x) truncation, removes decimals from x DNLP
uniform(LOW,HIGH) generates a random number between LOW and HIGH with uniform distribution, see MathWorld none
uniformInt(LOW,HIGH) generates an integer random number between LOW and HIGH with uniform distribution, see MathWorld none
vcPower(x,Y) returns $$x^{Y}$$ for $$x\geq0$$.NLP

Logical functions

Function Description End. Classif.
bool_and(x,y) boolean and: returns 0 if $$x=0 \quad \vee \quad y=0$$, else returns 1, another possible command is 'x and y' DNLP
bool_eqv(x,y) boolean equivalence: returns 0 if exactly one argument is 0, else returns 1, another possible command is 'x eqv y' DNLP
bool_imp(x,y) boolean implication: returns 1 if $$x=0 \vee y \neq 0$$, else returns 0, another possible command is 'x imp y' DNLP
bool_not(x) boolean not: returns 1 if $$x=0$$, else returns 0, another possible command is 'not x' DNLP
bool_or(x,y) boolean or: returns 0 if $$x=y=0$$, else returns 1, another possible command is 'x or y' DNLP
bool_xor(x,y) boolean xor: returns 1 if exactly one argument is 0, else returns 0, another possible command is 'x xor y' DNLP
ifThen(cond,iftrue,else) first argument contains a condition (e.g. $$x>y$$). If the condition is true, the function returns iftrue else it returns else. DNLP
rel_eq(x,y) relation 'equal': returns 1 if $$x=y$$, else returns 0, another possible command is 'x eq y' DNLP
rel_ge(x,y) relation 'greater equal': returns 1 if $$x\geq y$$, else returns 0, another possible command is 'x ge y' DNLP
rel_gt(x,y) relation 'greater than': returns 1 if $$x>y$$, else returns 0, another possible command is 'x gt y' DNLP
rel_le(x,y) relation 'less equal': returns 1 if $$x\leq y$$, else returns 0, another possible command is 'x le y' DNLP
rel_lt(x,y) relation 'less than': returns 1 if $$x<y$$, else returns 0, another possible command is 'x lt y' DNLP
rel_ne(x,y) relation 'not equal': returns 1 if $$x\neq y$$, else returns 0, another possible command is 'x ne y' DNLP

Time and Calendar functions

Function Description End. Classif.
gday(SDAY) returns Gregorian day from a serial day number date.time, where Jan 1, 1900 is day 1 any
gdow(SDAY) returns Gregorian day of week from a serial day number date.time, where Jan 1, 1900 is day 1 any
ghour(SDAY) returns Gregorian hour of day from a serial day number date.time, where Jan 1, 1900 is day 1 any
gleap(SDAY) returns 1 if the year that corresponds to a serial day number date.time, where Jan 1, 1900 is day 1, is a leap year, else returns 0 any
gmillisec(SDAY) returns Gregorian milli second from a serial day number date.time, where Jan 1, 1900 is day 1 any
gminute(SDAY) returns Gregorian minute of hour from a serial day number date.time, where Jan 1, 1900 is day 1 any
gmonth(SDAY) returns Gregorian month from a serial day number date.time, where Jan 1, 1900 is day 1 any
gsecond(SDAY) returns Gregorian second of minute from a serial day number date.time, where Jan 1, 1900 is day 1 any
gyear(SDAY) returns Gregorian year from a serial day number date.time, where Jan 1, 1900 is day 1 any
jdate(YEAR,MONTH,DAY) returns a serial day number, starting with Jan 1, 1900 as day 1 any
jnow returns the current time as a serial day number, starting with Jan 1, 1900 as day 1 none
jstart returns the time of the start of the GAMS job as a serial day number, starting with Jan 1, 1900 as day 1 none
jtime(HOUR,MIN,SEC) returns fraction of a day that corresponds to hour, minute and second any

GAMS utility and performance functions

Function Description End. Classif.
errorLevel error code of the most recently used command none
execError number of execution errors, may either be read or assigned to none
gamsRelease returns the version number of the current GAMS release, for example 23.8 none
gamsVersion returns the current gams version, for example 238 none
handleCollect(HANDLE) tests if the solve of the problem identified by the calling argument HANDLE is done and if so loads the solution into GAMS. In particular it returns:
0: if the model associated with HANDLE had not yet finished solution or could not be loaded
1: if the solution has been loaded
none
handleDelete(HANDLE) deletes the grid computing problem identified by the HANDLE calling argument and returns a numerical indicator of the status of the deletion as follows:
0: if the the model instance has been removed
1: if the argument HANDLE is not a legal handle
2: if the model instance is not known to the system
3: if the deletion of the model instance encountered errors
A nonzero return indicates a failure in the deletion and causes an execution error.
none
handleStatus(HANDLE) tests if the solve of the problem identified by the calling argument HANDLE is done and if so loads the solution into a GDX file. A numerical indication of the result is returned as follows:
0: if a model associated with HANDLE is not known to the system
1: the model associaed with HANDLE exists but the solution process is incomplete
2: the solution process has terminated and the solution is ready for retrieval
3: the solution process signaled completion but the solution cannot be retrieved
An execution error is triggered if GAMS cannot retrieve the status of the handle.
none
handleSubmit(HANDLE) resubmits a previously created instance of the model identified by the HANDLE for solution. A numerical indication of the result is returned as follows:
0: the model instance has been resubmitted for solution
1: if the argument HANDLE is not a legal handle
2: if a model associated with the HANDLE is not known to the system
3: the completion signal could not be removed
4: the resubmit procedure could not be found
5: the resubmit process could not be started
In case of a nonzero return an execution error is triggered.
none
heapFree allocated memory which is no more in use but not freed yet none
heapLimit interrogates the current heap limit (maximum allowable memory use) in Mb and allows it to be reset none
heapSize returns the current heap size in Mb none
jobHandle returns the Process ID (PID) of the last job started none
jobKill(PID) sends a kill signal to the running job with Process ID PID, the return value is one if this was successful, otherwise it is zero none
jobStatus(PID) checks for the status of the job with the Process ID PID, possible return values are:
0: error (input is not a valid PID or access is denied)
1: process is still running
2: process is finished with return code which could be accessed by errorlevel
3: process not running anymore or was never running, no return code available
none
jobTerminate(PID) sends an interrupt signal to the running job with Process ID PID, the return value is one if this was succesful, otherwise it is zero none
licenseLevel returns an indicator of type of license:
0: demo license, limited to small models
2: run time license, no new variables or equations can be introduced besides those inherited in a work file
3: application license, only works with a specific work file which is locked to the license file
any
licenseStatus returns a non zero when a license error is incurred any
maxExecError maximum number of execution errors, may either be read or assigned to none
numCores returns the number of logical cores in the system any
sleep(SEC) execution pauses for SEC seconds none
timeClose returns the model closing time none
timeComp returns the compilation time in seconds none
timeElapsed returns the elapsed time in seconds since the start of a GAMS run none
timeExec returns the execution time in seconds none
timeStart returns the model start time since last restart none

Consider the following example of a function used as an expression in an assignment statement,

x(j) = log(y(j))  ;


which replaces the current value of x with the natural logarithm of y over the domain of the index set j.

### Extrinsic Functions

Using the GAMS Function Library Facility, functions can be imported from an external library into a GAMS model. Apart from the import syntax, the imported functions can be used in the same way as intrinsic functions. In particular, they can be used in equation definitions. Some function libraries are included with the standard GAMS software distribution (see Chapter Extrinsic Functions) but GAMS users can also create their own libraries using an open programming interface. The GAMS Test Library instances trilib01, trilib02, trilib03, and cpplib00 are simple examples in the programming languages C, Delphi, Fortran, and C++ that come with every GAMS system.

### Using Function Libraries

Function libraries are made available to a model using a compiler directive:

$FuncLibIn <InternalLibName> <ExternalLibName>  Note that the Function Library Facility gives you complete control over naming so that potential name conflicts between libraries can be avoided. The <InternalLibName> is a sort of handle and will be used to refer to the library inside your model source code. The <ExternalLibName> is the file name for the shared library that implements the extrinsic functions. To access libraries included with your GAMS distribution you use the library's name with no path prefix. GAMS will look for the library in a standard place within the GAMS installation. To access a library that does not reside in this standard place, the external name should include a relative or absolute path to the library's location. GAMS will search for the shared library you specify using the mechanisms specific to the host operating system. When processing the $FuncLibIn directive, GAMS will validate the library, make the included functions available for use, and add a table of the included functions to the listing file.

Before using individual functions you must declare them:

Function <InternalFuncName> /<InternalLibName>.<FuncName>/;


Note that the syntax is similar to that used for declaring Sets, Parameters, Variables and so forth and that the control over potential naming conflicts extends to the names of the individual functions. The <InternalFuncName> is the one that you will use in the rest of your model code. The <InternalLibName> is the one that you created with the $FuncLibIn directive and <FuncName> is the name given the function when the library was created. Once functions have been declared with the Function statement they may be used exactly like intrinsic functions in the remainder of your model code. ### Example Here is an example that adds some concrete detail. $eolcom //

$FuncLibIn trilib testlib_ml%system.dirsep%tridclib // Make the library available. // trilib is the internal name being created now. // tridclib is the external name. // With no path, GAMS will look for tridclib in // the GAMS system directory. * Declare each of the functions that will be used. * myCos, mySin and MyPi are names being declared now for use in this model. * Cosine, Sine and Pi are the function names from the library. * Note the use of the internal library name. Function myCos /trilib.Cosine/ mySin /trilib.Sine/ myPi /trilib.Pi/; scalar i, grad, rad, intrinsic; for (i=1 to 360, intrinsic = cos(i/180*pi); grad = mycos(i,1); abort$round(abs(intrinsic-grad),4) 'cos', i, intrinsic, grad;

variable x;
equation e;

e.. sqr(mysin(x)) + sqr(mycos(x)) =e= 1;
model m /e/;
x.lo = 0; x.l=3*mypi;
solve m min x using nlp;


The following lines from the listing file describe the library loaded.

FUNCLIBIN  trilib tridclib
Function Library trilib
Mod. Function                          Description
Type
any  Pi                                Pi


A description of the libraries included in the GAMS system can be found in Chapter Extrinsic Functions.

### Stateful Libraries

While GAMS intrinsic function are stateless, a user can implement stateful extrinsic functions, meaning that the extrinsic libraries can have some memory. This can be done in two ways:

The latter type of memory is problematic, since different parts of the GAMS system potentially use different instances of the function library. For example, if one sets SetMode(1) before the solve statement and one uses GAMS option solvelink<>5 (see SolveLink), the solver runs in a separate process with a new instance of the function library and therefore uses the default mode, which is 0. Even worse, if solvelink=0 is set, the GAMS process terminates in order to execute the solve statement and restarts a new GAMSprocess after the solve which again starts up with a fresh function library instance, so the function library's memory is lost also in this case. The GAMS Test Library model trilib04 demonstrates this problem.

## Extended Range Arithmetic and Error Handling

GAMS uses an extended range arithmetic to handle missing data, the results of undefined operations, and the representation of bounds that solver systems regard as infinite. The special symbols are listed in table Table 1 , with the brief explanation of the meaning of each.

Table 1: Special symbols for extended arithmetic

Special symbol Description mapval
inf Plus infinity. A very large positive number 6
-inf Minus infinity. A very large negative number 7
na Not available. Used for missing data. Any Operation that uses the value NA will produce the result NA 5
undf Undefined. The result of an undefined or illegal operation. A user cannot directly set a value to UNDF 4
eps Very close to zero, but different from zero. 8

GAMS has defined the results of all arithmetic operations and all function values using these special values.

The results can be inspected by running the model library problem [CRAZY]. As one would expect, 1+INF evaluates to INF, and 1-EPS to 1.

Attention
The mapval function should be used in comparisons involving extended range arithmetic. Only the extended range arithmetic shown in the table above give non-zero values for mapval. For example, mapval(a) takes a value of 6 if a is inf. All regular numbers result in a mapval of 0.

The following table shows a selection of results for exponentiation and division for a variety of input parameters.

Table 2: Exponentiation and Division

a b a**b power(a,b) a/b
2 2 4 4 1
-2 2 undf 4 -1
2 2.1 4.28 undf .952
na 2.5 na na na
3 0 1 1 undf
inf 2 inf inf inf
2 inf undf undf 0
Attention
One should avoid creating or using numbers with absolute values larger than 1.0E20. If a number is too large, it may be treated by GAMS as undefined (UNDF), and all values derived from it in a model may be unusable. Always use INF (or -INF) explicitly for arbitrarily large numbers

When an attempted arithmetic operation is illegal or has undefined results because of the value of arguments (division by zero is the normal example), an error is reported and the result is set to undefined (UNDF).

From there on, UNDF is treated as a proper data value and does not trigger additional error messages.

Attention
GAMS will not solve a model if an error has been detected, but will terminate with an error condition.

It is thus always necessary to anticipate conditions that will cause errors, such as divide by zero. This is most easily done with the dollar control, and will be discussed in the next section.

# Summary

GAMS provides powerful facilities for data manipulation with parallel assignment statements, built-in functions and extended range arithmetic.