Conditional Expressions, Assignments and Equations

This chapter deals with the way in which conditional assignments, expressions and equations are made in GAMS. The index operations already described are very powerful, but it is necessary to allow for exceptions of one sort or another. For example, heavy trucks may not be able to use a particular route because of a weak bridge, or some sectors in an economy may not produce exportable products. Exceptions such as these may easily be modeled with a logical condition combined with the dollar operator '$', a very powerful feature of GAMS introduced in this chapter. This chapter is organized as follows: We will introduce the general form of the dollar condition first and then we will focus on the various types of logical conditions. Next, we will discuss how dollar conditions are used to build conditional assignments, conditional indexed operations and conditional equations. We will conclude the chapter by showing that in certain cases conditions may be modeled using filtering sets instead of the dollar operator. Programming flow control features such as the if statement, the loop, the while statement, and the for statement are not covered in this chapter. These can be found in the chapter Programming Flow Control Features. # The Dollar Condition The dollar operator is one of the most powerful features in GAMS. The general syntax for a conditional expression is: term$ logical_condition


Here, term can be a number, a (indexed) symbol, and also a complex expression. The dollar operator may be read as under the condition that the following logical_condition evaluates to TRUE (or is unequal 0).

Consider the following simple condition, where a and b are scalars.

if (b > 1.5), then a = 2


This can be written in GAMS using the dollar operator as follows.

a $(b > 1.5) = 2 ;  Note that the term is the scalar a and the logical condition is the expression $$(b > 1.5)$$. If the condition is not satisfied, no assignment is made. To make it clear, this conditional assignment may be read as: 'given that b is greater than 1.5, a equals 2'. Logical conditions may take various forms, they are introduced in the next section. Conditional expressions may be used in the context of assignments, indexed operations and equations. These topics are covered in later sections of this chapter. Note Logical conditions used with the dollar operator cannot contain variables. However, variable attributes are allowed. # Logical Conditions Logical conditions are special expressions that evaluate to a value of either TRUE or FALSE. Logical conditions may be numerical expressions and numerical relations, they may refer to set membership and they may also contain acronyms. In the following subsections this is shown in the context of simple conditional assignments with the dollar operator on the left-hand side (compare section Dollar on the Left). In this section we use many examples to illustrate the concepts that are being introduced. In all these examples a and b are scalars, s, t, u and v are parameters, and i and j are sets. ## Logical Conditions: Numerical Expressions Numerical expressions may serve as logical conditions: a result of zero is treated as the logical value FALSE and a non-zero result is treated as the logical value TRUE. The following example illustrates this point. b$ (2*a - 4) = 7;


Here the numerical expression $$(2*a - 4)$$ is the logical condition. The numerical expression is zero if a equals 2, and non-zero otherwise. Hence the logical value of the expression is FALSE for $$a=2$$ and TRUE for all other values of a. The assignment is only made if the numerical expression evaluates to TRUE, otherwise no assignment is made.

Attention
Values of the extended range arithmetic such as inf are also allowed in logical conditions. If the result of a numerical expression used as a logical condition takes any of these values, the logical value is TRUE, even for e.g. eps, which is numerically 0.

Observe that functions are also allowed in logical conditions. If they evaluate to zero, the logical condition is FALSE, otherwise it is TRUE. Consider the following example:

