### Table of Contents

- Three Basic Models
- Components of the Example Models
- Running a GAMS Job
- Examining The Output
- Exploiting the Algebraic Structure
- Components of the Revised Example Models
- Documenting the GAMS Code
- Guidelines on Ordering GAMS Statements and Formatting GAMS Programs
- Adding Complexity
- Advantages of Algebraic Modeling in General

GAMS (the General Algebraic Modeling System) is a high-level modeling system for mathematical programming problems. This tutorial is aimed at modelers who are new to GAMS and are looking for a quick introduction to the core features of GAMS. Note that the text contains many links to the GAMS User's Guide for further exploration. Observe that this tutorial is adapted from the Quick Start Tutorial from Bruce McCarl. Another introductory text is the tutorial A GAMS Tutorial by Richard E. Rosenthal.

# Three Basic Models

Most modelers who are interested in GAMS have one (or more) of the following backgrounds:

- They wish to solve constrained optimization problems with objective functions.
- They are looking for a system to solve general equilibrium problems that are arise in various areas of economics.
- They wish to solve nonlinear systems of equations that arise in engineering.

GAMS is well equipped to model and solve all three types of problems. We will start by introducing examples for all three areas and the discussions that will follow will refer to these three basic examples.

## First Example: Solving a Linear Programming Problem (LP)

The simplest constrained optimization problem is an LP. Assume we wish to solve the following LP that represents a simple farm model where profit is maximized:

\[ \begin{array}{ccrcrcrclcl} \max\ && 109 X_{corn} &+& 90 X_{wheat} &+& 115 X_{corn} & & & & \\ s.t. && X_{corn} &+& X_{wheat} &+& X_{cotton} & \leq & 100 & & \text{(land)} \\ && 6 X_{corn} &+& 4 X_{wheat} &+& 8 X_{cotton} & \leq & 500 & & \text{(labor)} \\ && & & & & X_{corn} & \geq & 0 & & \text{(nonnegativity)} \\ && & & & & X_{wheat} & \geq & 0 & & \text{(nonnegativity)} \\ && & & & & X_{cotton} & \geq & 0 & & \text{(nonnegativity)} \\ \end{array} \]

Note that there are three decision variables: \(X_{corn}\) denotes the land assigned to growing corn, \(X_{wheat}\) is the land assigned to growing wheat and \(X_{cotton}\) represents the land where cotton is grown. In the first line the total profit is expressed as a function of the land allotted to the three crops, the multipliers represent the expected profit per acre depending of the type of crop. The first inequality imposes a limit on the available land, the second inequality imposes a limit on the available labor and the final three lines restrict the decision variables to nonnegative values.

This problem may be expressed in GAMS as follows:

```
Positive Variables Xcorn, Xwheat, Xcotton;
Variables Z;
Equations obj, land, labor;
obj.. Z =e= 109 * Xcorn + 90 * Xwheat + 115 * Xcotton;
land.. Xcorn + Xwheat + Xcotton =l= 100;
labor.. 6 * Xcorn + 4 * Xwheat + 8 * Xcotton =l= 500;
Model farmproblem / obj, land, labor /;
solve farmproblem using LP maximizing Z;
```

We will analyze this formulation and discuss every part of it after introducing the other two basic examples.

## Second Example: Solving for an Economic Equilibrium

The simplest general equilibrium model is the single good, single market problem. Assume we wish to solve the following equilibrium problem:

\[ \begin{array}{lclclcl} \text{Demand Price:} && P &\geq& P_d &=& 6 - 0.3 Q_d \\ \text{Supply Price:} && P &\leq& P_s &=& 1 + 0.2 Q_s \\ \text{Quantity Equilibrium:} && Q_s &\geq& Q_d && \\ \text{Nonnegativity:} && P &\geq& 0 &&\\ && Q_s &\geq& 0 &&\\ && Q_d &\geq& 0 &&\\ \end{array} \]

Here \(P\) is the market clearing price, \(P_d\) is the demand curve, \(Q_d\) denotes the quantity demanded, \(P_s\) the supply curve and \(Q_s\) the quantity supplied. Note that this is a problem in 3 equations and 3 variables. The variables are \(P\), \(Q_d\), and \(Q_s\). Note that \(P_d\) and \(P_s\) are not variables, since they can be computed from the equality relations.

Usually all equality constraints are used for such a set up. However, we will use a more general setup, because it relaxes some assumptions and more accurately depicts a model ready to be implemented in GAMS. In particular, we permit the case where the supply curve price intercept may be above the demand curve price intercept and thus the market may clear with a nonzero price but a zero quantity. In addition, we allow the market price to be above the demand curve price and below the supply curve price. We also impose some additional conditions based on Walras' Law to ensure a proper solution in such cases.

\[ \begin{array}{ccc} Q_d(P - P_d) = 0 &\text{or}& Q_d(P_d - (6 - 0.3 Q_d)) = 0 \\ Q_s(P - P_s) = 0 &\text{or}& Q_s(P_s - (1 + 0.2 Q_s)) =0\\ P(Q_s -Q_d) = 0 & & \\ \end{array} \]

Here the quantity demanded is nonzero only if the market clearing price equals the demand curve price, the quantity supplied is nonzero only if the market clearing price equals the supply curve price and the market clearing price is only nonzero if \(Q_s=Q_d\).

The simplest GAMS formulation is given below. Note that we needed to rearrange the equation `Psupply`

in order to achieve a greater than inequality, thus we accomodated the requirements of the solver PATH.

```
Positive Variables P, Qd , Qs;
Equations Pdemand, Psupply, Equilibrium;
Pdemand.. P =g= 6 - 0.3*Qd;
Psupply.. ( 1 + 0.2*Qs) =g= P;
Equilibrium.. Qs =g= Qd;
Model problem / Pdemand.Qd, Psupply.Qs, Equilibrium.P /;
solve problem using MCP;
```

We will analyze this formulation and discuss every component of it after introducing the third example.

## Third Example: Solving a Nonlinear Equation System

Engineers often wish to solve a nonlinear system of equations. Examples include chemical equilibria or problems in the context of oil refining. Many other such problems of this type exist. The problem that follows is adapted from the paper Wall, T W, Greening, D, and Woolsey , R E D, "Solving Complex Chemical Equilibria Using a Geometric-Programming Based Technique" Operations Research 34, 3 (1987).

```
ba * so4 = 1
baoh / ba / oh = 4.8
hso4 / so4 / h = 0 .98
h * oh = 1
ba + 1e-7*baoh = so4 + 1e-5*hso4
2 * ba + 1e-7*baoh + 1e-2*h = 2 * so4 + 1e-5*hso4 + 1e-2*oh
```

Note that this is a nonlinear system of equations with the variables `ba`

, `so4`

, `baoh`

, `oh`

, `hso4`

and `h`

. The following formulation in GAMS is from the model [WALL] in the GAMS model library.

```
Variables ba, so4, baoh, oh, hso4, h ;
Equations r1, r2, r3, r4, b1, b2 ;
r1.. ba * so4 =e= 1 ;
r2.. baoh / ba / oh =e= 4.8 ;
r3.. hso4 / so4 / h =e= .98 ;
r4.. h * oh =e= 1 ;
b1.. ba + 1e-7*baoh =e= so4 + 1e-5*hso4 ;
b2.. 2 * ba + 1e-7*baoh + 1e-2*h =e= 2 * so4 + 1e-5*hso4 + 1e-2*oh ;
Model wall / all / ;
ba.l=1; so4.l=1; baoh.l=1; oh.l=1; hso4.l=1; h.l=1;
solve wall using nlp minimizing ba;
```

