Table of Contents
Introduction
In this chapter we will describe the programming flow control features available in GAMS. The if statement facilitates expressing complex conditional statements (see also chapter Conditional Expressions, Assignments and Equations). In addition, GAMS offers four loop constructs to handle looping requirements: the loop statement, the while statement, the for statement and the repeat statement. At the end of this chapter we will introduce the break, and continue statements, which give additional control over the execution of loop structures, and the abort statement, a statement that may be used to terminate the execution of a program.
Note that this chapter deals with programming flow control features at execution time. In addition, GAMS provides a dollar control option that allows for conditional processing of input files at compile time. For more information, see the detailed description of the option $if. For details on dollar control options in general, see chapter Dollar Control Options.
The If Statement
The if
statement is useful to branch conditionally around a group of statements. In some cases this can also be written as a set of dollar conditions, but the if
statement may make the GAMS code more readable. An optional else
and/or elseif
part allows the user to formulate traditional if-then-else
constructs.
The If Statement: Syntax
The syntax for an if
statement in GAMS is as follows:
if (logical_condition,
statement; {statement;}
{ elseif logical_condition,
statement; {statement;} }
[ else
statement; {statement;} ]
);
The keyword if
indicates that this is an if
statement. The logical condition is followed by one or more statements that are executed if the logical condition is satisfied. For details on the various forms of logical conditions in GAMS, see sections Logical Conditions and Filtering Sets. The if
statement may end at this point, without any specifications for cases when the logical condition is FALSE
and no action is taken in these cases. However, GAMS also allows further specifications: optional alternative if
tests and optional statements for cases when all previous if
tests have failed. The keyword elseif
introduces an alternative if
test with a logical condition and one or more statements. Note that the elseif
case is optional and may be repeated multiple times. Note further that the elseif
case implies that the logical condition of the if
case has not been satisfied. The keyword else
introduces the final part of the construct. It is optional and allows specification for cases when the logical condition of the if
case (and possibly the elseif
case(es)) has not been satisfied.
- Attention
- Only execution statements are permitted in programming flow control statements. Consequently declaration statements and equation definitions are not allowed inside an
if
statement.
Examples are given in the next subsection. Note that there is an alternative syntax that is more in line with the syntax of some popular programming languages. For more information, see the detailed description of the dollar control option onEnd.
The If Statement: Examples
Consider the following set of conditional assignment statements that use dollar conditions:
p(i)$(f <= 0) = -1 ;
p(i)$((f > 0) and (f < 1)) = p(i)**2 ;
p(i)$(f >= 1) = p(i)**3 ;
q(j)$(f <= 0) = -1 ;
q(j)$((f > 0) and (f < 1)) = q(j)**2 ;
q(j)$(f >= 1) = q(j)**3 ;
They may be expressed using an if-elseif-else
statement:
if (f <= 0,
p(i) = -1 ;
q(j) = -1 ;
elseif ((f > 0) and (f < 1)),
p(i) = p(i)**2 ;
q(j) = q(j)**2 ;
else
p(i) = p(i)**3 ;
q(j) = q(j)**3 ;
) ;
Note that the body of the if
statement may contain solve
statements. For instance, consider the bit of GAMS code that follows. Note that ml
is a GAMS model, z
is a free variable, j
is a set and x
is a variable.
solve ml using lp minimizing z;
if (ml.modelstat = 4,
display "model ml was infeasible, relax bounds on x and solve again";
x.up(j) = 2*x.up(j) ;
solve ml using lp minimizing z ;
else
if (ml.modelstat <> 1,
abort "error solving model ml" ;
);
);
First the model ml
is solved. For details on solve
statements in GAMS, see section The Solve Statement. Then a post solution analysis is done with the if
statement. If the model is infeasible, the upper bound on the variable x
is relaxed and the model is solved again. If the original model is not infeasible and it is not optimal either, then the compilation is aborted and the error message above is reported. For more information on GAMS output, see chapter GAMS Output, particularly subsection Model Status for a list of all GAMS model statuses. The display
statement is introduced in chapter The Display Statement. For details on the abort
command, see abort.
The following GAMS code is illegal since it is not permitted to define equations inside an if
statement.
if (s > 0,
eq.. sum(i,x(i)) =g= 2 ;
);
The following GAMS code is also illegal since declarations inside an if
statement are not allowed.
if (s > 0,
scalar y ; y = 5 ;
);
The Loop Statement
The loop
statement facilitates executing a group of statements for each member of a set. Loop
statements are particularly useful for cases when parallel assignments are not sufficient. This is the case most often when there is no analytic relationship between the values to be assigned to a parameter. It is, of course, also useful to have a looping statement for general programming.
The Loop Statement: Syntax
The syntax for the loop
statement in GAMS is as follows:
loop(index_list[$(logical_condition)],
statement; {statement;}
) ;
The keyword loop
indicates that this is a loop statement. The index_list
is the controlling domain of the loop. Note that loops may be controlled by more than one set. In this case parentheses are required around the index list, which is also called the loop set(s). Observe that dynamic sets are allowed as loop sets. The loop set(s) may be restricted by a logical condition. For details on the various forms of logical conditions in GAMS, see sections Logical Conditions and Filtering Sets. For an introduction to dollar conditions in general, see chapter Conditional Expressions, Assignments and Equations. The index list is followed by one or more statements. Except for the final statement, each statement must end with a semicolon ';'
. The loop statements are executed for each member of the controlling domain in turn. The order of evaluation is the entry order of the labels. A loop is thus another, more general, type of indexed operation.
- Attention
- Only execution statements are permitted in programming flow control statements. Consequently declaration statements and equation definitions are not allowed inside a
loop
statement. - It is illegal to modify any controlling set inside the body of the loop.
- Only execution statements are permitted in programming flow control statements. Consequently declaration statements and equation definitions are not allowed inside a
Loop
statements in GAMS are often used for iterative calculations, generating reports with put statements and doing scenario based studies with solve statements. Examples are given in the next subsection. Note that there is an alternative syntax that is more in line with the syntax of some popular programming languages. For more information, see the detailed description of the dollar control option onEnd.
The Loop Statement: Examples
Consider a hypothetical case when a growth rate is empirical:
Set t / 1985*1990 /;
Parameter pop(t) / 1985 3456 /
growth(t) / 1985 25.3, 1986 27.3, 1987 26.2
1988 27.1, 1989 26.6, 1990 26.6 /;
The loop
statement is then used to calculate the cumulative sums iteratively:
loop(t, pop(t+1) = pop(t) + growth(t) ) ;
In this example the driving set is t
and we have just one statement in the scope of the loop.
The following small artificial examples illustrate the effects of a dollar condition in a loop
statement.
Sets i / i1*i3 /
j / j1*j5 /
k(i,j) / i1.j1, i1.j3, i3.j3, i3.j5 /;
Parameter c(i) / i1 3, i2 1 /
q(i,j) / i1.j1 1, i1.j2 3, i1.j4 2 / ;
Scalars x, y, z;
x = 1; y = 3; z = 1;
loop ( (i,j) $ (q(i,j) > 0), x = x + q(i,j));
loop ( i $ (c(i) + c(i)**2), z = z + 1);
loop ( i $ sum(j, abs(q(i,j))), z = z + 1);
loop ( j $ (ord(j) > 1 and ord(j) < card(j)), z = z + 1);
loop ( (i,j) $ k(i,j), y = y + ord(i) + 2*ord(j));
In the first loop
statement the controlling domain is the set pair (i,j)
. It is restricted to those label combinations whose values associated with the parameter q
are greater than zero. The logical condition in the second loop
statement is \( c(i) + c(i)^2\). This is shorthand for \( c(i) + c(i)^2 \neq 0\). The domain in the third loop
statement is restricted to those elements of the set i
where the sum over j
of the absolute values of the parameter q
does not equal zero. Note that this condition is satisfied only for the label "i1"
. Observe that i
and j
are both ordered sets. In the fourth loop
statement the first and the last element of the set j
are excluded. For more on the set operators ord
and card
, see sections The Ord Operator and The Card Operator respectively. The dollar control in the last loop
statement excludes all label combinations that are not members of the set k
. For further details on dollar conditions, see chapter Conditional Expressions, Assignments and Equations.
- Note
- The dollar condition may be replaced by an if statement; see the example below.
The next example shows how a model can be solved for each element of a set i
with different data using a loop
statement. Note that problemdata
is a scalar, g(i)
and d(i)
are parameters, mymodel
is a GAMS model and profit
is a free variable.
loop (i,
problemdata = g(i);
solve mymodel using lp maximizing profit;
d(i) = profit.l;
);
In the first statement some data in the model is updated in accordance with the \(i^{th}\) element of the parameter g
. In the second statement the model is solved. For details on the solve
statement, see section The Solve Statement. The objective value for each iteration is saved in the parameter d
in the third statement.
A loop is often used to perform iterative calculations. Consider the following example, which finds square roots by Newton's method. This example is purely for illustration - in practice, the function sqrt
should be used. Newton's method is based on the assertion that if \(x\) is an approximation to the square root of \(v\), then \((x+v/x)/2\) is a better approximation.
Set i "set to drive iterations" / i-1*i-100 /;
Parameter value(i) "used to hold successive approximations";
Scalars target "number whose square root is needed" / 23.456 /
sqrtval "final approximation to sqrt(target)"
curacc "accuracy of current approximation"
reltol "required relative accuracy" / 1.0e-06 /;
abort$(target <= 0) "argument to newton must be positive";
value("i-1") = target/2 ;
curacc = 1 ;
loop(i$(curacc > reltol),
value(i+1) = 0.5*(value(i) + target/value(i));
sqrtval = value(i+1);
curacc = abs (value(i+1)-value(i))/(1+abs(value(i+1)))
) ;
abort$(curacc > reltol) "square root not found"
option decimals=8;
display "square root found within tolerance", sqrtval, value;
Note that in this example the dollar condition in the loop does not restrict the driving set i
, but it is used to terminate the loop procedure. The scalar curacc
is updated in every iteration. As soon as it becomes equal to or smaller than the required relative accuracy reltol
the loop stops. As the output below shows, this is the case after seven iterations. The body of the loop
statement consists of three statements. The first statement calculates the current approximation and assigns it to the parameter value
. The second statement updates the scalar sqrtval
, and the third statements computes the accuracy of the current approximation in each iteration. Note that before and after the loop statement we added lines to account for special cases. For details on the abort
statement, see section The Abort Statement at the end of this chapter. The output generated by the display statement is given below.
---- 19 square root found within tolerance ---- 19 PARAMETER SQRTVAL = 4.84313948 final approximation to sqrt(target) ---- 19 PARAMETER VALUE used to hold successive approximations i-1 11.72800000, i-2 6.86400000, i-3 5.14062471, i-4 4.85174713 i-5 4.84314711, i-6 4.84313948, i-7 4.84313948
Note that a statement within the body of a loop may be an if statement (or any other programming flow control statement). Moreover, the logical condition in a loop
statement may be expressed with an if
statement instead of a dollar condition. The following example serves as illustration. Observe that k
is a set and s
, t
, u
and a
are parameters.
loop (k,
if((s(k) < 0 and t(k)),
u(k) = a(k);
);
);
Note that if the logical condition is not satisfied the assignment is not made and the parameter u
remains unchanged.
Recall that subsets are connected with their supersets by arcs thus building a domain tree where the root node is the universal set. The following example demonstrates how the domain tree may be used in a loop statement.
Set i / i1*i10 /
ii(i)
j(i) / i1*i9 /
jj(j) / i1*i8 /
jjj(jj) / i1*i7 /;
loop(i(jjj), ii(i) = yes;);
display ii;
Observe that the looping set is i(jjj)
. This means that we loop over those elements of i
that are also elements of the set jjj
. This construct is permitted since i
is in the domain tree on the path from jjj
to the universe or universal set. It is allowed to go up the domain tree on one path and go down on another path. Therefore all the elements of jjj
are assigned to ii
. The outcome of the display statement confirms this:
---- 8 SET ii i1, i2, i3, i4, i5, i6, i7
The While Statement
The while
statement facilitates the repeated execution of one or more statements as long as a logical condition is satisfied.
The While Statement: Syntax
The syntax for the while
statement in GAMS is as follows:
while(logical_condition,
statement; {statement;}
);
The keyword while
indicates that this is a while
statement. Inside the while
statement a logical condition is followed by one or more statements. For details on the various forms of logical conditions in GAMS, see sections Logical Conditions and Filtering Sets. The statements are executed as long as the logical condition is TRUE
.
- Attention
- Only execution statements are permitted in programming flow control statements. Consequently declaration statements and equation definitions are not allowed inside a
while
statement.
Examples are given in the next subsection. Note that there is an alternative syntax that is more in line with the syntax of some popular programming languages. For more information, see the detailed description of the dollar control option onEnd.
The While Statement: Examples
Consider the following simple example:
Scalar x; x = 1;
while ( round(x,2) < 10,
x = x + 0.01;
);
display x;
Note that the scalar x
is increased in each iteration until it equals 10. Note further, that to ensure an exact result, in numerical comparisons we need a stable check like we have above (round(x,2) < 10
), otherwise rounding errors may occur. As soon as x
reaches 10, the logical condition is no longer satisfied and therefore there will be no further passes. Hence the final value of x
equals 10.
Note that the number of passes in a while
statement may be restricted using the command line parameter or option forlim. For details on command line parameters and options, see section Specifying Options Through the Command Line and chapter The Option Statement respectively.
While
statements may be used to control the solve
statement. For instance, consider the following implementation of a random multi-start method for non-convex optimization.
scalar count / 1 /;
scalar globmin / inf /;
option bratio = 1 ;
while(count <= 1000,
x.l(j) = uniform(x.lo(j),x.up(j)) ;
solve ml using nlp minimizing obj ;
if (obj.l < globmin,
globmin = obj.l ;
bestsol(j) = x.l(j) ;
) ;
count = count+1 ;
) ;
Note that we start from a random starting point by setting the initial level values randomly between the upper and lower bounds. This assumes that the bounds have been previously specified and are not infinity. When the method improves, that is, if the logical condition (obj.l < globmin)
is satisfied, the best known solution is stored in the scalar globmin
. The level values associated with the best known solution so far are then saved in the parameter bestsol
. This procedure is repeated 1000 times. The model [PRIME] is another example where the use of the while
statement is illustrated. In this model the set of all prime numbers smaller than 200 is generated.
The following GAMS code is illegal since equation definitions inside a while
statement are not permitted.
while(s > 0,
eq.. sum(i,x(i)) =g= 2 ;
);
The following GAMS code is also illegal since declarations inside a while
statement are not allowed.
while(s > 0,
scalar y ; y = 5 ;
);
The For Statement
The for
statement provides a compact way to iterate over a range of values and execute one or more statements each time.
The For Statement: Syntax
The syntax for the for
statement in GAMS is as follows:
for (a = start_value to|downto end_value [by incr],
statement; {statement;}
);
The keyword for
indicates that this is a for
statement. The scalar a
begins with the real number start_value
and is changed after each pass of the loop by the increment incr
until it reaches the real number end_value
. Note that the specification of an increment is optional, the default is 1. If the increment is given, it has to be a positive real number. Note further that to
indicates that the scalar a
is increased and downto
indicates that it is decreased. In each iteration one or more statements are executed.
- Attention
- Only execution statements are permitted in programming flow control statements. Consequently declaration statements and equation definitions are not allowed inside a
for
statement.
Examples are given in the next subsection. Note that there is an alternative syntax that is more in line with the syntax of some popular programming languages. For more information, see the detailed description of the dollar control option onEnd.
The For Statement: Examples
Consider the following simple example:
Scalar s;
for (s = -3.8 to -0.1 by 1.4,
display s ;
);
Note that negative real numbers are possible for the start and end values. The resulting listing file will contain the following lines:
---- 3 PARAMETER s = -3.800 ---- 3 PARAMETER s = -2.400 ---- 3 PARAMETER s = -1.000
Observe that the value of s
was increased by 1.4 with each pass of the loop as long as it did not exceed -0.1. In the next example the value of s
is decreased:
Scalar s;
for (s = 3 downto -0.1 by 1.4,
display s ;
);
Note that the number of passes in a for
statement may be restricted using the command line parameter or option forlim. For details on command line parameters and options, see section Specifying Options Through the Command Line and chapter The Option Statement respectively.
Like while
statements, for
statements may be used to control the solve
statement. The following example illustrates the use of the for
statement by replicating the random search for a global optimum of a non-convex model that we discussed above.
scalar i ;
scalar globmin / inf / ;
option bratio = 1 ;
for (i = 1 to 1000,
x.l(j) = uniform(x.lo(j),x.up(j)) ;
solve ml using nlp minimizing obj ;
if (obj.l < globmin,
globmin = obj.l ;
bestsol(j) = x.l(j) ;
);
);
Note that the logical condition in the while
loop (count <= 1000
) is replaced by the specification of the range of values for the scalar i
. The body of the for
loop is identical to the body of the while
loop, except for the statement to update the scalar count
that we needed in the while
loop. This demonstrates the similarities and differences between the two loops.
The following GAMS code is illegal since it is not allowed to define equations inside a for
statement.
for (s = 1 to 5,
eq.. sum(i,x(i)) =g= 2 ;
);
The following GAMS code is also illegal since declarations inside a for
statement are not permitted.
for (s = 1 to 5,
scalar y ; y = 5 ;
);
The Repeat Statement
The repeat
statement facilitates the repeated execution of one or more statements. This is done unconditionally at least once and stopped when a logical condition is satisfied.
The Repeat Statement: Syntax
The syntax for the repeat
statement in GAMS is as follows:
repeat (
statement; {statement;}
until logical_condition );
The keyword repeat
indicates that this is a repeat
statement. One or more statements are executed in each iteration. The keyword until
introduces the termination criterion: if the logical condition is satisfied, the repeat
loop is terminated. For details on the various forms of logical conditions in GAMS, see sections Logical Conditions and Filtering Sets.
Note that the repeat
statement is similar to the while
statement, but a repeat
loop is guaranteed to be executed at least one time since the logical condition is stated after the statements.
- Attention
- Only execution statements are permitted in programming flow control statements. Consequently declaration statements and equation definitions are not allowed inside a
repeat
statement.
Examples are given in the next subsection.
The Repeat Statement: Examples
Consider the following simple example:
Scalar a / 1 /;
repeat (
a = a + 1;
display a;
until a = 5 );
The scalar a
is increased in each iteration by 1. If a
equals 5, the termination criterion is satisfied and the loop stops. Note that this example works nicely since both, the scalar and the increment, are integer. In case the entity on the right-hand side of the termination condition is not an integer or the increment is not an integer, we recommend a formulation of the check that is more stable to avoid rounding errors. An example for a stable termination condition follows.
Scalar a / 1 /;
repeat (
a = a + 0.1;
display a;
until abs(a-5) < 1e-6 );
Observe that in the next example the termination condition is TRUE
from the start. In this case the statement in the body of the repeat
statement is executed once and then the loop is terminated. Hence the final value of a
will be 5.
Scalar a / 4 /;
repeat (
a = a + 1;
display a;
until a >= 3 );
Note that the number of passes in a while statement may be restricted using the command line parameter or option forlim. For details on command line parameters and options, see section Specifying Options Through the Command Line and chapter The Option Statement respectively.
Here is a little more complex example. A repeat
statement is used to narrow the interval where a quadratic function passes through zero. Note that, as is often the case, one of the statements in the repeat
loop is another programming flow control statement, in this case an if
statement.
Scalar max "current upper boundary of interval" /10/
min "current lower boundary of interval" /-10/
root "value where function equals zero"
function_value1 "function value at min"
function_value2 "function value at max"
tolerance "tolerance for root" /0.00000001/
signswitch "indicates that sign switch was found" /0/
inc "increment to try to find sign switch" ;
function_value1 = 6 - 5*min + sqr(min);
inc = (max - min)/37;
root = min;
repeat (
root = root + inc;
function_value2 = 6 - 5*root + sqr(root);
if(( sign(function_value1) <> sign(function_value2)
and abs(function_value1) > 0
and abs(function_value2) > tolerance ),
max = root;
signswitch = 1;
else
if(abs(function_value2) > tolerance,
function_value1 = function_value2;
min = root;
);
);
until (signswitch > 0) or (root > max) );
display min, max, function_value1, function_value2;
The result of the display
statement shows that the value of min
is 1.892 and the value of max
is 2.432, the interval was narrowed to 0.54, which is just a little less than the value of inc
. As expected, function_value1
and function_value2
differ in sign, confirming that the root of the quadratic function is indeed in the interval.
The Break Statement
The break
statement gives additional control over the execution of loop structures, namely the loop statement, the while statement, the for statement and the repeat statement. It allows to break the execution of a loop structure prematurely.
The Break Statement: Syntax
The syntax for the break
statement is as follows:
break [n];
The keyword break
indicates that this is a break statement. It terminates the n
inner most control structures. n
is optional and if it is omitted, it is set to 1.
Most often break
statements are used in the context of if statements or with dollar conditions. For details on the various forms of logical conditions in GAMS, see sections Logical Conditions and Filtering Sets.
The Break Statement: Examples
This is a simple, artificial example using the break
statement to exit a loop
statement:
Set i / i1*i10 /;
Scalar cnt / 0 /;
loop(i,
break$sameas('i6',i);
cnt = cnt+1;
);
display cnt;
The break
statement in combination with the dollar condition terminates the execution of the loop body in the 6th iteration. This can be seen looking at the value of cnt
after the loop, which will be 5.
Here is a little more complex example which uses the optional argument n
to terminate more than one loop structure at once:
Set i / i1*i10 /;
Scalar x, y,
cnt / 0 /;
for(x = 1 to 10,
y = 0;
while(y < 10,
y = y+1;
loop(i,
break$sameas('i6',i) 2;
cnt = cnt+1;
);
);
);
display cnt;
In this example, cnt
will be 50 at the end. As in the previous example, it is increased 5 times in the inner most loop, before the break
statement is executed. This time break
is called with the argument 2
, which causes the two inner most control structures (namely the loop
and the while
) to be terminated. The outer most control structure (the for
) is not influenced, so that its body gets executed 10 times, which results in a total of 50 increments for the scalar cnt
.
Note, if break
would be called with the argument 3 instead of 2, also the for
loop would be terminated, so that cnt
would be 5 at the end. If break
would be called with 1 (or without additional argument) instead of 2, only the inner most loop
would be terminated so that cnt
would be 500 at the end.
The Continue Statement
The continue
statement gives additional control over the execution of loop structures, namely the loop statement, the while statement, the for statement and the repeat statement. It allows to jump to the end of the inner most loop structure without executing the remaining statements in the body.
The Continue Statement: Syntax
The syntax for the continue
statement is as follows:
continue;
The keyword continue
indicates that this is a continue statement. It jumps to the end of the inner most control structure.
Most often continue
statements are used in the context of if statements or with dollar conditions. For details on the various forms of logical conditions in GAMS, see sections Logical Conditions and Filtering Sets.
The Continue Statement: Examples
This is a simple, artificial example using the continue
statement to skip parts of a loop
body:
Set i / i1*i10 /;
Scalar cnt / 0 /;
loop(i,
continue$(mod(ord(i),2)=0);
cnt=cnt+1
);
display cnt;
In that example, every 2nd iteration of the loop
statement is skipped. Therefore, cnt
will be 5 at the end of the loop
.
The Abort Statement
The abort
statement is used to terminate the execution of a program. Most often the abort statement is used in the context of conditionals. Examples are given below. Also it may be used to display a text or an identifier in the listing file similar to the display statement but mostly to present the reason for the termination of the execution.
Note that the abort
statement is to be distinguished from the dollar control option $abort which may be used to terminate the compilation of a program.
The Abort Statement: Syntax
The syntax for the abort
statement is as follows:
abort ident | quoted text {, ident | quoted text};
The keyword abort
indicates that this is an abort statement. Ident
denotes an identifier. If the identifier is a set or a parameter, only the name of the set or parameter itself is specified, without any domains. If the identifier is a variable, an equation or a model, it must be followed by a suffix, since only attributes of variables, equations and models can be displayed. For more on variable and equation attributes including full lists, see sections Variable Attributes and Equation Attributes respectively. For details on model attributes, see section Model Attributes. Recall that sets also have attributes, they may also be displayed using the suffix notation. For details on set attributes, see section Set Attributes. As usual, quoted text
must be surrounded by single or double quotes. The identifiers and the text may be mixed and matched in any order, and the whole statement may be continued over several lines.
An abort statement causes the termination of the execution with an execution error and the information in the statement will be displayed.
There is also a variant with the extension .noError
that terminates the execution and displays the information, but does not cause an execution error. The syntax is as follows:
abort.noError ident | quoted text {, ident | quoted text};
Most often abort
statements are used in the context of if statements or with dollar conditions. The syntax is as follows:
if (logical_condition, abort ident | quoted text {, ident | quoted text}; );
or
abort$logical_condition ident | quoted text {, ident | quoted text};
For details on the various forms of logical conditions in GAMS, see sections Logical Conditions and Filtering Sets.
The Abort Statement: Examples
Consider the following artificial example:
Set i / i1*i5 /;
Parameter p(i) / i1 1, i2 2, i3 3, i4 5, i5 8 /;
loop(i,
if (p(i) > 3, abort "Parameter larger than 3", p);
p(i) = p(i) + 2;
);
Note that the abort statement is part of an if statement which is part of a loop statement. The execution of this program will be terminated with the following display and error message:
---- 4 Parameter larger than 3 ---- 4 PARAMETER p i1 3.000, i2 4.000, i3 5.000, i4 5.000, i5 8.000 **** Exec Error at line 4: Execution halted: abort 'Parameter larger than 3'
Observe that the values of p('1')
, p('2')
and p('3')
were updated, but the values of p('4')
and p('5')
are equal to the initialization values since the program was terminated before they could be updated.
If the extension .noError
is used in the example above, the following lines will appear in the listing file:
---- 4 Parameter larger than 3 ---- 4 PARAMETER p i1 3.000, i2 4.000, i3 5.000, i4 5.000, i5 8.000 **** **** Execution halted from line 4: abort.noError 'Parameter larger than 3' ****
Note that the execution of the program is aborted as before, but there is no execution error in this case.
Instead of an if statement we may use a dollar condition in the loop:
Set i / i1*i5 /;
Parameter p(i) / i1 1, i2 2, i3 3, i4 5, i5 8 /;
loop(i,
abort$(p(i) > 3) "Parameter larger than 3", p;
p(i) = p(i) + 2;
);
Observe that this alternative formulation has the same outcome as above.