b $cos(a) = 7;  Note that the assignment is only made if the cosine of a does not equal zero. ## Logical Conditions: Numerical Relational Operators Numerical relational operators compare two numerical expressions and return a logical value. For completeness, all numerical relational operators are listed in Table 1. Relation Operator Alternative Notation Return Values Strictly less than x < y x lt y Returns TRUE if $$x < y$$, else returns FALSE. Less than or equal to x <= y x le y Returns TRUE if $$x \leq y$$, else returns FALSE. Equal to x = y x eq y Returns TRUE if $$x = y$$, else returns FALSE. Not equal to x <> y x ne y Returns TRUE if $$x \neq y$$, else returns FALSE. Greater than or equal to x >= y x ge y Returns TRUE if $$x \geq y$$, else returns FALSE. Strictly greater than x > y x gt y Returns TRUE if $$x > y$$, else returns FALSE. Table 1: Numerical Relational Operators Consider the following examples. b$ (a < 0) = 10;
b $(sqr(a) > a) = 12; a$ ( sum(i, s(i)) > 0 ) = 7;
t(i) $(a <> 0) = t(i) + 1;  In the first line the logical condition is the relational expression $$(a < 0)$$. The assignment is only made if this expression is TRUE, that is, if the scalar a is negative. The logical condition in the second line is a bit more complex. It evaluates to FALSE if $$0 \leq a \leq 1$$. For all other values of a, it evaluates to TRUE. So the assignment is made for all values of a, except for those values of a that are in the closed interval $$[0, 1]$$. Note that if $$a = -3$$, then the logical condition in the first line will be TRUE, so b will become 10. In addition, the logical condition in the second line will be TRUE, so b will change to 12. The logical condition in the third line evaluates to TRUE if the sum of all values of the parameter s is strictly positive. Then a is assigned the value of 7. The assignment in the last line depends on whether a is non-zero. If a is zero no assignment is made, otherwise all entries of the parameter t are updated. Note that acronyms may also be used with relational operators to build logical conditions. However, only the equality operator = and inequality operator <> are allowed in the context of acronyms, since they have no numerical values and the other operators would be meaningless. For an example, see section Acronym Usage. ## Logical Conditions: Logical Operators GAMS offers standard logical operators that may combine two or more logical conditions to build complex logical expressions. For example, if several expressions are required to be TRUE simultaneously, they may be connected with the operator and. The logical operators available in GAMS are listed in Table 2 and Table 3. Another way to construct complex logical conditions is by nesting them. For details, see subsection Nested Dollar Conditions below. Operation Operator Alternative Notation Description Negation not x The logical condition x has to be FALSE, in order for the expression to be TRUE. Logical conjunction x and y Two logical conditions are TRUE simultaneously. Logical disjunction x or y At least one of two logical conditions applies. Exclusive disjunction x xor y Exactly one of two logical conditions applies. Logical implication x imp y x -> y If the logical condition x is TRUE but at the same time the logical condition y is FALSE, then the whole expression is FALSE, in all other cases the expression evaluates to TRUE. Logical equivalence x eqv y x <=> y Both logical conditions are either TRUE simultaneously or FALSE simultaneously for the whole expression to be TRUE. Table 2: Logical Operators The logical values of these operators are summarized in the following truth table. x y not x x and y x or y x xor y x imp y x eqv y FALSE FALSE TRUE FALSE FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE FALSE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE TRUE TRUE Table 3: Truth Table of Logical Operators The following somewhat artificial examples serve as illustration. Set i / i1*i5 /; Parameter s(i) / i1 3, i2 5, i4 8 / t(i) / i1*i4 13 / u(i) / i2 1 / v(i) / i1 7, i3 2 /; u(i)$ (not s(i))               = v(i);
u(i) $(s(i) and u(i) and t(i)) = s(i); u(i)$ (s(i) or v(i) or t(i))   = 4;


Note that there are three conditional assignments for the parameter u. In the first assignment the logical condition is (not s(i)). This condition holds for all entries of s that are not specified and therefore zero by default: s('i3') and s('i5'). Hence u('i3') and u('i5') are assigned the values of v('i3') and v('i5') respectively. The value of v('i3') is 2 and the value of v('i5') is zero by default. After the first assignment we have u('i2')=1 and u('i3')=2, all other values of u are zero. Note that the logical condition failed for u('i2') and therefore its value remained unchanged. The logical condition in the second assignment is TRUE for those labels of the set i that have non-zero entries in the parameters s, u and t simultaneously. This condition holds only for i2. Therefore u('i2')=s('i2')=5 and all other values of u remain unchanged, resulting in non-zero values only for u('i2') and u('i3'). The logical condition in the last assignment evaluates to TRUE for all labels of the set i that have at least one non-zero entry in the parameters s, v and t. This holds for all labels except for i5. Therefore u('i5') stays zero and all other values of u are changed to 4. These examples demonstrate the power of the dollar operator combined with logical operators. Even more complex logical conditions are possible; see subsection Mixed Logical Conditions below for details.