# Components of the Example Models

Now that we have our three basic models in place, we will analyze them and identify and discuss their components, including variables, equations, model definitions, solve statements and starting points.

## Variables in the Example Models

Variables in GAMS have to be declared as variables with a variable statement. The variable statements in the examples above are repeated below:

- First example:
`Positive Variables Xcorn, Xwheat, Xcotton; Variables Z;`

- Second example:
`Positive Variables P, Qd , Qs;`

- Third example:
`Variables ba, so4, baoh, oh, hso4, h ;`

Note that `variable(s)`

is a keyword in GAMS. `Positive`

is another keyword, it serves as a modifier to the keyword `variable`

and has the effect that the variables that follow may take only nonnegative values. Variables that are declared with the keyword `variable`

without a modifier are unresticted in sign. For more details on variable declarations and variable types, see sections Variable Declarations and Variable Types respectively.

Observe that GAMS is not case sensitive and allows a line feed to be used instead of a comma. Thus, the following three variable declarations are all valid and have the same effect:

```
POSITIVE VARIABLES Xcorn, Xwheat, Xcotton;
Positive Variables xcorn,
xwheat,
xcotton;
positive variables Xcorn
Xwheat , Xcotton;
```

In the GAMS formulation of the first example, we have introduced the variable `Z`

in addition to the three variables that featured in the mathematical formulation. Note that GAMS requires the optimization model

```
Maximize cx
```

to have the following form:

```
Maximize z
z = cx
```

Here `z`

is a variable, also called *objective* *variable*. Observe that it is the objective variable that is maximized, not the function `cx`

. The name of the objective variable may be chosen freely by the user, like any other variable name. The objective variable is a free variable, which means that it has no bounds. Hence, it each optimization problem there must always be at least one free variable.

Given the requirement of an objective variable in an optimization problem, we need to declare a new free variable and introduce an equation for it. In our first example we declared `Z`

as a free variable, then we declared and specified the equation `obj`

setting `Z`

equal to the objective function expression and we instructed the solver to maximize `Z`

. The relevant lines of code from the first example follow:

```
Variables Z;
Equation obj, land , labor;
obj.. Z =e= 109 * Xcorn + 90 * Xwheat + 115 * Xcotton;
solve farmproblem using LP maximizing Z;
```

- Note
- In some optimization problems users do not need to introduce a new variable to serve as an objective variable, but a free variable that already features in the model may be used. For example, in the second example above,
`ba`

is a free variable that is used as objective variable, since the model type NLP requires an objective variable. We will discuss this further below.

## Equations in the Example Models

Each equation in a model must first be *declared* with a equation declaration statement and then *defined* with a equation definition statement. We repeat the respective statement from the three examples below:

- First example:
`Equations obj, land, labor; obj.. Z =e= 109 * Xcorn + 90 * Xwheat + 115 * Xcotton; land.. Xcorn + Xwheat + Xcotton =l= 100; labor.. 6 * Xcorn + 4 * Xwheat + 8 * Xcotton =l= 500;`

- Second example:
`Equations Pdemand, Psupply, Equilibrium; Pdemand.. P =g= 6 - 0.3*Qd; Psupply.. ( 1 + 0.2*Qs) =g= P; Equilibrium.. Qs =g= Qd;`

- Third example:
`Equations r1, r2, r3, r4, b1, b2 ; r1.. ba * so4 =e= 1 ; r2.. baoh / ba / oh =e= 4.8 ; r3.. hso4 / so4 / h =e= .98 ; r4.. h * oh =e= 1 ; b1.. ba + 1e-7*baoh =e= so4 + 1e-5*hso4 ; b2.. 2 * ba + 1e-7*baoh + 1e-2*h =e= 2 * so4 + 1e-5*hso4 + 1e-2*oh ;`

Note that the equation declaration statement begins with the keyword `Equation(s)`

. Its main purpose is to name the equation(s). For further details on equation declarations, see section Declaring Equations.

The algebraic structure of the equation is specified in the equation definition statement, where the name of the equation is followed by two dots `..`

and the algebra. The relation between the left-hand side and right-hand side is specified by special symbols indicating the equation type. The most common symbols are `=e=`

for equality, `=l=`

for a less than or equal to relation and `=g=`

for a greater than or equal to relation. An overview of all GAMS equation types is given in Table Equation Types. For more information on equation definitions, see sections Defining Equations and Conditional Equations.

## Model Definitions in the Example Models

Once all structural elements of a model have been defined and specified, a model statement is used to define the model that will be solved. The model statement form the three examples follow.

- First example:
`Model farmproblem / obj, land, labor /;`

- Second example:
`Model problem / Pdemand.Qd, Psupply.Qs, Equilibrium.P /;`

- Third example:
`Model wall / all / ;`

Note that a model statement always starts with the keyword `model`

. It is follwed by the name of the model which users may choose freely and a list of the equations that are part of the model. Observe that the list of equations in the first example contains all equations that were declared and defined. However, this need not be the case. It is possible to declare and define an equation and then not use it in a model. For example, users could define several models that contain different subsets of equations. If all equations that were previously declared and defined enter the model, the keyword `all`

may be used as a shortcut, like in the third example.

- Attention
- Only equations that have been declared may be listed in a model statement. All equations in a model must have been defined before the model can be solved.

Note that equilibrium problems like the second example are solved as Mixed Complementarity Problems (MCPs). MCPs require a special variant of the model statement where not only the equations are listed , but also their complementarity relationships. The complementarity relationship between an equation and its associated variable is marked with a dot ".". Hence, in the second example, the equation `Pdemand`

is perpendicular to the the variable`Qd`

, the equation `Psupply`

is perpendicular to the variable `Qs`

and the equation `Equilibrium`

is perpendicular to the variable `P`

.

In the three model statements above the name of the model was immediately followed by the list of the equations included in the model. Observe that an optional explanatory text may be inserted after the name of the model.

## Solve Statements in the Example Models

After the model has been defined it remains to be solved, i.e. to find a solution for the variables. The solve statement directs GAMS to use a solver to optimize the model or solve the system of equations. The solve statements of the three examples follow:

- First example:
`solve farmproblem using LP maximizing Z;`

- Second example:
`solve problem using MCP;`

- Third example:
`solve wall using nlp minimizing ba;`

Note that a solve statement always begins with the keyword `solve`

follwed by the name of the model, as previously specified with a model statement, the keyword `using`

and the *type* of the model. We have an LP (linear programming problem) in the first example, an MCP (mixed compementarity problem) in the second example and an NLP (nonlinear programming program) in the third example. A complete list of GAMS model types is given in section Classification of Models. After the model type the direction of the optimization is given: either `maximizing`

as in the first example or`minimizing`

as in the third example. In the final position is the name of the objective variablethat is to be optimized.

- Note
- MCPs and systems of equations of the model type Constrained Nonlinear System (CNS) do not have objective variables. Therefore their solve statements end with the model type.

Observe that the system of nonlinear equations in the second example was expressed as an NLP that requires an objective function and a related objective variable. Actually this is an older practice in GAMS as the GAMS model type CNS was added after this example was initially formulated. Hence, we could alternatively use the following solve statement:

```
solve wall using cns;
```

However, note that the model type CNS can only be solved by select solvers and cannot incorporate integer variables. A formulation as an optimization problem relaxes these restrictions, thus allowing the use of the model type MINLP and all NLP solvers. If the model type NLP or one of its variants is chosen, one of the variables must be selected as objective variable to be optimzed. Observe that which variable is chosen may not really have any effect since a feasible solution requires all of the simultaneous equations to be solved. Thus, while in the third example the variable `ba`

is maximized, there is no inherent interest in attaining its maximum - it is just convenient.

## Starting Points

In the third example we have the following line *before* the solve statement:

```
ba.l=1; so4.l=1; baoh.l=1; oh.l=1; hso4.l=1; h.l=1;
```

Note that this line provides starting points for the variables in the model. The suffix `.l`

appended to a variable name denotes the level value of that variable. If a level value of a variable is specified before the solve statement, this value will act as a starting point for the search algorithms. The level value of a variable is one example of a *variable* *attribute*. Other examples include lower and upper bounds which may be set with the suffixes `.lo`

and `.up`

. For more information on variable attributes, see section Variable Attributes. For guidance on how to choose good starting points, see the tutorial Good NLP Formulations. Specifying starting points may be important for avoiding numerical problems in the model solution. For more on this topic, see the tutorial Finding and Fixing Execution Errors and Performance Problems.

Observe that the statetements above are the first examples of assignment statements in this tutorial. Assignment statements play a crucial role in GAMS, they are introduced in section The Assignment Statement.

# Running a GAMS Job

The model formulation of a GAMS model is saved in a text file with the extension `.gms`

, say `myfile.gms`

. Then the file is submitted to GAMS. GAMS will execute the instructions in the `.gms`

file, with the result that calculations are done, solvers are used and an output file with the solution results is created. The output file is also called the *listing* *file*. By default, the name listing file of the input file `myfile.gms`

will be `myfile.lst`

.

There are two ways to submit a job to GAMS: via the command line and via the GAMS IDE.

## Running GAMS on the Command Line

The model formulation of a GAMS model is saved in a text file with the extension `.gms`

, say `myfile.gms`

. This file may be run with GAMS using the following call:

> gams myfile

Note the extension `.gms`

may be omitted. This basic GAMS call may be extended with arguments that are called *command* *line* *parameters*. The following example serves as illustration:

> gams trnsport pw=80 ps=9999 s=mysave

Note that there are three command line parameters: the first will set the page width to 80, the seond will set the page length to 9999 and the third will have the effect that a work file named `mysave`

is saved. GAMS offers many command line parameters, they are introduced and discussed in detail in chapter The GAMS Call and Command Line Parameters.

## Running GAMS with the IDE

The GAMS **I**ntegrated **D**evelopment **E**nvironment is a graphical user interface for Windows that facilitates editing, development, debugging GAMS models and running GAMS jobs.

# Examining The Output

The output of a GAMS run is saved in the output or listing file. The listing file may contain many parts. Some parts may be suppressed by the modeler, other parts are suppressed by default and need to be activated. For an introduction and detailed discussion, see chapter GAMS Output.

In this section we will review the output that is generated by running the three example models.

## The Echo Print

The listing file always begins with the echo print. The echo print is a copy of the input file with added line numbers. For example, the echo print of the first example is given below:

1 Positive Variables Xcorn, Xwheat, Xcotton; 2 Variables Z; 3 4 Equations obj, land, labor; 5 6 obj.. Z =e= 109 * Xcorn + 90 * Xwheat + 115 * Xcotton; 7 land.. Xcorn + Xwheat + Xcotton =l= 100; 8 labor.. 6 * Xcorn + 4 * Xwheat + 8 * Xcotton =l= 500; 9 10 Model farmproblem / obj, land, labor /; 11 12 solve farmproblem using LP maximizing Z;

Note that the echo print of the other two examples follows the same principles. Note further, that the echo print serves as an important reference guide since GAMS reports the line numbers of any errors that were detected and of solve and display statements.

Observe that usually the code of even experienced GAMS modelers will contain compilation errors. They are marked in the echo print. For more information on compilation error and how to resolve them, see section Compilation Errors and the tutorial Fixing Compilation Errors.

## Model Generation Output

Once GAMS has successfully compiled the input file and any numerical computations in assignments have been performed, the solve statements will be executed. The first step is generating a computer readable version of the equations in the problem that will be passed on to an appropriate solver system. During the model generation phase GAMS creates the following output:

- A listing of the equations of the model.
- A listing of the variables of the model.
- A summary of the model structure.
- If errors were detected during model generation they will be reported as well.

### The Equation Listing

The equation listing is the first part of the output generated by a solve statement. By default, the first three equations in every block are listed. The equation listing of the first two equations of each of the three examples are given below:

- First example:
Equation Listing SOLVE farmproblem Using LP From line 12 ---- obj =E= obj.. - 109*Xcorn - 90*Xwheat - 115*Xcotton + Z =E= 0 ; (LHS = 0) ---- land =L= land.. Xcorn + Xwheat + Xcotton =L= 100 ; (LHS = 0)

- Second example:
Equation Listing SOLVE problem Using MCP From line 10 ---- Pdemand =G= Pdemand.. P + 0.3*Qd =G= 6 ; (LHS = 0, INFES = 6 ****) ---- Psupply =G= Psupply.. - P + 0.2*Qs =G= -1 ; (LHS = 0)

- Third example:
Equation Listing SOLVE wall Using NLP From line 16 ---- r1 =E= r1.. (1)*ba + (1)*so4 =E= 1 ; (LHS = 1) ---- r2 =E= r2.. - (1)*ba + (1)*baoh - (1)*oh =E= 4.8 ; (LHS = 1, INFES = 3.8 ****)

Note that the equation listing is a representation of the algebraic structure of the linear terms in the equation and a local representation containing the first derivatives of the nonlinear terms. The nonlinear terms are automatically placed in parentheses to indicate a local approximation. For further details, see section The Equation Listing in chapter GAMS Output.

### The Column Listing

The column or variable listing contains a list of the individual coefficients sorted by column rather than by row (like in the equation listing). By default, the first three entries for each variable are shown, along with their lower bound `.lo`

, upper bound `.up`

and current level values `.l`

. The column listing of the first two variables for each of the three examples are given below.

- First example:
Column Listing SOLVE farmproblem Using LP From line 12 ---- Xcorn Xcorn (.LO, .L, .UP, .M = 0, 0, +INF, 0) -109 obj 1 land 6 labor ---- Xwheat Xwheat (.LO, .L, .UP, .M = 0, 0, +INF, 0) -90 obj 1 land 4 labor

- Second example:
Column Listing SOLVE problem Using MCP From line 10 ---- P P (.LO, .L, .UP, .M = 0, 0, +INF, 0) 1 Pdemand -1 Psupply ---- Qd Qd (.LO, .L, .UP, .M = 0, 0, +INF, 0) 0.3 Pdemand -1 Equilibrium

- Third example:
Column Listing SOLVE wall Using NLP From line 16 ---- ba ba (.LO, .L, .UP, .M = -INF, 1, +INF, 0) (1) r1 (-1) r2 1 b1 2 b2 ---- so4 so4 (.LO, .L, .UP, .M = -INF, 1, +INF, 0) (1) r1 (-1) r3 -1 b1 -2 b2

### Model Statistics

The final information generated while a model is being prepared for solution, is the statistics block. Its most obvious use is to provide details on the size and nonlinearity of the model. The model statistics of the third example follow.

MODEL STATISTICS BLOCKS OF EQUATIONS 6 SINGLE EQUATIONS 6 BLOCKS OF VARIABLES 6 SINGLE VARIABLES 6 NON ZERO ELEMENTS 20 NON LINEAR N-Z 10 DERIVATIVE POOL 20 CONSTANT POOL 16 CODE LENGTH 22

For more information on model statistics, see section The Model Statistics in chapter GAMS Output.

## The Solution Report

The final major component of the listing file is the solution output. It consists of a summary, some solver-specific output and a report of the solutions for equations and variables.

### The Solve Summary

The solve summary is very important since it contains an overview of key information of the solution. The solve summary of the third example is given below.

S O L V E S U M M A R Y MODEL wall OBJECTIVE ba TYPE NLP DIRECTION MINIMIZE SOLVER CONOPT FROM LINE 16 **** SOLVER STATUS 1 Normal Completion **** MODEL STATUS 2 Locally Optimal **** OBJECTIVE VALUE 1.0000 RESOURCE USAGE, LIMIT 0.034 1000.000 ITERATION COUNT, LIMIT 7 2000000000 EVALUATION ERRORS 0 0

For details on the solve summary including possible values for `SOLVER`

`STATUS`

and `MODEL STATUS`

, see section The Solve Summary in chapter GAMS Output.

### The Solver Report

The next part of the listing file is the solver report. It contains solver specific output. The respective output of the third example follows:

CONOPT 3 24.7.3 r58181 Released Jul 11, 2016 DEG x86 64bit/MacOS X C O N O P T 3 version 3.17A Copyright (C) ARKI Consulting and Development A/S Bagsvaerdvej 246 A DK-2880 Bagsvaerd, Denmark Pre-triangular equations: 0 Post-triangular equations: 0 ** Optimal solution. There are no superbasic variables.

For more on solver reports, see section Solver Report in chapter GAMS Output.

### The Solution Listing

The solution listing is a row-by-row then column-by-column listing of the solutions returned to GAMS by the solver program. Each individual equation and variable is listed including their level and marginal values and their lower and upper bounds. The solution listing of the first example follows:

LOWER LEVEL UPPER MARGINAL ---- EQU obj . . . 1.0000 ---- EQU land -INF 100.0000 100.0000 52.0000 ---- EQU labor -INF 500.0000 500.0000 9.5000 LOWER LEVEL UPPER MARGINAL ---- VAR Xcorn . 50.0000 +INF . ---- VAR Xwheat . 50.0000 +INF . ---- VAR Xcotton . . +INF -13.0000 ---- VAR Z -INF 9950.0000 +INF .

Note that single dots '.' represent zeros. The extended range arithmetic symbols `-INF`

and `+INF`

denote minus and plus infinity respectively. `EPS`

is another extended range arithmetic symbol that often appears in solution listings. In this context, it is used to indicate basis status in the degenerate case. For example, a basic variable is indicated by a zero (single dot) marginal, while a non-basic variable whose marginal is (nearly) zero is indicated by a marginal of EPS. For further details, see section The Solution Listing in chapter GAMS Output.

# Exploiting the Algebraic Structure

GAMS was deliberately designed to make it easy to express algebraic relationships. Thus it provides notation for indexed operations like sums. Assume that \(z\) is defined as the sum over \(x_i\) where \(i = \{1,2,3\}\):

\[ z = \sum_{i=1}^{3} x_i = x_1 + x_2 + x_3 \]

This can be expressed in GAMS in the following way:

```
z = sum(i, x(i));
```

Here `i`

is a set with three elements, `z`

is a scalar or variable and `x(i)`

is a parameter or variable defined over the set `i`

. Note that the keyword `sum`

automatically cycles through all elements of the set `i`

.

Indexed operations like `sum`

may be used in the algebraic specification of equations or in the context of assignments where the value of identifiers are computed. In the following two sections we will introduce revised versions of the first two examples, where we illustrate how using `sum`

simplifies the code and enables more general formulations.

## Revised First Example

Recall that the first example is the following LP:

\[ \begin{array}{ccrcrcrclcl} \max\ && 109 X_{corn} &+& 90 X_{wheat} &+& 115 X_{corn} & & & & \\ \text{s.t.} && X_{corn} &+& X_{wheat} &+& X_{cotton} & \leq & 100 & & \text{(land)} \\ && 6 X_{corn} &+& 4 X_{wheat} &+& 8 X_{cotton} & \leq & 500 & & \text{(labor)} \\ && & & & & X_{corn} & \geq & 0 & & \text{(nonnegativity)} \\ && & & & & X_{wheat} & \geq & 0 & & \text{(nonnegativity)} \\ && & & & & X_{cotton} & \geq & 0 & & \text{(nonnegativity)} \\ \end{array} \]

Note that this is a special case of the general resource allocation problem that can be written as follows:

\[ \begin{array}{ccrclll} \max\ && \sum_j c_j X_j & & & & \\ \text{s.t.} && \sum_j a_{ij} X_j & \leq & b_i & & \text{for all} \, \, i \\ && X_j & \geq & 0 & & \text{for all} \, \, j, \\ \end{array} \]

where

- \(j = \{ \text{corn, wheat, cotton} \}\)
- \(i = \{ \text{land, labor} \}\)
- \(X_j = \{ X_{\text{corn}}, X_{\text{wheat}}, X_{\text{cotton}} \}\)
- \(c_j = \{ 109, 90, 115 \}\)
- \(a_{ij} = \left( \begin{array}{ccc} 1 & 1 & 1 \\ 6 & 4 & 8 \\ \end{array} \right)\)
- \(b_i = \{ 100, 500 \}\).

This model may be formulated in GAMS in the following way:

```
Set j / corn, wheat, cotton /
i / land, labor /;
Parameter c(j) / corn 109, wheat 90, cotton 115 /
b(i) / land 100 , labor 500 /;
Table a(i,j)
corn wheat cotton
land 1 1 1
labor 6 4 8 ;
Positive Variables x(j);
Variables profit;
Equations objective
constraint(i) ;
objective.. profit =e= sum(j, (c(j))*x(j));
constraint(i).. sum(j, a(i,j) *x(j)) =l= b(i);
Model resalloc /all/;
solve resalloc using LP maximizing profit;
```

We will discuss the components of this model in section Components of the Revised Example Models below.

## Revised Second Example

Recall that the second example is an economic equilibrium model with a single commodity:

\[ \begin{array}{lclclcl} \text{Demand Price:} && P &\geq& P_d &=& 6 - 0.3 Q_d \\ \text{Supply Price:} && P &\leq& P_s &=& 1 + 0.2 Q_s \\ \text{Quantity Equilibrium:} && Q_s &\geq& Q_d && \\ \text{Nonnegativity:} && P &\geq& 0 &&\\ && Q_s &\geq& 0 &&\\ && Q_d &\geq& 0 &&\\ \end{array} \]

A more general formulation of this model accomodates multiple commodities. Consider the following formulation where \(c\) denotes the commodities:

\[ \begin{array}{lclclclcl} \text{Demand Price for c:} && P_c &\geq& Pd_{c} &=& Id_{c} - \sum_{cc} Sd_{c,cc} Qd_{cc} && \text{for all} \, \, c \\ \text{Supply Price for c:} && P &\leq& Ps_{c} &=& Is_{c} + \sum_{cc} Ss_{c,cc} Qs_{cc} && \text{for all} \, \, c\\ \text{Quantity Equil. for c:} && Qs_{c} &\geq& Qd_{c} && && \text{for all} \, \, c \\ \text{Nonnegativity:} && P_c &\geq& 0 && && \text{for all} \, \, c\\ && Qs_{c} &\geq& 0 && && \text{for all} \, \, c\\ && Qd_{c} &\geq& 0 && && \text{for all} \, \, c,\\ \end{array} \]

where

- \(P_c \, \,\) is the price of commodity \(c\),
- \(Qd_c \, \, \) is the quantity demanded of commodity \(c\),
- \(Pd_c \, \, \) is the price from the inverse demand curve for commodity \(c\),
- \(Qs_c \, \, \) is the quantity supplied of commodity \(c\),
- \(Ps_c \, \, \) is the price from the inverse supply curve for commodity \(c\),
- \(cc \, \, \) is an alternative notation for the commodities and is equivalent to \(c\),
- \(Id_c \, \, \) is the inverse demand curve intercept for \(c\),
- \(Sd_{c,cc} \, \,\) is the slope of the inverse demand curve. It is used to model the effect of buying one unit of commodity \(cc\) on the demand price of commodity \(c\). When \(c=cc\) it is an own commodity effect and when \(c \neq cc\) it is a cross commodity effect.
- \(Is_c \, \, \) is the inverse supply curve intercept for \(c\),
- \(Ssc,cc\) is theslope of the inverse supply curve. It is used to model the effect of supplying one unit of commodity \(cc\) on the supply price of commodity \(c\). When \(c=cc\) it is an own commodity effect and when \(c \neq cc\) it is a cross commodity effect.

This model may be formulated in GAMS in the following way:

```
Set commodities / corn, wheat /;
Set curvetype / supply, demand/;
Table intercepts(curvetype,commodities)
corn wheat
demand 4 8
supply 1 2;
Table slopes(curvetype,commodities,commodities)
corn wheat
demand.corn -.3 -.1
demand.wheat -.07 -.4
supply.corn .5 .1
supply.wheat .1 .3 ;
Positive Variables P(commodities)
Qd(commodities)
Qs(commodities);
Equations PDemand(commodities)
PSupply(commodities)
Equilibrium(commodities);
Alias (cc,commodities);
Pdemand(commodities)..
P(commodities) =g= intercepts("demand",commodities)
+ sum(cc,slopes("demand",commodities,cc)*Qd(cc));
Psupply(commodities)..
intercepts("supply",commodities)
+ sum(cc,slopes("supply",commodities,cc)* Qs(cc)) =g= P(commodities);
Equilibrium(commodities)..
Qs(commodities) =g= Qd(commodities);
Model problem / Pdemand.Qd, Psupply.Qs,Equilibrium.P /;
solve problem using MCP;
```

# Components of the Revised Example Models

The revised example models have several new features including sets, specific data entry, and variables and equations that are defined over sets. In addition, if the models are run, modelers will notice some differences in the output. In this section we will discuss these new language features and the differences in the output they entail.

## Sets in the Revised Examples

In the revised examples we used the subscripts `i`

, `j`

, `commodities`

and `cc`

. In GAMS, subscripts are sets. They have to be defined before they may be used as subscripts. Sets are defind with set statements. Consider the set statement from the first revised example:

```
Set j / corn, wheat, cotton /
i / land, labor /;
```

Note that the statement begins with the keyword `set`

followed by the name of the set and a list of the elements of the set. Note further, that more than one set may be defined with one set statement. In addition, an optional explanatory text may be inserted after the name of the set and also after each set element. For more details on set definitions, see chapter Set Definition.

Observe that the following line appears in the revised second example:

```
Alias (cc,commodities);
```

This is an alias statement that introduces a new alternative name for a set that was defined earlier. In our example, the set `commodities`

was defined in the first line of the code and `cc`

is the alias, the alternative name for the set `commodities`

. Note that more than one alias may be defined in an alias statement. For further information on aliases, see section The Alias Statement: Multiple Names for a Set.

Note that in our example the alias facilitates to consider both the effects of own and cross commodity quantity on the demand and supply price for an item.

## Data Entry in the Revised Examples

GAMS provides three formats for data entry: scalars, parameters and tables. Usually scalars are defined with a scalar statement, data vectors are defined with a parameter statement and matrices are defined with a table statement.

Note that we used parameter and table statements in the revised examples. In this section we will discuss parameter and table statements. For details on scalar statements, see section Scalars.

**Parameters**

The parameter format is used to enter items defined over sets. Generally, the parameter format is used for data items that are one-dimensional (vectors), but multi-dimensional data may be entered with a parameter statement as well. Consider the parameter statement from the first revised example:

```
Parameter c(j) / corn 109, wheat 90, cotton 115 /
b(i) / land 100, labor 500 /;
```

Note that the statement begins with the keyword `parameter`

followed by the name of the parameter and the set over which the parameter is defined, the *index* or *domain*. Then a list follows where a numerical value is assigned to each member of the index set. Note that the referenced elements must have been defined to be members of the respective set. By default, elements of the domain that are not listed in the parameter statement are assigned the value of zero. Note that more than one parameter may be defined with one parameter statement. For further details on parameter statements, see section Parameters.

**Tables**

The table format is used to enter data that are dependent on two or more sets. Consider the following two table statements from the revised examples:

```
Table a(i,j) crop data
corn wheat cotton
land 1 1 1
labor 6 4 8 ;
Table intercepts(curvetype,commodities)
corn wheat
demand 4 8
supply 1 2;
```

Note that the statement begins with the keyword `table`

followed by the name of the table and the sets over which the table is defined. The next line serves as header for the columns of the table, the elements of the set in the *second* index position are listed here. The elements of the set in the *first* index position are the headers of the rows. Thus the elements of the two index positions span a grid where numerical values may be entered. Like in the parameter format, the referenced set elements must have been defined to be members of the respective set.

- Note
- Alignment is crucial in table statements. The numerical entries must be placed in one and only one column of the table.

By default, elements of the domain that are not listed in the table statement are assigned the value of zero. Note that only one table may be defined with a table statement. For further details on table statements, see section Tables. Observe that data may also be entered with assignment statements. For more information, see section Data Entry by Assignment.

## Indexed Variables and Equations in the Revised Examples

When the algebraic structure of a problem is exploited in modeling, variables and equations are often defined over one or more sets, they are *indexed*. For example, in the first revised example we have the following lines:

```
Positive Variable x(j);
Equations constraint(i);
```

Note that here the variable `x`

is defined over the set `j`

and the equation `constraint`

is indexed over the set `i`

. Similarly, in the second revised example we have the following variable and equation statements:

```
Positive Variables P(commodities)
Qd(commodities)
Qs(commodities) ;
Equations PDemand(commodities)
PSupply(commodities)
Equilibrium(commodities) ;
```

Observe that here all positive variables and all equations are indexed over the set `commodities`