## Logical Conditions: Set Membership and Set Functions

Apart from numerical and relational expressions, set membership and functions referencing set elements may be used as a logical condition. Consider the following example as illustration for set membership as logical condition.

Set        i     / i1*i5 /
j(i)  / i1*i3 / ;
Parameter  s(i)  / i1 3, i2 5, i3 11, i4 8, i5 1 /
t(i);
t(i) $j(i) = s(i) + 3;  Note that the set j is a subset of the set i and that the parameter t is declared but not defined. The conditional expression t(i)$j(i) in the last line restricts the assignment to the members of the subset j since only they satisfy the condition j(i). The values for t('i4') and t('i5') remain unchanged. In this case this means that they are zero (by default). Note that there is an alternative formulation for this type of conditional assignment; for details see subsection Filtering Sets in Assignments below.

Note
Only the membership of subsets and dynamic sets may be used as logical conditions.

The use of set membership as a logical condition is an extremely powerful feature of GAMS, see section Conditional Equations below for more examples.

Logical conditions may contain functions that return particular values depending on the position of elements in sets, the size of sets or the comparison of set elements to each other or text strings. These functions are presented in Table 4.

sameAs(element1,element2) or sameAs("text",element2) or sameAs(element1,"text") Returns TRUE if element1 is identical to element2 or element1 is identical to text, and FALSE otherwise.
diag(element1,element2) or diag("text",element2) or diag(element1,"text") Same as function sameAs, but returns numerical value 1 for TRUE and 0 for FALSE.
card(set_name) Returns the number of elements in a set. Note that this can also be called with a quoted text and returns the number of characters of that text in that case. For more details, see section The Card Operator.
ord(set_name) Returns the relative position of an element in a set. Note that ord may be used only with one-dimensional, static, ordered sets. For more details, see section The Ord Operator.

Table 4: Functions Referencing Sets

In the following example we have two sets of cities and we want to know how many of them feature in both sets.