. Such definitions indicate that the variables and equations are potentially defined for every element of the defining set. Thus, for example, a variable `P`

could exist for each and every element of the set `commodities`

. However, how many of these potential cases are activated is determined by the respective equation definion statement(s) where the variable `P`

is used. For further details on indexed variables and equations,see chapter Variables and section Indexed Equations respectively.

Next, we will discuss the equation definition statements. The respectives lines from the first revised example follow:

```
objective.. profit =e= sum(j, (c(j))*x(j));
constraint(i).. sum(j, a(i,j) *x(j)) =l= b(i);
```

Note that the equation `constraint`

is indexed over the set `i`

and there are no restrictions specified in the equation definition statement. Thus, GAMS will generate a separate equation for every element of the set `i`

in the model generation phase.

The same logic applies to the indexed equations of the second revised example whose definition statements are repeated below:

```
Pdemand(commodities)..
P(commodities) =g= intercepts("demand",commodities)
+ sum(cc,slopes("demand",commodities,cc)*Qd(cc));
Psupply(commodities)..
intercepts("supply",commodities) + sum(cc,slopes("supply",commodities,cc)* Qs(cc))
=g= P(commodities);
Equilibrium(commodities)..
Qs(commodities) =g= Qd(commodities);
```

Observe that equations may be defined over only a part of their domain. This restriction is usually achieved with dollar conditions. For details see section Conditional Equations.

## Differences in the Output

If variables and equations are defined over sets, some parts of the listing file will look different. In particular, there are some changes in the equation listing, the variable listing and the solution listing.

**Revised Models: The Equation Listing**

Note that indexed variables are given with their indices in the equation listing. In addition, the specific equations generated for each element of the domain are listed under the name of an indexed equation. To illustrate, we present the equation listing of the first revised example below:

---- objective =E= objective.. - 109*x(corn) - 90*x(wheat) - 115*x(cotton) + profit =E= 0 ; (LHS = 0) ---- constraint =L= constraint(land).. x(corn) + x(wheat) + x(cotton) =L= 100 ; (LHS = 0) constraint(labor).. 6*x(corn) + 4*x(wheat) + 8*x(cotton) =L= 500 ; (LHS = 0)

**Revised Models: The Column Listing**

Similar to indexed equations in the equation listing, each instance of a variable is listed under the name of an indexed variable in the variable listing. The respective output of the first revised model follows.

---- x x(corn) (.LO, .L, .UP, .M = 0, 0, +INF, 0) -109 objective 1 constraint(land) 6 constraint(labor) x(wheat) (.LO, .L, .UP, .M = 0, 0, +INF, 0) -90 objective 1 constraint(land) 4 constraint(labor) x(cotton) (.LO, .L, .UP, .M = 0, 0, +INF, 0) -115 objective 1 constraint(land) 8 constraint(labor)

**Revised Models: The Solution Listing**

In the solution listing of the revised models there is a separate line for each element of the index set. The respective output of the first revised model is given below:

---- EQU constraint LOWER LEVEL UPPER MARGINAL land -INF 100.0000 100.0000 52.0000 labor -INF 500.0000 500.0000 9.5000 ---- VAR x LOWER LEVEL UPPER MARGINAL corn . 50.0000 +INF . wheat . 50.0000 +INF . cotton . . +INF -13.0000

# Documenting the GAMS Code

We have now covered the essential GAMS features. However, any good code includes documentation, otherwise it might be useless if it is revisited after a longer time. GAMS offers three ways to document the code: comments, explanatory texts and naming.

**Comments**

There are several ways to add comments in GAMS. The most common are *single* *line* *comments* and *block* *comments*. Single line comments may be inserted on any line by placing an asterisk `*`

in the first column position. The text that follows the asterisk will be completely ignored by the GAMS compiler and may contain any content including GAMS keywords. Note that several successive lines may be single line comments. Block comments are marked with the dollar control option $ontext at the beginning of the comment block and the dollar control option $offtext at the end of the comment. Block comments usually span several lines, but they may also contain just one line on the one hand and whole sections of the code on the other hand.

In addition, users may freely enter blank lines to set off certain sections of the code and generally enhance readability. For further details on comments, see section Comments.

**Explanatory** **Text**

Declarations of sets, parameters, variables and equations may include an optional descriptive text that follows the name of the identifier. In addition, the elements of sets may be accompanied by a text. This text is more than a comment: it is retained by GAMS and is displayed whenever results are written for the respective identifier in the output file. Note that the explanatory textmay be quoted or unquoted and single or double quotes may be used, but they must match. An example is given below.For further details, see section Text.

**Naming**

Apart from avoiding reserved words, names for identifiers in GAMS may be freely chosen. Some modelers, particularly if they have a background in mathematics, prefer short names like `x(i)`

. Other modelers strongly prefer longer descriptive names that makes it easier for them to recall what quantities are denoted. In this case naming is regarded as part of the documentation. GAMS accomodates both styles and modelers may choose which style works best for them. If short names are used, we recommend to generously use descriptive texts and comments for documentation.

To illustrate the virtues of comments, blank lines, explanatory text and long names we will repeat the code of the revised LP from above and then offer an alternative, documented formulation.

```
Set j / corn, wheat, cotton /
i / land , labor /;
Parameter c(j) / corn 109, wheat 90, cotton 115 /
b(i) / land 100 , labor 500 /;
Table a(i,j)
corn wheat cotton
land 1 1 1
labor 6 4 8 ;
Positive Variables x(j);
Variables profit;
Equations objective
constraint(i) ;
objective.. profit =e= sum(j, (c(j))*x(j));
constraint(i).. sum(j, a(i,j) *x(j)) =l= b(i);
Model resalloc /all/;
solve resalloc using LP maximizing profit;
```

The documented version with longer names follows:

```
$ontext
well formatted algebraic version of the first example model
$offtext
Set products 'Items produced by farm'
/ corn 'in acres'
wheat 'in acres'
cotton 'in acres' /
resources 'Resources limiting farm production'
/ land 'in acres'
labor 'in hours' /;
Parameter netreturns(products) 'Net returns per unit produced'
/ corn 109 , wheat 90, cotton 115 /
endowments(resources) 'Amount of each resource available'
/ land 100, labor 500 /;
Table resourceusage(resources,products) 'Resource usage per unit produced'
corn wheat cotton
land 1 1 1
labor 6 4 8 ;
Positive Variables production(products) 'Number of units produced';
Variables profit 'Total sum of net returns';
Equations profitAcct 'Profit accounting equation'
available(resources) 'Resource availability limit';
$ontext
Specify definition of profit
$offtext
profitAcct..
profit
=e= sum(products, netreturns(products)*production(products));
$ontext
Limit available resources
Fix at exogenous levels
$offtext
available(resources)..
sum(products,
resourceusage(resources,products) *production(products))
=l= endowments(resources);
Model resalloc /all/;
solve resalloc using LP maximizing profit;
```

# Guidelines on Ordering GAMS Statements and Formatting GAMS Programs

A GAMS program is a collection of GAMS statements. In this section we will offer some general guidelines on ordering GAMS statements and formatting GAMS programs.

- GAMS is case insensitive. This applies to GAMS keywords as well as to user-defined names. For example, the keyword
`VARIABLE`

is identical to`Variable`

and`variable`

and the user-defined name`mincost`

is identical to`minCost`

and`minCOST`