Set     i     / Beijing, Calcutta, Mumbai, Sydney, Johannesburg, Cairo /;
Set     j     / Rome, Paris, Boston, Cairo, Munich, Calcutta, Barcelona /;
Scalar  b;
b = sum((i,j)$sameAs(i,j),1);  Note that in the assignment statement we sum over both sets and we use the function sameAs to restrict the domain of the indexed operation to those label combinations (i,j) where the function sameAs evaluates as TRUE. Thus only identical elements are counted. Note that in this example the function diag could have been used with the same result. The functions ord and card are frequently used to single out the first or last element of an ordered set. For example, we may want to fix a variable for the first and last elements of a set: x.fx(i)$ (ord(i) = 1)       = 3;
x.fx(i) $(ord(i) = card(i)) = 7;  In the first assignment the variable x is fixed for the first element of the set i and in the second assignment x is fixed for the final element of i. Note As an alternative to the formulation above, one could also use the set attributes first and last to get the same result: x.fx(i)$ (i.first) = 3;
x.fx(i) $(i.last) = 7; ## Numerical Values of Logical Conditions We have seen that logical conditions may take the form of numerical expressions, expressions with relational operators, complex expressions using logical operators, set membership and set functions. However, GAMS does not have a Boolean data type. Attention GAMS follows the convention that the result of a relational operation is zero if the assertion is FALSE, and 1 if it is TRUE. Consider the following example as illustration. x = (1 < 2) + (2 < 3);  The expression to the right of the assignment evaluates to 2 since both logical conditions within parentheses are TRUE and therefore assume a value of 1. Note that this is different from the assignment below: x = (1 < 2) or (2 < 3)  This assignment evaluates to 1, since both statements to the left and right of or are TRUE and therefore the whole expression is TRUE. ## Mixed Logical Conditions The building blocks introduced in the subsections above may be combined to generate more complex logical conditions. These may contain standard arithmetic operations, numerical relational operations and logical operations. All operations, their symbols and their order of precedence are given in Table 5. Note that 1 denotes the highest order of precedence and 7 denotes the lowest order of precedence. As usual, the default order of precedence holds only in the absence of parentheses and operators (symbols) on the same level are evaluated from left to right. Type of Operation Operation Operator Order of precedence Standard arithmetic operation Exponentiation ** 1 Standard arithmetic operation Multiplication, Division *, / 2 Standard arithmetic operation Unary operators: Plus, Minus +, - 3 Standard arithmetic operation Binary operators: Addition, Subtraction +, - 3 Numerical Relational operation All <, <=, =, <>, >=, > 4 Logical operation Negation not 5 Logical operation Logical Conjunction and 6 Logical operation All other logical operations or, xor, imp, eqv 7 Table 5: Complete Hierarchy for Operator Precedence in GAMS Note We recommend to use parentheses rather than relying on the order of precedence of operators. Parentheses prevent errors and make the intention clear. Consider the following example: x - 5*y and z - 5 (x - (5*y)) and (z-5)  These two complex logical conditions are equivalent. However, the parentheses make the second expression easier to understand. Some simple examples of complex logical conditions, their numerical values and their logical values are given in Table 6. Logical Condition Numerical Value Logical Value (1 < 2) + (3 < 4) 2 TRUE (2 < 1) and (3 < 4) 0 FALSE (4*5 - 3) + (10/8) 18.25 TRUE (4*5 - 3) or (10 - 8) 1 TRUE (4 and 5) + (2*3 <= 6) 2 TRUE (4 and 0) + (2*3 < 6) 0 FALSE Table 6: Examples of Complex Logical Conditions ## Nested Dollar Conditions An alternative way to model complex logical conditions is by nesting them. The syntax is: term$ (logical_condition1$(logical_condition2$(...)))


Note that in nested dollar conditions all succeeding expressions after the dollar operator must be enclosed in parentheses. The nested expression is equivalent to the following conditional expression that uses the logical operator and instead of the nesting:

term $(logical_condition1 and logical_condition2 and ...)  Consider the following example. Note that i, j(i) and k(i) are sets, and u(i) and v(i) are parameters. u(i)$ (j(i)$k(i)) = v(i) ;  The assignment will be made only for those members of the set i that are members of both sets j and k. Note the position of the parentheses in the dollar condition. The assignment statement above can be rewritten in the following way. u(i)$ (j(i) and k(i)) = v(i) ;

Note
We recommend to use the logical and operator instead of nesting dollar operators, because this formulation is easier to read.

# Conditional Assignments

A conditional assignment is an assignment statement with a dollar condition on the left-hand side or on the right-hand side. Most examples until now were conditional assignments with the dollar operator on the left.

Attention
The effect of the dollar condition is significantly different depending on which side of the assignment it is located.

The next two subsections describe the use of the dollar condition on each side of the assignment. Note that in many cases it may be possible to use either of the two forms of the dollar condition to describe an assignment. We recommend to choose the clearer formulation.

Note that if the logical condition in an assignment statement refers to set membership, then under certain conditions the restriction may be expressed without the use of the dollar operator. For details, see section Filtering Sets in Assignments below.

## Dollar on the Left

If the dollar condition is on the left-hand side of an assignment, an assignment is made only in case the logical condition is satisfied. If the logical condition is not satisfied then no assignment is made and the previous content of the parameter on the left will remain unchanged. In case the parameter on the left-hand side of the assignment has not previously been initialized or assigned any values, zeros will be used for any label for which the assignment was suppressed.

Consider the following example adapted from [CHENERY]. Note that the parameter sig has been previously defined in the model.

rho(i) $(sig(i) <> 0) = (1./sig(i)) - 1. ;  In this assignment rho(i) is calculated and the dollar condition on the left protects against dividing by zero. If any of the values associated with the parameter sig turns out to be zero, no assignment is made and the previous values of rho(i) remain. As it happens, rho(i) was not previously initialized, and therefore all the labels for which sig(i) is zero will result in a value of zero. Now recall the convention that non-zero implies TRUE and zero implies FALSE. The assignment above could therefore be written as: rho(i)$ sig(i)  =  (1./sig(i)) - 1. ;