. However, note that the spelling in the output file is determined by the spelling in the first occurence of an identifier or label. - Individual GAMS statements may be formatted in almost any style. Multiple lines may be used for a statement, blank lines may be embedded and any number of spaces or tabs may be inserted. In addition, several statements may be placed on one line. Note that they have to be separated by semicolons
`;`

. - We recommend that every GAMS statement is terminated with a semicolon
`;`

. However, note that semicolons are not manadatory if the next word is a GAMS keyword. - Identifiers like sets, parameters, scalars,tables, acronyms, variables, equations, models and files must first be
*declared*and*defined*before they may be used in the code. An identifier is named in a declaration statement and specific values are assigned to it when it is defined. Often identifiers are defined at the same time they are declared. Note that for equations the declaration and definition statements are always distinct. - The names for identifiers and labels and the explanatory text must follow certain rules. See chapter GAMS Programs and the tutorial Good Coding Practices for more information.
- Statements must be ordered such that identifiers are declared before they are used. If identifiers are used on the right-hand side of an assignment statement, they must also have been defined. If they are used in an equation and the equation is included in a model, then they must be assigned data before a solve statement for the respective model. Note that compilation errors will be triggered if this order is not followed.

# Adding Complexity

There are several GAMS features that are widely used and serve to add subtlety and compexity to models. They include exception handling through conditionals, displaying data in the output file and report writing where the information from the optimal solution is used to create reports that meet the needs of modelers and their clients.

## Conditionals

Assignments are often valid only for certain cases and sometimes equations should reasonably be restricted to a subset of the domain over which they were defined. It is easy to model such assignments and equations in GAMS with conditionals. Conditional expressions in GAMS are introduced and discussed in detail in chapter Conditional Expressions, Assignments and Equations. In this section we will only give a quick overview to demonstrate the capabilities of conditionals in GAMS.

Note that the dollar condition is at the heart of conditionals in GAMS. The general form of a conditional expression is as follows:

```
term $ logical_condition
```

This translates to: "Do something with 'term' only if the logical condition is true." Observe that `term`

may be a number, a set, a parameter, a variable or an equation. The dollar operator `$`

is a GAMS speciality and one of the most powerful features of GAMS. The logical condition may take many different forms, see section Logical Conditions for details.

The following examples illustrate how conditionals in GAMS may be used.

**Conditional** **Assignments**

Consider the following example:

```
x $ (y > 0) = 10;
```

Note that `x`

is assigned the value of ten only if the the scalar `y`

is greater than zero, otherwise no assignment is made and `x`

keeps its previous value. For more information, see section Conditional Assignments.

**Conditional Indexed Operations**

Consider the following example:

```
z = sum[i $ (y(i) <> 0), x(i)];
```

Note that the term `x(i)`

will only be included in the sum if `y(i)`

is nonzero. For further information, see section Conditional Indexed Operations.

**Conditionals in the Domain of Definition of Equations**

Consider the following equation definition statements:

```
Eq1 $ (qq > 0).. xvar =e= 3;
Eq2 $ (sum(i, q(i)) > 0).. yvar =l= 4;
Eq3(i) $ (a(i) > 0).. ivar(i) =g= -a(i);
```

Note that in each equation the domain of definition is restricted to those cases where the logical condition evaluates to `TRUE`

. For further details, see section Dollar Control over the Domain of Definition.

**Conditionals in the Algebraic Formulation of Equations**

Our last example illustrates how a dollar condition may be used in the body of an equation:

```
Eq4 . . xvar + yvar $ (qq > 0) =e= 3;
```

Note that the term `yvar`

is included in the equation only if `qq`

is greater than zero, otherwise `yvar`

is treated as if it were zero. For more information, see section Dollar Operators within the Algebra of Equations.

## Displaying Data

In GAMS, the display statement is a quick way to write data into the output file. For example, assume we add the following statement after the solve statement in the revised and documented version of the farm linear programming model above:

```
display profit.l, production.l;
```

Recall that `profit`

and `production`

are variables. The suffix `.l`

indicates that we wish to display the variable attribute `level`

. The following output will be generated in the listing file:

---- 47 VARIABLE profit.L = 9950.000 Total sum of net returns ---- 47 VARIABLE production.L Number of units produced corn 50.000, wheat 50.000

Observe that the name of the variable, the explanatory text and the respective numerical values are given. In addition to data like parameters, sets, variable attributes, equation attributes and model attributes, quoted text may be displayed. Note that numerical entries that equal zero will not be displayed. For a more detailed introduction, see chapter The Display Statement.

## Report Writing

In many cases modelers wish to summarize the most important results of the solution in a table for a quick overview. GAMS allows post-solution computations where information form the solution may be used to assign values to new parameters that are then displayed. The information from the solution most often used for report writing includes the level values of variables and equations and the marginal values of equations (also called *dual* *values* or *shadow* *prices*). Note that variable and equation attributes are accessed as follows:

```
var_name.sfx
eqn_name.sfx
```

Here `var_name`

and `eqn_name`

is the name of the variable and equation in GAMS respectively. The *attribute* is denoted by `.sfx`

, where `sfx`

may be `l`

for level and `m`

for marginal. Note that the suffix `sfx`

may take other values as well. For details see sections Variable Attributes and Equation Attributes.

Observe that the numerical values of the levels and marginals of variables and equations are generally undefined until a solve statement is executed. After GAMS has retrieved the solution from the solver, the respective values from the solution are assigned to the attributes. These values remain unchanged until the next solve, where they are replaced with the values from the most recent solution.

In the remainder of this section we will present two examples to illustrate report writing. Assume we add the following report writing sequence after the solve statement to the revised and documented version of the farm linear programming model above:

```
Set item / Total, "Use by", Marginal /;
Set qitem / Available, Corn, Wheat, Cotton, Value /;
Parameter Thisreport(resources,item,qitem) 'Report on resources';
Thisreport(resources,"Total","Available") = endowments(resources);
Thisreport(resources,"Use by",qitem) =
sum(products$sameas(products,qitem),
resourceusage(resources,products) * production.l(products));
Thisreport(resources,"Marginal","Value") =
available.m(resources);
option thisreport:2:1:2;
display thisreport;
```

Note that both, equation marginals (`available.m(resources)`

) and variable levels (`production.l(products)`

) are included in the calculations. The function sameas in the logical condition above returns the value `TRUE`

if the element of the set `products`

is equivalent to the element of the set `qitem`

and `FALSE`

otherwise. Thus this condition ensures that the third index of the parameter `Thisreport`

is identical to the element of the set `products`

in the sum. Observe that with the option statement in the penultimate line the appearance of the display is customized. For details see section Local Display Control. The following report will be generated by the display statement:

---- 61 PARAMETER Thisreport Report on resources Total Use by Use by Marginal Available corn wheat Value land 100.00 50.00 50.00 52.00 labor 500.00 300.00 200.00 9.50

Similarly, we could add the following report writing sequence to the revised version of the equilibrium model above:

```
Set qitem / Demand, Supply, "Market Clearing" /;
Set item / Quantity, Price /;
Parameter myreport(qitem,item,commodities);
myreport("Demand","Quantity",commodities) = Qd.l(commodities);
myreport("Supply","Quantity",commodities) = Qs.l(commodities);
myreport("Market Clearing","Price",commodities) = P.l(commodities);
display myreport;
```

Note that in the new parameter the level values for supply and demand as well as the market clearing price are saved. The resulting report follows:

---- 39 PARAMETER myreport Corn Wheat Supply .Quantity 1.711 8.156 Demand .Quantity 1.711 8.156 Market Clearing.Price 2.671 4.618

For more on report writing, see chapters The Display Statement and The Put Writing Facility.

# Advantages of Algebraic Modeling in General

We will conclude this tutorial with a discussion of the advantages of using algebraic modeling in general.

Algebraic modeling languages like GAMS facilitate model formulations in general algebaric terms, that are very concise and readable. Language elements that are essential include sets that may serve as indices, algebraic expressions, indexed operations, powerful sparse index and data handling variables and constraints with user-defined names. Model formulations are largely independent of the data and exact application contexts. Such formulations may be easily transferred to different contexts, data may be added without the need to reformulate the model and the model may be extended to reflect additional complexity.

However, GAMS algebraic requirements and the summation notation are difficult for some users. Some modelers will always prefer the exact problem context, not an abstract general formulation. This may lead to a strategy most modelers use: Start with a small concrete formulations that capture the essence of the problem and support the development of more general GAMS models.

## One Model - Different Contexts

In the linear programming problem above we modeled profit maximizing in a farm. This model may easily be transferred to another context as follows:

```
Set products 'Items produced'
/ Chairs, Tables, Dressers /
resources 'Resources limiting production'
/ RawWood, Labor, WarehouseSpace /;
Parameter Netreturns(products) 'Net returns per unit produced'
/ Chairs 19, Tables 50, Dressers 75 /
Endowments(resources) 'Amount of each resource available'
/ RawWood 700, Labor 1000, WarehouseSpace 240 /;
Table Resourceusage(resources,products) 'Resource usage per unit produced'
Chairs Tables Dressers
RawWood 8 20 32
Labor 12 32 45
WarehouseSpace 4 12 10 ;
Positive Variables Production(products) 'Number of units produced';
Variables Profit 'Total sum of net returns' ;
Equations ProfitAcct 'Profit accounting equation '
Available(resources) 'Resource availability limit';
ProfitAcct..
Profit
=e= sum(products, netreturns(products) * production(products)) ;
Available(resources)..
sum(products,
resourceusage(resources,products) * production(products))
=l= endowments(resources);
Model resalloc /all/;
solve reasalloc using LP maximizing Profit;
```

Note that in this model we have chairs, tables and dressers instead of corn, wheat and cotton and raw wood, labor and warehouse space instead of land and labor, but the *algebraic* *structure* of the model is the same. Thus we still have sets for products and resources, parameters for net returns per unit produced and available resources, a table for resource usage per unit produced and exactly the same variables and equations, the same model and solve statement. Hence, if the algebraic structure for a type of problem is built, it may be used in another context of the same problem type with just minor modifications in the data.

## Adding More Data

It is easy to add more data to a model. For example, we could add two new products and two new resources to the carpenter model above in the following way:

```
Set products 'Items produced'
/ Chairs, Tables, Dressers, HeadBoards, Cabinets /
resources 'Resources limiting production'
/ RawWood, Labor, WarehouseSpace, Hardware, ShopTime /;
Parameter Netreturns(products) 'Net returns per unit produced'
/ Chairs 19, Tables 50, Dressers 75, HeadBoards 28, Cabinets 25 /
Endowments(resources) 'Amount of each resource available'
/ RawWood 700, Labor 1000, WarehouseSpace 240, Hardware 100, Shoptime 600 /;
Table Resourceusage(resources,products) 'Resource usage per unit produced'
Chairs Tables Dressers HeadBoards Cabinets
RawWood 8 20 32 22 15
Labor 12 32 45 12 18
WarehouseSpace 4 12 10 3 7
Hardware 1 1 3 0 2
Shoptime 6 8 30 5 12;
Positive Variables Production(products) 'Number of units produced';
Variables Profit 'Total sum of net returns' ;
Equations ProfitAcct 'Profit accounting equation'
Available(resources) 'Resource availability limit';
ProfitAcct..
Pofit
=e= sum(products, netreturns(products) * production(products)) ;
Available(resources)..
sum(products,
resourceusage(resources,products) * production(products))
=l= endowments(resources);
Model resalloc /all/;
solve reasalloc using LP maximizing Profit;
```

Observe that the elements `HeadBoards`

and `Cabinets`

were added to the set `Products`

and the elements `Hardware`

and `ShopTime`

were added to the set `Resources`

. In addition, the data in the two parameters and the table was updated to reflect these new labels. However, the model structure remained unchanged. Thus, GAMS models may easily be extended from smaller to larger data sets. Note that this feature may be exploited for model development. Users may develop a model with a small data set and test and debug it. Afterwards, they may move to the full problem data set without having to alter the algebraic structure of the model.For more details on this strategy, see section Small to Large: Aid in Development and Debugging.

## Extending the Model

Assume we wish to make a model more complex by adding new features. For example, we could extend the carpenter model above to reflect the possibility of renting or hiring additional resources subject to a maximum limit. Consider the following code:

```
Set products 'Items produced'
/ Chairs, Tables, Dressers /
resources 'Resources limiting production'
/ RawWood, Labor, WarehouseSpace/
hireterms 'Resource hiring terms'
/ Cost, Maxavailable /;
Parameter Netreturns(products) 'Net returns per unit produced'
/ Chairs 19, Tables 50, Dressers 75 /
Endowments(resources) 'Amount of each resource available'
/ RawWood 700, Labor 1000, WarehouseSpace 240 /;
Table Resourceusage(resources,products) 'Resource usage per unit produced'
Chairs Tables Dressers
RawWood 8 20 32
Labor 12 32 45
WarehouseSpace 4 12 10 ;
Table Hiredata(resources,hireterms) 'Resource hiring data'
Cost Maxavailable
RawWood 3 200
Labor 12 120
WarehouseSpace 4 112;
Positive Variables Production(products) 'Number of units produced'
HireResource(resources) 'Resources hired';
Variables Profit 'Total sum of net returns' ;
Equations ProfitAcct 'Profit accounting equation'
Available(resources) 'Resource availability limit'
Hirelimit(resources) 'Resource hiring limit';
ProfitAcct..
Profit
=e= sum(products, Netreturns(products) * Production(products))
- sum(resources, Hiredata(resources,"cost") * HireResource(resources)) ;
Available(resources)..
sum(products,
Resourceusage(resources,products) * Production(products))
=l= Endowments(resources) + HireResource(resources);
Hirelimit(resources)..
HireResource(resources) =l= Hiredata(resources,"Maxavailable");
Model resalloc /all/;
solve reasalloc using LP maximizing Profit;
```

Observe that we introduced the set `hireterms`

, the table `Hiredata`

, the positive variable `HireResource`

and the equation `Hirelimit`

. In addition, we included new terms in the equations `Profit`

and `Available`

to reflect that through hiring the resources are increased, but hiring comes with a cost diminishing the profit. Thus the algebraic structure of the earlier model could be used as the core for this model that has additional features.

Note that this method may also be exploited for model development. Users may adapt models from other studies customizing them for the problem at hand and thus speeding up the development process. In addition to adapting models from related earlier studies that were done by the modeler or his group, model development may be jumpstarted by adapting models from the extensive GAMS Model Library.