In the following examples i is a set and s and t are parameters.

s(i) $t(i) = t(i); s(i)$ ((t(i)-1) > 0) = t(i)**0.5;


Note that the first assignment is suppressed if the value of the parameter t equals zero. The second assignment is suppressed for values of the parameter t that are smaller or equal to 1.

Note
The first of the last two examples is special in the way that the logical condition used with the dollar on the left and the expression on the right hand side of the assignment are actually the same. This allows to use a shorter notation using the combined $= assignment. That assignment is equivalent to the following one (which called sparse assignment): s(i)$= t(i);


## Sparse Assignments

Sparse assignments will assign a value to the left-hand side of the = sign only if the right-hand side is nonzero. This behavior is triggered using the $= notation as in the following example. Set i /a,b,c/ Parameter d1(i) "Initial data" /a 1, b 1, c 1/ d2(i) "Data to be used to overwrite d1" /a 0, b -2 / d3(i) "Empty data parameter"; * Initialize d3 to d1 d3(i) = d1(i); * Use dollar on the left to overwrite d3 with non-zero values from d2 d3(i)$d2(i) = d2(i);
* Result: d3('a')=1; d3('b')=-2; d3('c')=1;

* Re-Initialize d3 to d1
d3(i) = d1(i);
* Use sparse assignment to overwrite d3 with non-zero values from d2
d3(i) $= d2(i); * Result: d3('a')=1; d3('b')=-2; d3('c')=1;  Note that in the final assignments above, the values of the parameter d3(i) are replaced with values from parameter d2(i) only if the entry in d2(i) is non-zero, the other values are left untouched. Both assignments are equivalent. ## Dollar on the Right If the dollar condition is on the right-hand side of an assignment statement, an assignment will always be made. In case the logical condition is not satisfied the value of zero is assigned. Above we had the following simple conditional assignment: a$ (b > 1.5) = 2;


Now we move the dollar condition to the right-hand side:

a = 2 $(b > 1.5) ;  This is equivalent to: if (b > 1.5) then (a = 2), else (a = 0)  Note that an if-then-else type of construct is implied, but the else operation is predefined and never made explicit. The else could be made explicit with the following formulation: a = 2$ (b > 1.5) + 0 $(b <= 1.5) ;  The use of this feature is more apparent in instances when an else condition needs to be made explicit. Consider the next example adapted from the fertilizer model [FERTD] . The set i is the set of plants, and we are calculating mur(i), the cost of transporting imported raw materials. In some cases a barge trip must be followed by a road trip because the plant is not alongside the river and we must combine the separate costs. The assignment is: mur(i) = (1.0 +. 0030*ied(i,'barge'))$ ied(i,'barge')
+ (0.5 + .0144*ied(i,'road' )) $ied(i,'road' );  This means that if the entry in the distance table ied is not zero, then the cost of shipping using that link is added to the total cost. If there is no distance entry, there is no contribution to the cost, presumably because that mode is not used. Consider another example for a conditional assignment with the dollar operator on the right: b = sum(i,t(i))$ (a > 0) + 4;


Here a and b are scalars, i is a set and t is a parameter. If the scalar a is positive, the scalar b is assigned the sum of all values of the parameter t plus 4. If a is zero or negative, b becomes just 4. Note that the sum is only computed if the condition holds, this potentially makes the program faster.

# Conditional Indexed Operations

We have seen how exceptions in assignments are modeled with dollar conditions. Dollar conditions are also used in indexed operations, where they control the domain of operation. This is conceptually similar to the conditional assignment with the dollar on the left.

Consider the following example adapted from [GTM], a gas trade model for interrelated gas markets. Here the set i contains supply regions and the parameter supc models supply capacities. The scalar tsupc is computed with the following statement:

tsupc  =  sum(i $(supc(i) <> inf), supc(i)) ;  This assignment restricts the sum to the finite values of the parameter supc. In indexed operations the logical condition is often a set. This set is called the conditional set and assignments are made only for labels that are elements of the conditional set. This concept plays an important role in dynamic sets. Multi-dimensional sets are introduced in section Multi-Dimensional Sets. In the example used there a two-dimensional set is used to define the mapping between countries and ports. Another typical example for a multi-dimensional set is a set-to-set mapping that defines the relationship between states and regions. This is useful for aggregating data from the state to the regional level. Consider the following example: Sets r "regions" / north, south / s "states" / florida, texas, vermont, maine / corr(r,s) / north.(vermont,maine) south.(florida,texas) /; Parameter y(r) "income for each region" income(s) "income of each state" / florida 4.5, vermont 4.2 texas 6.4, maine 4.1 / ;  The set corr links the states to their respective regions, the parameter income is the income of each state. The parameter y is computed with the following assignment statement: y(r) = sum(s$ corr(r,s), income(s)) ;


The conditional set corr(r,s) restricts the domain of the summation: for each region r the summation over the set s is restricted to the label combinations (r,s) that are elements of the set corr(r,s). Conceptually, this is analogous to the Boolean value TRUE or the arithmetic value non-zero. The effect is that only the contributions of vermont and maine are included in the total for north, and south is the sum of the incomes from only texas and florida.

Note that the summation above can also be written as:

y(r) = sum(s,income(s) $corr(r,s));  In this formulation the parameter income is controlled by the conditional set corr instead of the index s. Note that both formulations yield the same result, but the second alternative is more difficult to read. In the next example the logical condition on the right-hand side appears in the context of an indexed operation, but it does not refer to the index. Thus it is treated similarly to a dollar on the right logical condition. Note that a and b are scalars, i is a set and s is a parameter. b = sum(i$ a, s(i));


Here the scalar b is assigned the sum of the values of the parameter s only if a does not equal zero. Otherwise b will be assigned the value zero. Observe that the following alternative formulation will generally be faster than the assignment above:

b = sum(i, s(i)) $a;  Note that if the logical condition in the context of indexed operations refers to set membership, then under certain conditions the restriction may be expressed without the use of the dollar operator. For details, see section Filtering Controlling Indices in Indexed Operations below. # Conditional Equations The dollar operator is also used for exception handling in equations. The next two subsections discuss the two main uses of dollar operators in the context of equations: in the body of an equation and over the domain of definition. ## Dollar Operators within the Algebra of Equations A dollar operator in the algebraic formulation of an equation is analogous to the dollar control on the right of assignments, as presented in section Dollar on the Right. Assuming that "the right" means the right of the '..' then the analogy is even closer. As in the context of assignments, an if-else operation is implied. It is used to exclude parts of the definition from some of the generated constraints. Consider the following example adapted from the production model [CHENERY]. Set i "sectors" / light-ind, food+agr, heavy-ind, services / t(i) "tradables" / light-ind, food+agr, heavy-ind /; Variables x(i) "quantity of output" y(i) "final consumption" e(i) "quantity of exports" m(i) "quantity of imports"; Equations mb(i) "material balance"; mb(i).. x(i) =g= y(i) + (e(i) - m(i))$ t(i) ;


Note that in the equation definition in the last line, the term (e(i) - m(i)) on the right-hand side of the equation is added only for those elements of the set i that also belong to the subset t(i), so that the element services is excluded.

Further, conditional indexed operations may also feature in expressions in equation definitions. The supply balance equation from the gas trade model [GTM] is an example. Note that the set i contains the supply regions, the set j contains the demand regions, and the two-dimensional set ij is the set of feasible links; the variable x denotes the shipment of natural gas and the variable s denotes the regional supply.

sb(i)..  sum(j $ij(i,j), x(i,j)) =l= s(i) ;  Similar to the assignment example seen before, the conditional set ij(i,j) restricts the domain of the summation: for each supply region i the summation over the demand regions j is restricted to the label combinations (i,j) that are elements of the set of feasible links ij(i,j). ## Dollar Control over the Domain of Definition In case constraints should only be included in the model if particular conditions are met, a dollar condition in the domain of definition of an equation may be used to model this restriction. Such a dollar condition is analogous to the dollar control on the left of assignments. Assuming that "the left" means the left of the symbols '..' then the analogy is even closer. Note The dollar control over the domain of definition of equations restricts the number of constraints generated to less than the number implied by the domain of the defining sets. Consider the following example adapted from the Andean fertilizer model [ANDEAN] : gple(w,wp,te)$ ple(w,wp)..  yw(w,te) - yw(wp,te) =l= dpack;


Here w, wp and te are sets, ple is a two-dimensional parameter, yw is a variable and dpack is a scalar. Note that the dollar condition restricts the first two indices of the domain of the equation to those label combinations that have non-zero entries in the two-dimensional parameter ple.

Sometimes the desired restriction of an equation may be achieved either way: through a condition in the algebra or a condition in the domain of definition. Compare the following two lines, where eq1 and eq2 are equations, i and j are sets, b is a scalar, s is a parameter and x is a two-dimensional variable.

eq1(i) $b.. sum(j, x(i,j)) =g= -s(i); eq2(i).. sum(j, x(i,j))$ b =g=  -s(i) $b;  In the first line the dollar condition is in the domain of definition, in the second line the dollar conditions are in the algebraic formulation of the equation. If b is non-zero, the generated equations eq1 and eq2 will be identical. However, if b is 0, no equation eq1 will be generated, but for each i we will see a trivial equation eq2 of the form 0 =g= 0;. Note that if the logical condition in the domain of definition of an equation refers to set membership, then under certain conditions the restriction may be expressed without the use of the dollar operator. For details, see section Filtering the Domain of Definition below. # Filtering Sets If the logical condition refers to set membership, the restriction modeled with a dollar condition may sometimes be achieved without the dollar operator. Consider the following statement, where i and j(i) are sets, and u and s are parameters: u(i)$ j(i) = s(i) ;


Note that the assignment is made only for those elements of the set i that are also elements of the subset j. This conditional assignment may be rewritten in a shorter way:

u(j) = s(j) ;


In this statement the assignment has been filtered through the condition without the dollar operator by using the subset j as the domain for the parameters u and s. This formulation is cleaner and easier to understand. It is particularly useful in the context of multi-dimensional sets (tuples), and it may be used in assignments, indexed operations and the domain of definition of equations.

## Filtering Sets in Assignments

Suppose we want to compute the transportation cost between local collection sites and regional transportation hubs for a fictional parcel delivery service. We define sets for the collection sites and transportation hubs and a two-dimensional set where the collection sites are matched with their respective hubs:

Set i       "local collection sites"       / miami, boston, chicago, houston, phoenix /
j       "regional transportation hubs" / newyork, detroit, losangeles, atlanta    / ;

Set r(i,j)  "regional transportation hub for each local collection site"  /
boston   .newyork
miami    .atlanta
houston  .atlanta
chicago  .detroit
phoenix  .losangeles  / ;

Table distance(i,j)     "distance in miles"
newyork     detroit  losangeles     atlanta
miami         1327        1387        2737         665
boston         216         699        3052        1068
chicago        843         275        2095         695
houston       1636        1337        1553         814
phoenix       2459        1977         398        1810;

Parameter factor        "cost estimate per unit mile"
shipcost(i,j) "cost of transporting parcels from a local collection site to a regional hub per unit" ;

factor = 0.009 ;
shipcost(i,j) $r(i,j) = factor*distance(i,j) ;  The distance between collection sites and transportation hubs is given in the table. The last line is a conditional assignment for the parameter shipcost. This assignment is only made if the label combination (i,j) is an element of the set r. Note that in each instance the indices i and j appear together. Thus the assignment may be simply written as: shipcost(r) = factor*distance(r) ;  Note that the assignment is explicitly restricted to the members of the set r; the dollar operator is not necessary. Observe that if the indices i or j appear separately in any assignment, the above simplification cannot be made. For example, consider the case where the shipping cost depends not only on the parameter factor and the distance between collection sites and regional hubs, but also on the congestion at the regional hub. We introduce a new parameter congestfac that models the congestion at each regional hub and is indexed only over the set j: Parameter congestfac(j) "congestion factor" / newyork 1.5 detroit 0.7 losangeles 1.2 atlanta 0.9/ ;  The new cost of shipment is computed as follows: shipcost(i,j)$ r(i,j) = factor*congestfac(j)*distance(i,j) ;


Note that this conditional assignment cannot be reformulated as:

shipcost(r) = factor*congestfac(j)*distance(r) ;


In the representation above the index j appears on the right-hand side, but not on the left-hand side. GAMS will flag this assignment as an error. However, the following representation will work:

shipcost(r(i,j)) = factor*congestfac(j)*distance(r) ;


In this formulation the set r is explicitly denoted as a tuple of the sets i and j. The set j may then appear on the right-hand side.

## Filtering Controlling Indices in Indexed Operations

Similarly, the controlling indices in indexed operations may be filtered through the conditional set without the use of the dollar operator. We continue with the shipping cost example from the last subsection. The total cost of shipment is obtained through the equation that follows. We also include the variable definitions for clarity.

Variable shipped(i,j), totcost ;
Equation costequ ;

costequ.. totcost =e= sum((i,j) $r(i,j), shipcost(i,j)*shipped(i,j));  Here the variable shipped is the number of parcels shipped from the local collection site i to the regional transportation hub j, and the variable totcost is the total cost of all shipments. Note that she summation in the equation is restricted to the label combinations that are elements of the set r. Alternatively, the equation above may be written as: costequ.. totcost =e= sum(r, shipcost(r)*shipped(r));  In this formulation the summation is performed explicitly only over the elements of the set r, no dollar condition is necessary. However, if the expression in the equation included a term dependent only on index j, then we would have to reformulate differently. Suppose the equation included also the congestion factor congestfac that is indexed only over j: cost.. totcost =e= sum((i,j)$ r(i,j), factor*congestfac(j)*distance(i,j)*shipped(i,j));


In this case the equation needs to be simplified in the following way:

cost.. totcost =e= sum(r(i,j), factor*congestfac(j)*distance(r)*shipped(r));


Like before, the domain of the indexed operation sum is the set r. But this time the domain of r has to be named explicitly, so that the parameter congestfac which is indexed only over the set j is permitted in the scope of the indexed operation. Note that this reasoning is analogous to the reasoning for filtering sets in assignments in the subsection above.

## Filtering the Domain of Definition

The rules for filtering sets that we have introduced in subsections Filtering Sets in Assignments and Filtering Controlling Indices in Indexed Operations also apply in the context of equation domains. We continue with the parcel transport example introduced above and add a binary variable bin, the parameter bigM and the equation connect to the model. Recall that shipped(i,j) is a variable and r(i,j) is a set.

Parameter        bigM(i,j) ;
Binary variable  bin(i,j) ;

Equation         connect(i,j) ;

connect(i,j) \$ r(i,j).. shipped(i,j) =l= bigM(i,j)*bin(i,j) ;


The dollar condition restricts the domain of definition of the equation connect to those label combinations of the sets i and j that are elements of the set r. The equation relates the continuous variable shipped(i,j) to the binary variable bin(i,j). Note that each domain in the equation is the index pair (i,j). So the equation may be simplified as follows:

connect(r).. shipped(r) =l= bigM(r)*bin(r) ;


In this formulation the domain of the equation is explicitly restricted to the members of the set r, without the use of a dollar condition. Note that if the right-hand side of the equation contained any term that was indexed over i or j separately, then the domain of definition of the equation would have to be simplified as:

connect(r(i,j))


The reasoning is the same as in the case of assignments and indexed operations.

GAMS Development Corp.
GAMS Software GmbH

General Information and Sales
U.S. (+1) 202 342-0180
Europe: (+49) 221 949-9170