Table of Contents
- Introduction
- The Syntax
- A First Example
- Put Files
- Put File Pages
- Output Items
- The Put_Utility Statement
- Conditional Put Statements
- Errors Associated with Put Statements
- Creating a Report for the Model MEXSS
Introduction
While the GDX facility is widely used to exchange bulk GAMS data with other programs the put writing facility allows to generate sophisticated reports in GAMS. The result are external ASCII files that are structured using information that is stored by the GAMS system. The put writing facility offers users numerous ways to control three format layers: the format of the external file that is written to, the format of the pages of the external files and the format of output items. Hence the structure of the put writing facility is more complex and requires more programming than the display statement, but there is much more flexibility and control over the output. The put writing facility generates external files automatically when the GAMS program is executed. The files are written sequentially, a single page at a time. The current page is stored in a buffer, which is automatically written to an external file when the page is full. Thus, the put writing facility has only control over the current page and does not have the ability to go back to alter former pages. However, while a particular page is current, information placed on it may be overwritten or removed at will.
This chapter is organized as follows. We will first introduce the file statement and the put statement, which are at the core of the put writing facility. Then we will present a simple example that will serve as illustration. We will also introduce some widely used features as we comment on the example. The remainder on the chapter will cover in detail the external report files, also called put files, the structure of put file pages and ways to control their format, types of output items and their formatting controls, and the put_utility statement, a variant of the put statement that allows to special communication of formatted elements with the outside world. In addition, we will briefly discuss exception handling in the context of put statements and GAMS errors that are specific to put statements. We will conclude the chapter with an elaborate example. Note that put file attributes play a crucial role, since they are used for most formatting controls. A complete list of all file attributes is given in section Put File Attributes.
The Syntax
The basic structure of the put writing facility in its simplest form is as follows:
File file_name {,file_name};
put file_name;
put item {,item};
Note that the first line is a file statement. File statements define one or more external files that will be written to and specify internal names for them. These internal names wil be used in the GAMS model to reference the external files when they are written to. The second line is a put statement that assigns the file with the name file_name
as the current file. The third line is a put statement that writes one or more items to the current file. Items are any type of output like explanatory text, set labels, parameters, and variable, equation values and model attributes.
Next, we will present more details on the file statement and the put statement in the following two subsections and then we will turn to a first example that will illustrate how the the put writing facility works.
The File Statement: Defining Put Files
External files that are written to with the put writing facility are called put files. They are defined with a file statement. The syntax for a file statement is as follows:
File[s] file_name ["text"] [external_file_name] {,file_name ["text"] [external_file_name] } ;
The keyword file
or files
indicates that this is a file statement. It is follwed by the internal name for the put file, file_name
. The internal file name is a handle for the put file, it is used in the GAMS model to refer to the put file. The optional explanatory text may be used to describe the put file for future reference and to ease readability. The final part of the file statement is the actual name of the put file. Naming the external file is optional. In case it is omitted, by default, GAMS will create a name by appending the extension .put
to the internal name. Consider the following example:
File results;
Note that in this statement no external file name is specified. Thus GAMS will create the external file results.put
in the current working directory. Observe that by default, all put files are stored in the current working directory. There are several ways to specify alternative directories for put files. For details see section Choosing Where Put Files are Saved below.
- Note
- Multiple put files may defined with one file statement.
Consider the following example:
File class1
class2 "this defines a specific external file" /report.txt/
log "this defines access to the GAMS log file" /''/;
Observe that the internal name of the first file is class1
. As no external name is specified, GAMS will assign the absolute name class1.put
to this file. The second file will be referenced in the model with the name class2
and it corresponds to the external file report.txt
. The third file is special: the internal name ''
is reserved for writing output to the GAMS log. Note that writing to the GAMS log can be useful to monitor how the solution process of the model is progressing.
For further details on put files, see section Put Files below.
The Put Statement
The put statement is at the core of the put writing facility. It has two different functions: it specifies which of the previously defined put files is the current file and it writes output to that file. The syntax for the first function is simple:
put file_name;
The keyword put
indicates that this is a put statement, file_name
is the internal name of a put file that was previously defined with a file statement. This put statement has the effect that the specified file is now ready to be written to. Note that this put statement is necessary even if only one put file has been previously defined. For an example of how it is used when output is written to several different files, see the next section.
The basic syntax for a put statement that is used to write output to a file is as follows:
put item {,item};
The statement begins with the keyword put
followed by one or more items. Items may be a text (like a quoted text, an explanatory text, the name of a set element), a numerical value (like the value of a parameter, the value of an attribute, the solution status of the model) or a set value (YES
or NO
indicating whether a label is an element of a specific set). These items are discussed in detail in section Output Items below. In addition, GAMS facilitates writing a text block to a put file and including the content of an external file in a put file. For details see sections Text Items: Text Blocks and The Put_Utility Statement respectively.
Note that it is also allowed to use only one put statement to assign one file as the current file and write to it. The syntax follows:
put file_name item {,item};
In addition, it is permitted to use just one put statement to write to multiple files sequentially. Thus the most general form of a put statement is as follows:
put file_name item {,item} {,file_name item {,item}};
Note that only one file is current at a time. When a file is current, the output items following the name of this file will be written to the file. After this has been completed, the current file is reassigned to the next internal file name in the statement. The last internal file name used in a put statement continues to be the current file until a subsequent put statement uses an internal file name.
Observe that the keyword put
has several variants: putclose, puttl, puthd, putpage and put_utility.
A First Example
We will use a small example to introduce the basic features of the put writing facility. The example is based on the well-known transportation model [TRNSPORT]. The following code segment could be placed at the end of the transportation model to create a report:
File factors /factors.dat/,
results /results.dat/;
put factors;
put 'Transportation Model Factors' / /
'Freight cost ', f,
@1#6, 'Plant capacity'/;
loop(i, put @3, i.tl, @15, a(i)/);
put /'Market demand'/;
loop(j, put @3, j.tl, @15, b(j)/);
put results;
put 'Transportation Model Results' / / ;
loop((i,j), put i.tl, @12, j.tl, @24, x.l(i,j):8:4 /);
In the first line, the file statement defines the internal file names factors
and results
and connects them to the external files factors.dat
and results.dat
respectively. These internal file names are used inside the model to reference files which are external to the model.
In the second line, the put statement assigns the file factors
as the current file, that is the file which is currently available to be written to.
In the third line, the put statement starts the actual writing to the put file. The first item that is written is the quoted text string 'Transportation Model Factors'
. The item is followed by two slashes. A slash instructs the cursor to move to the first column of the next line. Two slashes have the effect that the cursor is moved to the first column of the second line, thus introducing a blank line.
- Attention
- Two slashes
//
are a popular end of line comment character sequence. So an intended blank line can result in a comment in the GAMS code. A safe way to use slashes in put statement is to separate the slashes by a space.
The next item is the string 'Freight cost '
followed by the value of the scalar f
. Note that these output items are separated by commas. Blanks and commas serve as delimiters for separating different output items. These delimiters leave the cursor at the next column position in the file following the last item written. In most cases, a blank and a comma may be used interchangeably. However, the comma is the stronger form and will eliminate any ambiguities.
In the fifth line, the code above starts with the instruction @1#6
. In the context of put statements, the symbols @
and #
serve to reposition the cursor to a specific column and row respectively. Thus in our case, the cursor is repositioned to column 1 of row 6 of the put file. Then another text string is written and a new line is started. The semicolon terminates the put statement. More details on cursor positioning are given in section Controlling the Cursor On a Page.
In line 6, the next put statement is embedded within a loop statement. Note that the set i
is the looping set. The put statement writes at column position 3 the set label name and at column position 15 the value of the parameter a(i)
for each element of the set i
. Observe that set element labels are referenced with the name of the set and the suffix .te
. For more information on identifier suffixes, see section Text Items below. Note that the put statement has to be placed within a looping structure, since only one element of the index set may be written with a put statement.
In line 7, the first symbol after the keyword put
is a slash, that has the effect that a blank line is inserted before the text string 'Market demand'
is written.
In line 8, we have again a put statement within a loop structure: the values of the parameter b
are written in a similar way to those of parameter a
in line 6.
After execution, the put file factors.dat
will look as follows:
Transportation Model Factors Freight cost 90.00 Plant capacity Seattle 350.00 San-Diego 600.00 Market demand New-York 325.00 Chicago 300.00 Topeka 275.00
Note that this output has been formatted using the default file format values. GAMS offers several ways to customize the format, see sections Global Item Formatting Controls and Local Item Formatting Controls below for further information.
In the last three lines of the code above, the file results.dat
is made current and the level values associated with the variable x
along with their corresponding set element index labels are written line by line. Note that the format of the output results of the variable x
is customized by specifying a field width of 8 spaces with 4 of these spaces reserved for decimal places. This is an example of local formatting. The put file results.dat
will contain the following lines:
Transportation Model Results Seattle New-York 50.0000 Seattle Chicago 300.0000 Seattle Topeka 0.0000 San-Diego New-York 275.0000 San-Diego Chicago 0.0000 San-Diego Topeka 275.0000
This small example has demonstrated the main features of the put writing facility. However, its surface has just barely been scratched. In the remainder of this chapter we will describe in detail the many features of the put writing facility. Observe that in section Creating a Report for the Model MEXSS at the end of this chapter we will present a more elaborate report.
Put Files
As mentuioned earlier, external files that are written to with the put writing facility are called put files. They are defined with a file statement and are made current with a put statement. Once they are current, they may be written to. By default, put files are saved in the current working directory. In this section we will cover more details on put files. We will discuss ways to specify other directories for put files, introduce the putclose statement, a variant of the put statement that closes the current file, and we will show how to append to an existing external file instead of replacing (overwriting) it. In addition, we will introduce the notion of put file attributes including a list of all attributes.
Choosing Where Put Files are Saved
Recall that by default, put files are saved in the current working directory. GAMS offers several ways to specify other directories for put files. The easiest way to specify another directory is by including the absolute or relative path in the file statement. Consider the following example:
File report / C:\Documents\GAMS\Output\report.dat /;
Note that the put file report.dat
with the internal name report
will be stored in the directory specified in the file statement instead of the current working directory.
An alternative directory for all put files in a model may be specified with the command line parameter PutDir. Assume we wish to write some ouput from running the well-known transportation model [TRNSPORT] to the file results
defined above. Consider the following GAMS call:
> gams trnsport PutDir=c:\output
Note that the file results.put
will be stored in the directory specified in the GAMS call. Observe that storing put files in the directory specified with PutDir
is applies to all file that are not specified via an absolute file name. For more information on command line parameters, see chapter The GAMS Call and Command Line Parameters. scratchdir as putdir option (.pdir
) lets GAMS write put files into the scratch directory.
The content of a put file will be sent to the GAMS log file if the put file is specified in the following way:
File name / '' /;
For example, the following code snippet may be added to the transportation model [TRNSPORT]:
File name / '' /;
put name ;
put 'instructions that will go to the GAMS log' /;
put 'more instructions that will go to the GAMS log' /
As a result, the respective GAMS log will contain the following lines:
... instructions that will go to the log file more instructions that will go to the log file *** Status: Normal completion --- Job trnsport.gms Stop 01/25/17 15:46:09 elapsed 0:00:00.320
The Putclose Statement: Closing a Put File
Recall that the file statement and the put statement are at the core of the put writing facility. The putclose statement is a variant of the put statement, it is used to close a put file. The syntax is as follows:
putclose [file_name] {item} {file_name item {item}};
If the file_name
is missing, putclose
will close the current file. Often the putclose statement is used in this simple form. Consider the following example:
File report;
put report;
put "This is a report."
putclose;
Note that the last line has the effect that the file report.put
is closed. The file may be used again later. As usual, it has to be assigned as the current file and then it may be written to. By default, an existing file is overwritten (replaced). Alternatively, it may be appended to. For details see section Writing to an Existing Put File below. The briefest version of the above code is
File report; putclose report "This is a report."
Closing a put file is useful for example when writing a solver option file from within the GAMS model. Consider the following example, where we will create and close an option file for the solver MINOS.
File opt 'Minos option file' / minos.opt /;
put opt 'Iteration limit 500'/
'Feasibility tolerance 1.0E-7'/ ;
putclose opt;
Note that the file minos.opt
is closed with a simple putclose statement. This will make the file available to be used by the solver. Observe that the code snippet above has to be placed before the respective solve statement.
Now, the last three lines in the example above may be reduced to two lines in the following way:
putclose opt 'Iteration limit 500'/
'Feasibility tolerance 1.0E-7'/ ;
In this formulation, the putclose statement makes the file minos.opt
current, writes to it and then closes the file after the last item has been written. Even though this is shorter, many users prefer the first formulation, since it is clearer.
Similarly to the put statement, the putclose statement may also be used to write to several files subsequently. The only difference to the put statement is, that the last current file will be closed after is has been written to.
Observe that GAMS automatically closes the put files of a model when it exits, even without a putclose statement.
Writing to an Existing Put File
When the put writing facility is used to write to a file that is not empty, by default, the existing content is overwritten (replaced). However, GAMS provides the option to append to the file instead via the file attribute append option (.ap
). Consider the following example:
File append /append.dat/
put append;
put "This is the first line." /;
putclose;
append.ap = 1;
put append;
put "This is the second line.";
Note that the putclose statement in line 4 closes the file append.dat
. The assignment in the next line instructs the put writing facility to append to the file if the file is opened again and written to. Thus the following output is generated:
This is the first line. This is the second line
For information on file attributes in general, see section Put File Attributes below.
Put File Attributes
Put files have attributes that are mainly used to customize the format of put files, put file pages and output items. Put file attributes are accessed in the
following way:
file_name.attribute
Here file_name
is the internal name of the put file and .attribute
is the specific attribute that is to be accessed. We can also access the specific attribute of the current file by file.attribute
. This useful in particular in batincludes that are used for multiple put files. Put file attributes may be used on the left-hand side and right-hand side of assignments. Consider the following example:
factors.nw = 10;
scalar x; x = factors.nw;
In the first line, the attribute numeric field width (.nw
) of the put file with the internal name factors
is assigned the value of 10. In the second line, the value of the attribute .nw
is assigned to a scalar parameter x
. In addition, put file attributes may be used as output items. For an example, see section Controlling the Cursor with File Attributes below. A complete list of put file attributes is given in Table 1.
Put File Attribute | Symbol | Description | Default Value | Optional Values |
---|---|---|---|---|
Append option | .ap | Allows to append to an existing file, instead of replacing (overwriting) it. For more information, see section Writing to an Existing Put File. | 0 | 0: Overwrite 1: Append |
Bottom margin | .bm | Number of blank lines to be placed in the bottom margin of the page. The bottom margin lines are in adition to the lines specified with the file attribute page size (.ps ). Note that this attribute is functional only if the value of the suffix print control (.pc ) is zero. | 0 | |
Alphabetic case | .case | Specifies the case in which alphabetic characters are displayed in the put file, regardless of the input. Note that the meaning of 1 and 2 differs from the one for lcase. | 0 | 0: Mixed case 1: Upper case 2: Lower case |
Current column | .cc | This attribute may be used to return or set the current cursor column in the main window. For more information, see Current Cursor Column. | 0 | Value may be between 1 and the page width. |
Current row | .cr | This attribute may be used to return or set the current cursor row in the main window. For more information, see Current Cursor Row. | 1 | Value may be between 1 and the page size minus any header rows, title rows and margins. |
Number of put errors | .errors | See section Put Errors for details and an example. | 0 | |
Header current column | .hdcc | This attribute may be used to return or set the current cursor column in the header block. For more information, see Current Cursor Column. | 0 | Value may be between 1 and the page width. |
Header current row | .hdcr | This attribute may be used to return or set the current cursor row in the header block. For more information, see Current Cursor Row. | 1 | Value may be between 1 and the size of the header. |
Header last line | .hdll | This attribute may be used to return the number of the last line of the page header or reset the last row written in the page header. For more information, see Last Line Control. | 0 | |
Alphabetic label case | .lcase | Specifies the case in which alphabetic characters of a label are displayed in the put file, regardless of the original casing. | 0 | 0: Mixed case 1: Lower case 2: Upper case |
Label justification | .lj | Alignment of set labels. | 2 | 1: Right, 2: Left, 3: Center |
Last line | .ll | This attribute may be used to return the number of the last line of the main window or reset the last row written in the main window. For more information, see Last Line Control. | 0 | |
Left margin | .lm | Number of empty columns to be placed on the left of the page. | 0 | |
Last page | .lp | Returns the number of pages that are already in the put file. Note that setting this attribute to zero does not delete the pages that have been written to the file. | ||
Label field width | .lw | Field width of set label output. For more information, see section Global Item Formatting Controls. | 12 | Values may be 0 or larger. |
Number of decimals | .nd | Sets the number of decimals that are displayed for numeric items. A value of zero entails that fixed-format output will show the number rounded to the nearest integer. For an example, see section Global Item Formatting Controls. | 2 | Values may be between 0 and 20. |
Numeric justification | .nj | Alignment of numeric output. | 1 | 1: Right, 2: Left, 3: Center |
Numeric round format | .nr | Selects the formatting used for numeric output. For example, one can choose to use scientific notation (i.e. E-format) for all numbers: this is especially useful for numbers so small that they display as only zeros in fixed format with the specified suffix number of decimals (.nd ). For more information and an example, see section Global Item Formatting Controls. | 1 | 0: Item is displayed in F or E format to fit given width and decimals. 1: Item is rounded to fit given width and decimals. 2: Item is displayed in E format to fit given width and decimals. 3: Item is rounded to fit given width. 4: Item is displayed in F or E format to fit given width. |
Numeric field width | .nw | Field width of numeric output. For more information, see section Global Item Formatting Controls. | 12 | Values may be 0 or larger. |
Numeric zero tolerance | .nz | Sets the tolerance level for which a number will be rounded to zero for display purposes. Note that in case this attribute is set to zero, rounding will be determined by the field width. | 1.0e-10 | |
PutDir becomes scratch directory | .pdir | Setting this to nonzero will result in resetting the PutDir to the scratch directory. Since the scratch directory is unknown while parameters are provided, this allows to use the scratch directory as PutDir . | 0 | |
Print control | .pc | Specifies the format of the put file. The options 4, 5, 6 and 8 create delimited files, which are especially useful when preparing output for the direct importation into other computer programs such as spreadsheets. For an example, see section Creating a Report for the Model MEXSS. | 2 | 0: Standard paging based on the current page size. Partial pages are padded with blank lines. Note that the file suffix bottom margin (.bm ) is only functional when used with this print control option. 1: FORTRAN page format. This option places the numeral one in the first column of the first row of each page in the standard FORTRAN convention. 2: Continuous page. This option is similar to .pc option zero, with the exception that partial pages in the file are not padded with blank lines to fill out the page. 3: ASCII page control characters inserted. 4: Formatted output; non-numeric output is quoted and each item is delimited with a blank space. 5: Formatted output; non-numeric output is quoted and each item is delimited with commas. 6: Formatted output; non-numeric output is quoted and each item is delimited with tabs. 7: Fixed width, fills up line with trailing blanks. 8: Formatted output; each item is delimited with a blank space. |
Page size | .ps | Number of rows (lines) that may be placed on a page of the put file. It may be reset by the user at any place in the program.Observe that the specification of this attribute is only effective if the attribute print control (.pc ) has a value other than its default value. Note that a put error will result if it is set to value that is smaller than the number of rows which have already been written to the current page. | 60 | Any value between 1 and 130. |
Page width | .pw | Number of columns (characters) that may be placed on a single row of the page. It may be reset by the user at any place in the program. Note that a put error will result if it is set to value that is smaller than the number of columns which have already been written to the current page. Observe that if a value is specified that is above the upper limit, then the value will be reset to the upper limit. | 32767 | Any value between 1 and 32767. |
Set value justification | .sj | Alignment of set values. | 1 | 1: Right, 2: Left, 3: Center |
Set value field width | .sw | Field width of set values. For more information, see section Global Item Formatting Controls. | 12 | Values may be between 0 and 20. |
Text fill | .tf | Controls what content will be displayed, if there is no explanatory text for a set element, but a text item with suffix .te was specified. Note that options 4, 5 and 6 are useful if the output is intended to be included in a GAMS model at a later time. | 2 | 0: Blanks are displayed. 1: Blanks will be displayed if the specified element does not exist, otherwise the name of the element will be displayed. 2: The name of the element is displayed. 3: The name of the element is displayed even if an explanatory text exists. 4: Like option 3, but displays output in quotes with comma separators. 5: Like option 4, but with periods as separators. 6: Like option 4, but with blanks as separators. |
Text justification | .tj | Alignment of quoted text and explanatory text. | 2 | 1: Right, 2: Left, 3: Center |
Title current column | .tlcc | This attribute may be used to return or set the current cursor column in the title block. For more information, see Current Cursor Column. | 0 | Value may be between 1 and the page width. |
Title current row | .tlcr | This attribute may be used to return or set the current cursor row in the title block. For more information, see Current Cursor Row. | 1 | Value may be between 1 and the size of the header. |
Title last line | .tlll | This attribute may be used to return the number of the last line of the page title or reset the last row written in the page title. For more information, see Last Line Control. | 0 | |
Top margin | .tm | Number of blank lines to be placed at the top margin of the page. These lines are in addition to the number of lines specified with the file attribute page size (.ps ). | 0 | |
Text field width | .tw | Field width for quoted text and explanatory text. Note that a value of zero forces the field width to match the exact size of the item being displayed. For more information, see section Global Item Formatting Controls. | 0 | Value may be 0 or larger. |
Window size | .ws | Returns the number of rows that may be written to the main window given the number of rows in the title and header blocks and the page size. Note that this attribute is computed by GAMS and cannot be changed by the user. |
Put File Pages
In this section we will discuss the structure of put file pages, in particular how to write titles and headers. In addition, we will give details on how users may control many aspects of the format of a put file page.
Adding Titles and Headers
Titles and headers are widely used when there are sections of a page that remain relatively constant throughout a document. There are three independent writing areas on each page of a put file: the title block, the header block and the main window. The layout of a page is shown in the following diagram.
+-----------------+ | Title Block | +-----------------+ | Header Block | +-----------------+ | | | Main Window | | | +-----------------+
Note that the put statement writes to the main window. There are two variants of the put statement that write to the title block and header block respectively: the puttl statement and the puthd statement.
Observe that every page must have an entry in the main window. If a page has no output in its main window, the page will not written, regardless of whether there are output items in the title or header blocks. To force a page that has an empty window out to file, we recommend to simply write something innocuous to the window, like the following:
put ''; // space
This will initiate the main window of the page and thus the page will be written.
Further, note that the size of any area of a page is based on the number of lines written to it and the total number of lines has to be smaller than the specified page size. A new page is started automatically whenever a page is full. For details on manual pagination, see section The Putpage Statement: Controlling Paging. Each area of a page is maintained independently. For example, we may write to the title block first, then to the header block and then again to the title block. However once we have written to the main window, all subsequent entries to the title and header are written to the next page, not the current page.
The Puttl Statement: Writing to the Title Block
The puttl (or putTitle
which can be used as a synonym) statement is a variant of the put statement that writes to the title block of a page. The syntax is as follows:
puttl [file_name] item {item};
The keyword puttl
indicates that this is a puttl statement. The internal name of the file, file_name
, may be omitted if the desired file is already current. Like in the put statement, the content that is written is one or more items
, that may be a text string, a numerical value or a set value. For more information on items, see section Output Items below. Consider the following example:
puttl factors 'GAMS Put Example';
If this line is placed before the put statement that writes to the main window in the example above, then GAMS Put Example
will be written to the title block.
Observe that title blocks often contain the name of the model and the number of the put page. Once content is placed in the title block, it will be repeated on every page unless it is modified or deleted. For details on how to write output like the page number to a put file, see section System Suffixes as Output Items below.
- Note
- If content has already been written to the main window of a page, the items in the puttl statement will appear in the title block starting from the next page. Thus the title has to be written before any entries in the main window if it is to appear on the current page.
Observe that if the title and header blocks contain too many lines given the page size, the page will overflow resulting in a put error.
The Puthd Statement: Writing to the Header Block
Like the puttl statement, the puthd (or putHeader
which can be used as a synonym) statement is a variant of the put statement. Puthd statements write to the header block of a page. The syntax is as follows:
puthd [file_name] item {item};
The keyword puthd
indicates that this is a puthd statement. The internal name of the file, file_name
, may be omitted if the desired file is already current. Like in the put statement, the content that is written is one or more items
. See section Output Items below for more information on items.
Observe that title blocks often contain a disclaimer or an instruction that is meant to be repeated on every page. Once content is placed in the header block, it will be repeated on every page unless it is modified or deleted.
- Note
- If content has already been written to the main window of a page, the items in the puthd statement will appear in the header block starting from the next page. Thus the header has to be written before any entries in the main window if it is to appear on the current page.
Observe that if the title and header blocks contain too many lines given the page size, the page will overflow resulting in a put error.
The Putclear Statement: Deleting Title and Header Blocks
The putclear
(or putfmcl
which can be used as a synonym) statement may be used to delete the title and header blocks. The syntax is simple:
putclear;
If the keyword putclear
is inserted after a title and/or header block has been written, but before the main window has been written to, then the title and/or header blocks of the current page will be deleted. If the main window has already been written to, the the title and/or header block of the next and all subsequent pages will be deleted. Note that if the user wishes to delete either only the title or only the header block, the put file attributes .tlll and .hdll respectively may be set to zero. For more information, see Last Line Control.
The Putpage Statement: Controlling Paging
A new page is started automatically if the bottom of a page is reached. Alternatively, a new page may be started early using a variant of the put statement: the putpage
statement. The syntax is as follows:
putpage [file_name] {item};
The keyword putpage
indicates that this is a putpage statement. In its simplest form, the putpage statement consists of just the keyword. If only the keyword is used, the current page will be terminated. The optional file_name
makes the put file with the internal name file_name
current. If output items follow, they will be written to the current page and a new page will be made available for the next put statement.
Consider the following example:
File example / example.txt /;
putpage example "This text is placed in the main window and the page ends here.";
put "Here starts a new page in the same putfile."
Observe that three file attributes are helpful for manual paging: last page (.lp
), window size (.ws
) and last line (.ll
).
Controlling the Format of a Put File Page
While GAMS established gracious defaults, there are numerous ways to customize the format of a put file page. In this section we will present the put file attributes that facilitate the control of various aspects of page formatting and ways to control the position of the cursor.
Controlling Page Size, Page Width and Margins
By default, 60 rows (lines) may be written on a put file page. At any point in the program the file attribute page size (.ps
) may be used to reset this value. Note that the upper limit is 130. Note further, that a put error will result if the attribute is set to value that is smaller than the number of rows which have already been written to the current page. Observe that the specification of .ps
is only effective if the attribute print control (.pc
) has a value other than its default value.
By default, 255 characters (colums) may be written to each line of a put file page. Like the page size, the page width may be reset at any point. GAMS provides the file attribute page width (.pw
) to do this. Note that the upper limit is 32767. Note further, that a put error will result if the attribute is set to value that is smaller than the number of columns which have already been written to the current page.
By default, put file pages do not have top, bottom and left margins. However, it is easy to specify blank lines for the margins with the file attributes top margin (.tm
) and bottom margin (.bm
). Note that the lines reserved for the margins are in addition to the value specified for the page size (.ps
). Observe that the file attribute .bm
is only functional if the value of the file attribute print control (.pc
) is set to zero. In addition, the number of empty columns for left margins may be specified with the file attribute left margin (.lm
)
Controlling the Print Format and the Use of Capital and Lower Case Letters
By default, GAMS prints continuous pages. However, the file attribute print control (.pc
) offers several alternative options. For a full list, see the respective entry in Table Put File Attributes above. Note in particular that the options 4, 5, 6 and 8 create delimited files, which are useful for importing output to other applications like spreadsheets. For an example, see section Creating a Report for the Model MEXSS.
By default, alphabetic characters are displayed in the case they were inputted. Note that the value of 1 for the file attribute alphabetic case (.case
) will display all output in capital letters, regardless of the input, and the value of 2 will result in only lower case letters being displayed.
Assume that we wish a put file report.txt
to have pages with 72 characters to a row and 58 lines, ASCII page control characters to be inserted at the end of every page, an additional top margin of 6 lines and all output displayed in upper case. The following assignments will implement these specifications:
File report /report.txt/;
report.pw = 72; report.ps = 58; report.pc = 3;
report.tm = 6; report.case = 1;
Controlling the Cursor On a Page
There are three ways to control the position of the cursor: with cursor control characters, with the system attribute system.tab
and with file attributes. In this section we will give details on cursor control characters, while inserting tabs and file attributes that are relevant for cursor control will be discussed in the next two sections.
By default, the cursor is moved to the space immediately following the last character written. GAMS provides the control characters listed in Table 2 to specify another position for the cursor.
Symbol | Description |
---|---|
# n | Move cursor position to row n of current page. |
@n | Move cursor position to column n of current line. |
/ | Move cursor to first column of next line. |
Table 2: Cursor Control Characters
Note that the numeric value n
that follows the characters #
and @
may be any expression or symbol with a numeric value. An example is given below. Note further, that the character @
is commonly used to align columns if the column headings have different widths. For an example, see section Creating a Report for the Model MEXSS. Observe that the character @
may be used to overwrite output items that were written earlier. Consider the following example:
File out /out.dat/;
put out;
put 'Good' @3 'morning everybody!';
This code snippet will generate the following output:
Gomorning everybody!
Observe that cursor control characters are also used and discussed in the example at the beginning of this chapter.
Controlling the Cursor with a System Attribute: Inserting Tabs
The system attribute system.tab
may be used to insert tabs. Consider the following example:
File test / test.dat /;
put test;
put "1" system.tab "2" system.tab "3" ;
The put file will contain the following line, separating 1, 2, and 3 by tabs.
1 2 3
Controlling the Cursor with File Attributes
In addition to cursor control characters and tabs, the position of the cursor may be controlled using the file attributes that will be discussed in this section. These file attributes refer to the current column, the current row and the last line in the title block, the header block and the main window.
As there are three independent writing areas on each put file page, there are three file attributes that refer to the current column. They are listed in Table 3.
Symbol | Description |
---|---|
.cc | Current cursor column in the main window. |
.hdcc | Current cursor column in the header block |
.tlcc | Current cursor column in the title block |
Table 3: File Attributes for the Column Position of the Cursor
Note that the values for these attributes are numeric and they are updated only at the end of a put statement. Consequently, their values will remain constant during a put statement, even if multiple items or lines are displayed. Observe that the attributes may be used on the left-hand side and on the right-hand side of an assignment statement to set the current column position and return it respectively.
The following example illustrates the updating of the cursor control suffixes and the use of cursor control characters. The example is trivial but instructive:
Scalar lmarg 'left margin' /6/;
File out; put out;
put @(lmarg+2) 'out.cc = ', out.cc:0:0 ' ';
put @out.cc 'x'/ @out.cc 'y'/ @out.cc 'z ';
put 'out.cc = ' out.cc:0:0;
The resulting file out.put
will contain the following lines:
out.cc = 1 x y z out.cc = 23
Note that the scalar lmarg
is set to a specific value that will be used as an alignment tab. Symbols which hold common alignment values such as margins or tabs are often useful for large structured documents. The first put statement uses the cursor control character @
to relocate the cursor to column 8 where the text item out.cc
and the respective value for the file attribute .cc
are displayed. Note that the numerical value of the file attribute is formatted locally with the effect that only integers are displayed. We observe that at the start of the first put statement the file attribute out.cc
equals 1.
The second put statement illustrates the updating of the cursor control suffixes by writing the letters x
, y
and z
on three different lines. Each is preceded by moving the cursor to the value of the file attribute .cc
. Note that at the end of the first put statement the value of out.cc
is updated to 20. Hence, out.cc
is 20 at the start of the second put statement. As a single put statement is used to write all three letters, the value of out.cc
remains constant and thus the letters are written in the same column. At the end of the second put statement the value of out.cc
value is updated to 23 (observe that there are two blank spaces after the letter z
).
The third put statement writes the current value of the file attribute out.cc
, which is the value at the start of the put statement.
As there are three independent writing areas on each put file page, there are three file attributes that refer to the current row. They are listed in Table 4.
Symbol | Description |
---|---|
.cr | Current cursor row in the main window |
.hdcr | Current cursor row in the header block |
.tlcr | Current cursor row in the title block |
Table 4: File Attributes for the Row Position of the Cursor
Note that the values for these attributes are numeric and they updated only at the end of a put statement. Consequently, their values will remain constant during a put statement regardless of how many rows are displayed. Observe that the attributes may be used on the left-hand side and on the right-hand side of an assignment statement to set the current row and return it respectively. The files attributes for the row postion of the cursor behave similarly to those for the column position.
Like the file attributes for the current column and row position, the file attributes for the last line have three variants, one for each writing area. They are given in Table 5.
Symbol | Description |
---|---|
.ll | Last line in the main window |
.hdll | Last line in the header block |
.tlll | Last line in the title block |
Table 5: File Attributes for the Last Line
Note that unlike the row and column controls, the last line attributes are updated continuously. Last line attributes are especially useful for modifying the three writing areas of a page. They may be used on the left-hand side and on the right-hand side of an assignment statement to set the current last line and return it respectively. Rows will be deleted if the last line attribute is set to a value that is lower than the current row.
- Attention
- The file attributes
.tlll
and.hdll
may not hold values applicable to the current page, because when the title or header blocks are modified, they will correspond to the title or header blocks of the next page if the main window has been written to on the current page.
As mentioned above, in addition to determining the last line in a writing area, these file attributes may be used to delete lines within a writing area. In the following example, the header block will be completely deleted by resetting the attribute .hdll
to zero.
File out;
puthd out 'This header statement will be eliminated';
out.hdll = 0;
Note that a header is written initially. However, by changing the attribute .hdll
to zero, the cursor is reset to the top of the header block. As a result, the header will not be written unless something new is added to the header block.
Output Items
Output items are the items in the put statement that are written to the put file. They may be a text, a numerical value or a set value. In this section we will provide more information on these three types of items. Observe that system suffixes and command line parameters are either text strings or have a numerical value. They may also be used as output items.
Text Items
Text items may be a quoted text, an explanatory text of identifiers and labels or names of set elements. In this section we will give details on each of these text items. In addition, text items may be system attributes or command line parameters. For these text items, see sections System Suffixes as Output Items and Command Line Parameters as Output Items respectively. Details on default field widths and alignments for text items and global and local customizing controls are given in section Customizing the Format of Output Items.
Text Items: Quoted Text
The simplest text output item is a quoted text. A quoted text is any combination of characters or numbers set apart by a pair of single (') or double (") quotes with each the items needing to use a matching pair. Thus the following three lines are all exactly equivalent.
put 'Run on ' system.date ' using source file ' system.ifile;
put "Run on " system.date " using source file " system.ifile;
put 'Run on ' system.date " using source file " system.ifile;
Note that there is a limit on the length of all output items: output items may not exceed the page width. In case this limit is exceeded, a put error will be reported in the listing file. Put errors are introduced and discussed in section Put Errors.
Text Items: Identifier Attributes
Text items like the explanatory text of an identifier, the name of a set element and the explanatory text of a set element are specified with identifier attributes. The identifier attributes are listed in Table 6.
Identifier Attribute | Symbol | Description |
---|---|---|
Explanatory text of an identifier | .ts | Displays the descriptive text associated with any identifier (like a set, a parameter, a variable, an equation, a model). |
Name of a set element | .tl | Displays the names of the individual elements of a set. Observe that the put statement must be embedded in a loop statement, where the respective set is the looping set or the set is a singleton set. |
Explanatory text of a set element | .te(index_list) | Displays the explanatory text associated with a set element. Note that this attribute requires the specification of a driving index. If the set is a simple set, the set name itself will have to be specified as index (see example below). If the set is defined over an index, then the index or a subset of the index may be specified. A special case arises in case users wish to gain access to the explanatory text that appears in the definition of another set (see example below). Observe that if there is no explanatory text for a set element in the set definition, then either the name of the set element (default) or a blank will be displayed, depending on the value of the file attribute text fill (.tf ). Note that with .tf=3 even if an explanatory text exists, the name of the element will be displayed. Observe that the put statement must be embedded in a loop statement, where the respective set is the looping set or the set is a singleton set. |
Indexed identifier with label combination | .tn | Displays the name of the identifier with all individual label combinations. Observe that the put statement must be embedded in a loop statement, where the respective index is the looping set or the set is a singleton set. See example below. |
Table 6: Identifier Attributes
Consider the following example:
Set i master set of sites / i1 Seattle, i2 Portland
i3 San Francisco, i4 Los Angeles, i5 /
j subset of sites / i3 * i5 / ;
File out; put out i.ts /;
loop(i, put i.tl, i.te(i) /);
The resulting put file out.put
will contain the following output:
master set of sites i1 Seattle i2 Portland i3 San Francisco i4 Los Angeles i5 i5
Note that the explanatory text of the set i
is written first, followed by the label names of the set i
and their respective explanatory texts. Note further that even though the set i
does not have an index (it is a simple set), an index is required for the attribute .te
. In this case we specify as index the set itself. Observe that the set element i5
was defined without an explanatory text. By default, GAMS inserts the name of the element instead. This may be changed by alterning the code in the following way:
put out i.ts /;
out.tf = 0;
loop(i, put i.tl, i.te(i) /);
Note that we assign the value of zero to the file attribute text fill (.tf
) before the put statement where one of the items refers to the explanatory text of a set element. As a result, a blank will be displayed where the explanatory text of the set element i5
is supposed to appear:
master set of sites i1 Seattle i2 Portland i3 San Francisco i4 Los Angeles i5
Assume we also wish to display the elements of the set j
and their explanatory texts. We could just adapt the code above for the set j
and add the following two lines:
put / j.ts /;
loop(j, put j.tl, j.te(j) /);
These lines will result in the follwing output to be appended to the put file:
subset of sites i3 i4 i5
Note that the explanatory text associated with the set elements is missing, since there is no explanatory text for the elements in the definition of the set j
and the value of zero for text fill is still valid. However, we may gain access to the explanatory text of the set elements in the definition of the set i
in the following way:
put / j.ts /;
loop(j, put j.tl, i.te(j) /);
Note that the the specification i.te(j)
singles out the explanatory texts of the elements of the set i
that are also elements of the set j
. Hence we will obtain the desired output:
subset of sites i3 San Francisco i4 Los Angeles i5
The following example illustrates the use of the identifier attribute .tn
. The model [MEXSS] is a simplified representation of the Mexican steel sector, where five steel plants have to satisfy the demand for steel in three markets. Each steel plant i
has several productive units m
and the capacity of every unit in every plant is specified with the parameter k(m,i)
. Assume we wish to write to a put file a list of all nonzero capacities. We could add the following code to the model:
File out /out.dat/;
put out 'Capacity (in metric tons)' / /;
loop((m,i)$k(m,i),
put k.tn(m,i), @30 '=' k(m,i) /;
)
Note that we restrict the loop statement with a logical condition to exclude entries of zero. The put file out.dat
will contain the following lines:
Capacity (in metric tons) k('blast-furn','ahmsa') = 3.25 k('blast-furn','fundidora') = 1.40 k('blast-furn','sicartsa') = 1.10 k('openhearth','ahmsa') = 1.50 k('openhearth','fundidora') = 0.85 k('bof','ahmsa') = 2.07 k('bof','fundidora') = 1.50 k('bof','sicartsa') = 1.30 k('direct-red','hylsa') = 0.98 k('direct-red','hylsap') = 1.00 k('elec-arc','hylsa') = 1.13 k('elec-arc','hylsap') = 0.56
Observe that a more elaborate report for the model [MEXSS] is given in section Creating a Report for the Model MEXSS at the end of this chapter. The identifier attribute .tn
is particularly useful when creating scalar EMP info files.
Text Items: Text Blocks
The easiest way to write blocks of text to a put file is with the dollar control options $onPut and $offPut. Consider the following example:
File fx; put fx;
$onPut
We will write four
lines of text to the put file,
including a blank line.
$offPut
The put file fx.put
will contain the following lines.
We will write four lines of text to the put file, including a blank line.
Note that these dollar control options have a variant that allows the substitution of compile-time variables. For details see the description of $on/offPut.
Numeric Items
Numeric items may be values of parameters, variable and equation attributes or model attributes and expressions of such elemens. These numeric items will be discussed in this section. In addition, numeric items may be command line parameters. For these numeric items, see section Command Line Parameters as Output Items. Details on default field widths and alignments for numeric items and global and local customizing controls are given in section Customizing the Format of Output Items.
Numeric Items: Parameters and Functions
In our first example in this chapter, one of the output items was the parameter f
. For convenience, we repeat the respective code below:
put 'Freight cost ', f;
Note that the simple name of the parameter is sufficient. In the same example we also had two parameters that were defined over an index: a(i)
and b(i)
. The respective lines of code follow:
loop(i, put @3, i.tl, @15, a(i)/);
* ...
loop(j, put @3, j.tl, @15, b(j)/);
Note that indexed parameters must be specified with their index and a put statement with an indexed parameter has to be embedded within a loop structure.
Numeric Items: Variable and Equation Attributes
Recall that data associated with variables and equations is stored in variable attributes and equation attributes respectively. A full list is given in sections Variable Attributes and Equation Attributes.
Suppose we wish to generate a report with the demand for each market in the transportation model [TRNSPORT], the satisfied demand after solution of the model and the marginal cost of meeting the demand. Recall that the demand data for each market is saved in the parameter b(j)
and the relationship between shipment quantities and demand is encoded in equation demand(j)
. The following code will generate the desired report:
File report /report.dat/; put report;
loop(j,
put 'Report for ' j.tl /
'Demand' @35 b(j):10:0 /
'Demand satisfied' @35 demand.l(j):10:0 /
'Marginal Cost of meeting demand' @35 demand.m(j):10:2 / /;
);
Note that we use three numeric output items: the parameter b(j)
, the level value of the equation demand.l(j)
and the marginal value of the equation demand.m(j)
. Note further, that all three items are indexed over the set j
and thus the put statement has to be placed within a loop statement. Observe that we customize the formatting of the items. For details see section Local Item Formatting Controls. The put file report.dat
will contain the following output:
Report for New-York Demand 325 Demand satisfied 325 Marginal Cost of meeting demand 0.23 Report for Chicago Demand 300 Demand satisfied 300 Marginal Cost of meeting demand 0.15 Report for Topeka Demand 275 Demand satisfied 275 Marginal Cost of meeting demand 0.13
Numeric Items: Model Attributes
GAMS models have many model attributes. An introduction and a complete list is given in section Model Attributes. While in principle all model attributes may be used as output items, the attributes .modelStat
and .solveStat
with their string valued counter parts .TModStat
and .TSolStat
are used most frequently. They refer to the model status and solver termination condition after solution respectively. For a complete list of their values, see sections Model Status and Solver Status.
Suppose we wish to generate a report that contains the time it took to execute the solve statement of the transportation model [TRNSPORT], the objective value and the corresponding string valued model and solver status. Recall that the name of the model is transport
. The following code will generate the desired report:
File report /report.dat/; put report;
put 'elapsed time in seconds of solve statement : ' transport.etSolve:0 /
'objective value: : ' transport.objVal:0 /
'model status: : ' transport.tmodstat /
'solver status: : ' transport.tsolstat ;
Observe that we customize the formatting of the first two items. For details see section Local Item Formatting Controls. The put file report.dat
will contain the following output:
elapsed time in seconds of solve statement : 0.11 objective value: : 153.68 model status: : 1 Optimal solver status: : 1 Normal Completion
Set Value Items
There are only two set values: YES
and NO
. The set value will be YES
if a label is an element of a specific set and NO
otherwise. Consider the following example which is adapted from the example in section Text Items: Identifier Attributes above:
Set i master set of sites / i1 Seattle, i2 Portland
i3 San Francisco, i4 Los Angeles, i5 /
j subset of sites / i3 * i5 / ;
File out2 / out2.dat /;
put out2 j.ts /;
out2.tf = 0;
loop(i, put i.tl, j(i), ' ', i.te(i) /);
Note that within the loop structure, the put statement writes each element of the set i
, determines whether it is a member of the set j
and displays the respective set value, and adds the explanatory text for the label. Hence the resulting put file out2.dat
will look as follows:
subset of sites i1 NO Seattle i2 NO Portland i3 YES San Francisco i4 YES Los Angeles i5 YES
Observe that the set values in the second column reflect set membership of the set j
. Observe further, that the missing explanatory text for label i5
is displayed as a blank, since the value of the file suffix text fill (.tf
) equals zero.
System Suffixes as Output Items
System suffixes contain information about a GAMS run, they are introduced and discussed in chapter System Attributes. System suffixes may be used as output items in the context of put statements. They are accessed in the following two ways:
system.attribute %system.attribute%
Here system
is a keyword and .suffix
is a specific system suffixes. Note that system.suffix
references the execution-time version (which can be of type string or numeric) of the system suffixes and %system.suffix%
(which is interpreted by the compiler as part of the input string) references the compile-time version. For further details on the difference between execution-time and compile-time system suffixes, see chapter System Attributes. A complete list of all system suffixes is given in section List of all System Suffixes, in Table 7 we present a list of the most common system suffixes.
System Attribute | Description |
---|---|
.date | Program execution date |
.ifile | Input file name |
.ofile | Output file name |
.rdate | Restart file date |
.rfile | Restart file name |
.sfile | Save file name |
.title | Title of the model as specified by $title |
Table 7: A Selection of System Suffixes
To illustrate how system suffixes are used, assume we wish to include the program execution date, the name of the input (GAMS) file, and the page number of the current put statement in the input file to the report results.dat
in section A First Example above. We will modify the code in the following way:
File factors /factors.dat/, results /results.dat/;
* ...
put results;
puthd 'Program Execution Date:', @26, system.date /
'Source File:', @26, system.ifile /;
'Page Number:', @26, system.page / /;
put 'Transportation Model Results' / / ;
loop((i,j), put i.tl, @12, j.tl, @24, x.l(i,j):8:4 /);
The file results.dat
will then contain the following lines:
Program Execution Date: 01/13/17 Source File: C:\Documents\GAMS\Models\trnsport.gms Page Number: 1 Transportation Model Results Seattle New-York 50.0000 Seattle Chicago 300.0000 Seattle Topeka 0.0000 San-Diego New-York 275.0000 San-Diego Chicago 0.0000 San-Diego Topeka 275.0000
Note that the date is given in the American format: month/day/year
and can be reset via the command line parameter DFormat. Also note that including the page number in the header block of a put file will have the effect that the pages of the put file will be numbered. Of course, this is especially useful for longer put files.
It is also possible to read environment variables at execution time in a put context using sysEnv.name
as in the following example:
$setEnv hello world
put_utility 'log' / sysEnv.hello;
If the environment variable queried is not defined, the result depends on the value of the command line parameter stringChk.
Command Line Parameters as Output Items
Command line parameters may also be used as output items. They are introduced and discussed in chapter The GAMS Call and Command Line Parameters. For an overview of all GAMS command line parameters, see section List of Command Line Parameters. Like system suffixes , command line parameters are referenced in the context of a put statement either compile-time strings or in an execution time version as follows:
put "%gams.parameter%";
put gams.parameter;
Here parameter
is a GAMS command line parameter. To illustrate how command line parameters are used, assume we wish to include the page size of the input file, the name of the input file and the name of the restart file in the report results.dat
in section A First Example above. We will modify the code in the following way:
File factors /factors.dat/, results /results.dat/ ;
* ...
put results;
put 'Transportation Model Results'// ;
loop((i,j), put i.tl, @12, j.tl, @24, x.l(i,j):8:4 //);
put / "Page size = %gams.ps%"
/ "GAMS input file = %gams.input%"
/ "GAMS restart file = %gams.restart%";
The last three lines of the put file results.dat
follow:
Page size = 58 GAMS input file = C:\Documents\GAMS\Models\trnsport.gms GAMS restart file =
Note that there was no restart file in the GAMS run, thus the value for %gams.restart%
is the empty string.
In this example it actually makes no difference if one uses the compile- or execution time version to query the value of a command line parameter. This might be different, when doing the compile and execution phase separately, e.g. when using remote execution. Here is a toy example showing the difference:
$onEchoV > logScrDir.gms
put_utility 'log' / '%gams.scrDir%';
put_utility 'log' / gams.scrDir;
$offEcho
$call gams logScrDir.gms a=c s=1 keep=1
$call gams logScrDir.gms a=e r=1
In the log, one will see that %gams.scrDir%
is evaluated in the first run at compile time already, while gams.scrDir
is evaluated at execution time in the second run:
--- logScrDir.gms(1) 3 Mb C:\Data\t m p\225d\ --- logScrDir.gms(2) 3 Mb C:\Data\t m p\225e\
Customizing the Format of Output Items
GAMS provides global and local controls to modify the default format of output items. Global controls are set with file attributes and apply to all output items in a put file that follow the assignment of a file attribute. Local controls are used to change the format of only one specific output item.
Global Item Formatting Controls
The alignment (justification) of the field and the width of the field may be modified for all types of output items. The attributes that control field alignment are listed in Table 8. Note that possible values are 1 (right), 2 (left) and 3 (center).
Type of Output Item | Symbol | Default Value |
---|---|---|
Text items: set labels | .lj | 2: Left |
Text items: quoted and explanatory text | .tj | 2: Left |
Numeric values | .nj | 1: Right |
Set values | .sj | 1: Right |
Table 8: File Attributes for Field Alignment
The width of the field is specified with the number of spaces to be allocated. The attributes that control field width are liste in Table 9.
Type of Output Item | Symbol | Default Value |
---|---|---|
Text items: set labels | .lw | 12 |
Text items: quoted and explanatory text | .tw | 0 |
Numeric values | .nw | 12 |
Set values | .sw | 12 (maximum 20) |
Table 9: File Attributes for Field Width
Note that the value of zero signifies a variable field width, matching the the exact size of the item being displayed. If a text output item does not fit within the specified field, truncation will occur to the right. For numeric output items, the decimal portion of a number is rounded or scientific notation is used to fit the number within the given field. If a number is still too large, asterisks will replace the value in the output file.
For example, the following assignment will set the field width for numeric items in the file out.put
globally to 4:
out.nw = 4;
In addition to field alignment and field width, there are further global controls that apply to numeric output items only. They are given in Table 10.
File Attribute | Symbol | Description | Default Value | Optional Values |
---|---|---|---|---|
Number of decimals | .nd | Sets the number of decimals that are displayed for numeric items. A value of zero entails that fixed-format output will show the number rounded to the nearest integer. | 2 | Values may be between 0 and 20. |
Numeric round format | .nr | Selects the formatting used for numeric output. For example, one can choose to use scientific notation (i.e. E-format) for all numbers: this is especially useful for numbers so small that they display as only zeros in fixed format with the value specified for number of decimals (.nd ). The default rounding format will treat small values in this way, but in many situations, it is important to be aware that such small values exist. | 1 | 0: Item is displayed in F or E format to fit given width and decimals. 1: Item is rounded to fit given width and decimals. 2: Item is displayed in E format to fit given width and decimals. 3: Item is rounded to fit given width. 4: Item is displayed in F or E format to fit given width. |
Numeric zero tolerance | .nz | Sets the tolerance level for which a number will be rounded to zero for display purposes. Note that in case this attribute is set to zero, rounding is determined by the field width. | 1.0e-10 |
Table 10: File Attributes for Global Format Control Specific to Numeric Items
Note that numeric items are always formatted to fit within the specified width limit, but their display may use fewer characters. Similarly, for some values of .nr
, the number of digits shown is limited by the choice of the .nd
parameter, but fewer digits may be shown. At most 17 significant digits are included - this is enough to represent any double-precision value unambiguously, i.e. as a base-10 string that converts back into this same double. With this in mind, any number can be represented fully in E-format using at most 24 digits, e.g. -1.25E+102
.
With .nr=0
, the formatting routines honor the decimals limit. Values closer to 1 are displayed in fixed format. Values so small they would display only zeros in fixed format are displayed in E-format, as are values too large for the width limit. Formatting with .nr=1
is similar, but small values are shown in fixed format even if they show all zeros. With .nr=2
E-format is used for all values, with the number of trailing digits respecting the decimals limit .nd
. The decimals limit is ignored for .nr=3
, and fixed format is used unless the value is so large that E-format output is shorter. Finally, .nr=4
is intended to be used with larger output widths, e.g. 18 or 24, in order to show values of all magnitudes in as full a precision as possible: it ignores the decimal limit and uses whatever format allows more significant digits in the specified width.
The following example illustrates the result of different combinations of numeric file attributes. Note that we will use five combinations of the file attributes .nd
, .nz
, .nr
and .nw
to display three numerical values.
Set c suffix combinations / comb1 * comb9 /
v value indices / value1 * value5 / ;
Table suffix(c,*) numeric suffix combinations
nd nz nr nw
comb1 3 0 0 12
comb2 3 1e-5 0 12
comb3 3 1e-5 1 12
comb4 8 0 0 10
comb5 6 1e-5 1 12
comb6 0 1e-5 1 12
comb7 10 0 2 18
comb8 0 0 3 14
comb9 0 0 4 18 ;
Parameter value(v) test values
/ value1 1.2345678901e14
value2 [pi]
value3 -0.1234567
value4 0.0001234567
value5 1.234567e-13 / ;
File out; put out;
out.nj=2; out.lw=10; out.cc=11;
loop (v, put v.tl:21);
loop (c,
out.nd=suffix(c,"nd");
out.nz=suffix(c,"nz");
out.nr=suffix(c,"nr");
out.nw=suffix(c,"nw");
put / c.tl;
loop (v,
put @(ord(v)*21-10), value(v)
)
);
Observe that we have chosen to align the values to the left. This will enhance readability as the model loops through the suffix combinations that entail different field widths. The resulting output file out.put
follows:
value1 value2 value3 value4 value5 comb1 1.234568E+14 3.142 -0.123 1.2345670E-4 1.234567E-13 comb2 1.234568E+14 3.142 -0.123 1.2345670E-4 0.000 comb3 1.234568E+14 3.142 -0.123 0.000 0.000 comb4 1.2346E+14 3.14159265 -0.1234567 0.00012346 1.2346E-13 comb5 1.234568E+14 3.141593 -0.123457 0.000123 0.000000 comb6 1.234568E+14 3 -0 0 0 comb7 1.2345678901E+14 3.1415926536E+00 -1.2345670000E-01 1.2345670000E-04 1.2345670000E-13 comb8 1.23456789E+14 3.141592653590 -0.12345670000 0.000123456700 0.000000000000 comb9 123456789010000 3.141592653589793 -0.12345678 1.234567E-4 1.234567E-13
Note that in comb1
the display of values switches to the exponential notation when the value becomes smaller than the number of decimal places allowed. This is a result of .nr=0
. Note further, that value4
is greater than the zero tolerance level (.nz
), but smaller than the number of decimals allowed (.nd
) in both, comb2
and comb3
. However, .nr=0
results in the exponential notation in the display of comb2
, while .nr=1
has the effect that this small value is rounded to zero. Observe that in comb6
fixed-format is used whenever allowed by the width limit, and in these cases the output is rounded to integer because .nd
is set to zero. With comb7
E-format is used in all cases: a leading space is added for positive values and a minus sign to negative values, and the magnitude is indicated with an explicit plus/minus and two digits (three if necessary). With comb8
we see fixed-format used whenever possible and as many digits (significant or not) as allowed by the width. With comb9
we see only significant digits, with the format chosen to allow the display of as many digits as possible.
Local Item Formatting Controls
The local item formatting controls allow to format specific output items. Note that local formatting overrides global format settings. The syntax is as follows:
item:{<>}width:decimals;
Here item
is the output item, followed by a colon, an alignment (justification) symbol, the field width, a colon and the number of decimals to be displayed. Note that the limit on the number of the decimal places is only valid for numeric output. Note further, that if a component of the local formatting feature is omitted, then the respective global formatting settings will be used. The local alignment symbols are listed in Table 11.
Symbol | Alignment |
---|---|
> | Right |
< | Left |
<> | Center |
Table 11: Local Alignment Symbols
Observe that similar to global formatting, a field width of zero means that the field width will be variable, depending on the item to be displayed.
The following example serves as illustration. Observe that we use end-of-line comments to annotate the code.
File out; put out;
$eolCom //
Set i / i1*i3 /;
Parameter d(i) / i1 1426, i2 1347, i3 900 /;
Scalar f / 17.6745 /;
loop(i, put d(i):0:0 /); // default justification and a field width
// of variable size with no decimals
put / 'Right Justified Comment':>50
/ 'Center Justified Truncated Comment':<>20;
put / / f:<6:2; // left aligned scalar with 6 spaces for field width
// and two decimals
The Put_Utility Statement
The put_utility
statement is a variant of the put statement that may be used to execute external programs. The syntax is as follows:
put_utility [file_name] 'command' / 'arguments' {/ 'command' / 'arguments'};
The keyword put_utility
and its synonym put_utilities
indicate that this is a put_utility statement. The keyword is followed by the internal name of an external file, file_name
. Note that file_name
may be omitted. It is not required for the put_utility
statement but might be used to activate a file to be used with following put
statements. Command
denotes one of the commands listed in Table 12 below. Commands are followed by a slash and their respective arguments
. Observe that a put_utility statement may contain multiple command / argument pairs. An example is given below.
The following simple example illustrates the put_utility statement:
File test / test.txt /;
put test "This is the original file."
put_utility 'ren' / 'test.dat';
putclose "This is the renamed file.";
test.ap = 1;
put "Write to the renamed file.";
Note that first the put file test.txt
with the internal name test
is defined, made current and written to. Then the put_utility statement uses the command ren to rename the current put file. The new name is test.dat
and the internal name test
will from now on reference the new file test.dat
. However, the original file test.txt
is not deleted. Hence, the code above will create two external files: test.txt
and test.dat
. The file test.txt
will contain the following line:
This is the original file.
The file test.dat
will have the following content:
This is the renamed file. Write to the renamed file.
- Note
- If Put File Attributes are specified, they are also considered for the
put_utility
commands and arguments. This could lead to surprising results in some cases, like in this example:
This will trigger the following errors:File test / test.txt /; test.pc = 5; put test "This is the original file." put_utility 'ren' / 'test.dat'; putclose "This is the renamed file.";
*** Error at line 5: Put_Utilities: Unknown request ""ren"" *** Error at line 5: Put_Utilities: Unknown request ""test.dat""
The problem is, thattest.pc = 5;
puts quotes around non-numeric output, and thus"ren"
(including the quotes) is not recognized as command anymore. To overcome this issuetest.pc
should be set back to default for theren
command like this:File test / test.txt /; test.pc = 5; put test "This is the original file."; test.pc = 2; put_utility 'ren' / 'test.dat'; test.pc = 5; putclose "This is the renamed file.";
We will present a list of all commands and their arguments in Table 12 and give examples for most commands below.
Table 12: List of Commands and their Arguments
Command | Description of Command | Description of Arguments |
---|---|---|
assignText | Allows to set the explanatory or label text of a singleton set element. See example below. | Name of singleton set symbol and text. |
click | Adds a clickable file reference to the process window of the IDE. See example below. | File name of the file to which the reference will point. |
dropEnv | Removes an environment variable at execution time. | Name of the environment variable. |
ECArguments | Allows to set the arguments for execution time embedded code execution. See example in section Embedded Code at Execution Time. | Text for the embedded code argument. |
exec | Passes a command to the operating system for execution. GAMS will wait until the command is executed. See example below. Note that the distinction between exec and shell is technical and may be operating system specific. Typically, the ability to use redirect of standard input output and the error console is involved. | Command to be executed with arguments. |
exec.aSync | Passes a command to the operating system for execution. However, GAMS will not wait until the command is executed. | Command to be executed with arguments. Job control is handled identical to jobs spawned via execute.async . |
exec.aSyncNC | Passes a command to the operating system for execution using a different console than the parent process (Windows only). GAMS will not wait until the command is executed, thus using multiple processors is possible. Job control is handled identical to jobs spawned via execute.async . | Command to be executed with arguments. |
exec.checkErrorLevel | Passes a command to the operating system for execution. GAMS will wait until the command is executed, raises an execution error and aborts the execution, if the errorLevel returned is not 0. | Command to be executed with arguments. |
gdxIn | Accesses the GDX file specified in the argument. A subsequent directive execute_load or execute_loadpoint without a specified file name will unload data from the GDX file thus accessed. See example below. | Name of the GDX file that data will be loaded from. |
gdxOut | Creates a new GDX file or accesses an existing GDX file specified in the argument. A subsequent directive execute_unload without a specified file name will write to the GDX file thus created or accessed. Note that if an existing GDX file is accessed, it will be overwritten. See example below. | Name of the GDX file to which data will be unloaded. |
glb | Used by GAMS to facilitate building the model library - not intended for users. | – |
htm | Used by GAMS to facilitate building the model library - not intended for users. | – |
inc | Includes the contents of an external file in the currently active put file. See example below. | File name of external file. |
incLog | Includes the contents of an external file in the currently log file . See example below. | File name of external file. |
incMsg | Includes the contents of an external file in the currently listing file . See example below. | File name of external file. |
incMsgLog | Includes the contents of an external file in both, the log file and the listing file. See example below. | File name of external file. |
log | Sends a message to the log file. See example below. | Text of message. |
msg | Sends a message to the listing file. See example below. | Text of message. |
msgLog | Sends a message to both, the log file and the listing file. See example below. | Text of message. |
ren | Creates a new external name for the current put file. The internal name will reference the new external file. Any subsequent put statements will write to the new file. See the simple example above and a more complex example below. | External file name. |
save | Writes a save file of the current state of execution. | Name of save file. |
setEnv | Sets an environment variable at execution time. | Name of the environment variable and its value. |
shell | Passes a command to the command shell processor, where it is processed. The processed form of the command is then passed to the operating system for execution. See example below. Note that the distinction between shell and exec is technical and may be operating system specific. Typically, the ability to use redirect of standard input output and the error console is involved. | Command to be executed with arguments. |
shell.checkErrorLevel | Passes a command to the command shell processor, where it is processed. The processed form of the command is then passed to the operating system for execution. GAMS checks the errorLevel returned implicitly, raises an execution error and aborts the execution, if is not 0. | Command to be executed with arguments. |
solver | Selects a solver for a given or all model types (use * ) by name. See example below. | Model type or * and solver name. |
stdOut | Sends a message to stdOut independent of the log file. | Text of message. |
stdErr | Sends a message to stdErr independent of the log file. | Text of message. |
title | Changes the title on the DOS window. | New name for window. |
winMsg | Sends a message to a window on a Windows machine. For examples, see models [ASYNNTRP] and [MRW01] in the GAMS Test Library. | Window name and message. |
xsave | Writes a compressed save file of the current state of execution. | Name of compressed save file. |
In the remainder of this section we will present examples.
Exec: Creating Empty Files by Executing External Program touch
Consider the following example:
Set i / 1*3 /;
loop(i, put_utility 'exec' / 'touch ' i.tl:0 '.txt');
Note that the command to be executed is touch
. Thus this code snippet will create three empty files called 1.txt
, 2.txt
and 3.txt
.
Exec and Ren: Creating Directories and Renaming Files
Consider the following example:
File test / test.txt /; put test;
Set i / i01*i07 /;
loop(i,
put_utilities 'exec' / 'mkdir ' 'test-':0 i.tl:0;
put_utilities 'ren' / 'test-':0 i.tl:0 '%system.dirSep%test-':0 i.tl:0 '.txt':0 ;
put 'this should be ' i.tl );
Observe that as the loop is executed, the first put_utitily statement will create seven subdirectories called test-i01
, ..., test-i07
. The second put_utility statement will create a text file for each of the new subdirectories. The text file in subdirectory test-i01
is called test-i01.txt
, the text file in subdirectory test-i02
is called test-i02.txt
, etc. The put statement in the last line will write to each text file. For example, the following line will be generated for the text file test-i01.txt
:
this should be i01
Note that at the end of the loop, the external file associated with the internal file name test
is the put file test-i07.txt
, since this file was the last current put file.
Inc: Including the Content of a File
In this example, we first create the external file recall.txt
, write to it and close it. Then we create a new external file called report.dat
. In a third step we include the content of the first file in the second file.
File recall /recall.txt/;
putclose recall "I am the external content."
File report /report.dat/;
put report "Here we include content from an external file.";
put_utility 'inc' / 'recall.txt' ;
Note that the file report.dat
will contain the following lines:
Here we include content from an external file. I am the external content.
IncMsg, IncLog and IncMsglog: Including the Content of a File to the Log File and Listing file
In this example, we first create the external file recall.txt
, write to it and close it. Then we include the content of recall.txt
into the log and listing file.
File recall /recall.txt/;
putclose recall "I am the external content." / "I go over more than one line.";
display 'before the include';
put_utility 'incMsg' / 'recall.txt' ;
display 'after the include';
The listing file of this model shows the content of recall.txt
:
---- 4 before the include *** Start of include of file recall.txt I am the external content. I go over more than one line. *** End of include of file recall.txt ---- 6 after the include
Msg, Log and Msglog: Writing to the Log File and Listing file
Consider the following example:
put_utility 'msg' / 'This message is for the lst file.'
/ 'log' / 'This message is for the log file.'
/ 'msgLog' / 'And this message is for the lst and the log file.' ;
Note that the following two lines will be generated in the log file:
This message is for the log file. And this message is for the lst and the log file.
In addition, the listing file will contain the following two lines just before the report file summary.
This message is for the lst file. And this message is for the lst and the log file.
Gdxout: Creating GDX Files and Unloading Data to them
Consider the following example:
Set j / 2005*2007 /;
Scalar random;
loop(j,
put_utility 'gdxOut' / 'data' j.tl:0;
random = uniform(0,1);
execute_unload random;
);
This code will create the GDX files data2005.gdx
, data2006.gdx
and data2007.gdx
. Note that each GDX file will contain a value between zero and 1 for the scalar random
. For example, the file data2005.gdx
(exported to an ASCII via gdxdump
) will have the following content:
Scalar random / 0.171747132 /;
Gdxin: Loading Data from GDX Files
Note that the following example is an extension of the previous example that demonstrated the use of the command gdxout
.
loop(j,
put_utility 'gdxIn' / 'data' j.tl:0 ;
execute_load random;
display random;
);
This code loads the values of the scalar random
from the GDX files data2005.gdx
, data2006.gdx
and data2007.gdx
and displays them in the listing file of the GAMS input file:
---- 19 PARAMETER random = 0.172 ---- 19 PARAMETER random = 0.843 ---- 19 PARAMETER random = 0.550
Shell: Writing to Various Files
Consider the following example:
Set j / j1*j5 /;
Scalar random;
loop(j,
random = uniformint(0,100);
put_utility 'shell' / 'echo ' random:0:0 ' > ' j.tl:0;
);
Observe that the shell script command echo
outputs an integer between zero and 100 to the files j1
, ..., j5
.
Click: Adding a Clickable Link
Assume that there is a file called sets.html
in our working directory. Consider the following code snippet:
put_utility 'click' / 'sets.html' ;
If we run this code snippet with the GAMS IDE, the following clickable link will appear in the IDE process window:
>>> File sets.html
Solver: Select a solver by name at execution time
The solver
keyword allows to select a solver at execution time by name. Normally, the option statement option solver=xpress, lp=cplex;
is used to select the current solver, but in case where you want to programatically change the solver as in this example, this put_utility keyword can be useful. Consider the following code snippet which extends the [DICE] model:
...
set slv 'MIP solvers to run' / cplex, cbc, gurobi, mosek, scip, xpress /;
parameter rep 'report status, time, objective value, and more';
option bratio=1;
loop(slv,
put_utility 'solver' / 'mip' / slv.tl:0;
solve xdice using mip max wnx;
rep(slv,'sstat') = xdice.solveStat;
rep(slv,'mstat') = xdice.modelStat;
rep(slv,'obj') = xdice.objVal;
rep(slv,'time') = xdice.etSolve;
rep(slv,'solver id') = xdice.sysIdent;
);
display rep;
If we run this code we get a report like this:
---- 82 PARAMETER rep report status, time, objective value, and more sstat mstat obj time solver id cplex 1.000 1.000 21.000 0.455 19.000 cbc 1.000 8.000 21.000 2.804 6.000 gurobi 1.000 1.000 21.000 0.631 32.000 mosek 1.000 1.000 21.000 4.425 48.000 scip 1.000 1.000 21.000 3.907 65.000 xpress 1.000 1.000 21.000 2.571 71.000
If one want's to set a solver for all possible model types (similar to option solver=xpress;
) specific model type has to be replaced by *
: put_utility 'solver' / '*' / 'xpress';
.
AssignText: Assigns label text to an element of a singleton set
GAMS has no string data type. The explanatory or label text of an element can serve in several situations as a poor man's string type and used in put
and put_utility
statements. The example below extends the [TRNSPORT] model and disables flow on a particular connection. The solution point file created by savePoint gets renamed to e.g. sol_seattle_new-york.gdx
. The filename is assembled using the assigntext
keyword. This has been packaged for better readability in some STRING
macros:
...
$macro STRINGDEF(sym) singleton set sym / sym /
$macro STRING(sym) sym.te(sym)
$macro STRINGASSIGN(sym,text) put_utility 'assignText' / 'sym' / text
$macro STRINGAPPEND(sym,text) put_utility 'assignText' / 'sym' / sym.te(sym) text
alias (i,ii), (j,jj);
transport.savePoint = 1;
STRINGDEF(fname);
loop((ii,jj),
x.up(ii,jj) = 0;
solve transport min z using lp;
x.up(ii,jj) = inf;
STRINGASSIGN(fname,'sol');
STRINGAPPEND(fname,'_' ii.tl:0);
STRINGAPPEND(fname,'_' jj.tl:0 '.gdx');
put_utility 'shell' / 'mv transport_p.gdx ' STRING(fname);
);
Conditional Put Statements
In GAMS, shorthand notation for conditional statement are dollar conditions, as introduced in chapter Conditional Expressions, Assignments and Equations. Dollar conditions may also be used in the context of a put statement and its variants. The syntax in its most general form is as follows:
put $ logical_condition [file_name] item {item} {file_name item {item}};
Note that like all put statements, the conditional put statement begins with the keyword put
. The keyword is followed by the dollar operator and a logical condition. If the logical condition is TRUE
the put statement will be executed, otherwise the put statement will be ignored. For details on logical conditions in GAMS, see sections Logical Conditions and Filtering Sets. Observe that the remainder of the conditional put statement is identical to the regular put statement introduced in section The Put Statement.
The following example demonstrates how dollar conditions are used in the context of put statements.
put$(a > 10) 'Some output items';
Note that the quoted text will only be written to the put file if the scalar or variable a
is greater than 10.
Errors Associated with Put Statements
There are two types of errors that may occur when the put writing facility is used: syntax errors and put errors. In this section we will discuss these errors.
Syntax Errors in Put Statements
Syntax errors are caused by the incorrect usage of the GAMS language, including unmatched parentheses, undefined identifiers, uncontrolled sets or the incorrect use of a keyword. These errors are detected during program compilation and are always fatal to program execution. For more information on compilation errors, see section Compilation Errors and the tutorials A GAMS Tutorial by Richard E. Rosenthal and Fixing Compilation Errors.
Put Errors
Put errors are unique to the put writing facility. They are detected during program execution and are caused when the specifications of file attributes are violated. Typical errors include assigning inappropriate values to file attributes and attempts to write outside a page, like moving the cursor with the cursor control character @
to a location beyond the page width. Consider the following example:
File out /out.dat/;
out.pw = 8;
put out "Let's try this.";
Note that we specify the page width (.pw
) to be just 8 characters. However, the quoted text has clearly more than 8 characters. In such a case the GAMS code will be compiled and the log file will report "Normal completion". At the appropriate position in the listing file the following error will be reported:
**** PUT ERROR FOR FILE out AT LINE 5: PUT LINE OVERFLOW - LOOK FOR **** ON PUTFILE, YOU CAN RESET .PW UP TO 32767
The put file out.dat
will contain the following line:
Let'****
As put errors are not fatal and are not emphasized in the log file, they may be easily overlooked. Especially in large put files, put errors may go undetected. GAMS provides the file attribute .errors
that facilitates the display of the numer of put errors. Consider the following example:
File out /out.dat/;
out.pw = 8;
put out "Let's try this.";
abort$(out.errors) "Put errors in out:", out.errors;
Users may choose to output the number of put errors in a put file or display statement or even trigger an execution error as in the example above.
Creating a Report for the Model MEXSS
We started this chapter with a simple example and we will complete it with a more elaborate example. In this section we will show how the put writing facility may be used to create a report for the model [MEXSS]. The code for the report may be inserted at the end of the original model and is shown below in its entirety.
The model [MEXSS] analyzes the relative efficiency of five different plants for meeting the product requirements of ingot steel in three different markets. The model may be used to identify the major bottlenecks that constrain production in the system of plants. It will find the production levels in the steel mills and shipments from the mills to the markets that will meet the market requirements at least cost. We will create a report for this model that will present details on the available capacities of the productive units at the five plants, the unused capacities and the marginal values of the capacities. This report may be extended to include other data and results and the code may be reused to create new reports if the data in the model is changed. For models that are run periodically, say, weekly or monthly, reusable reports can be invaluable.
We will start the code for the report with defining the put file, setting the file attributes print control and page size and making the the put file current. Then we will specify some global formatting settings. We will continue with writing a title block and finally turn to the core of the report: a table with three subtables. Note that we will use in-line comments to annotate the code. The code follows:
$eolcom //
File out /out.dat/;
out.pc=3; out.ps=54; // print control, page size
put out;
* Global Format Settings:
Scalars indent1 indent to first column of units display
indent2 indent to first column of field labels
indent3 indent to first column of first numeric field
textwide wide text / 80 /
textnarr narrow text / 30 / ;
out.nr = 0; // numeric round format
out.tw = textwide; // width of text field
out.lw = 11; // width of label field
out.nw = 11; // width of numeric field
out.nd = 2; // number of decimals displayed
indent1 = 3;
indent2 = 30;
indent3 = 27;
* Title Block
puttl 'MEXICO STEEL - SMALL STATIC MODEL':<> /
system.date:<>/ / /;
* Main Window
out.tj = 3; // alignment of text: center
put
' This report is based on selected data and results from the model'/
'MEXSS in the GAMS Library. This model analyzes the relative efficiency'/
'of five different plants in meeting the product requirements for ingot'/
'steel in three different markets. The model aims to find the pattern '/
'of production levels in the mills and shipments from the mills to the '/
'markets that will meet the market requirements at the least cost. '/
/
'Reference: Kendrick, D. A., Meeraus, A., Alatorre J., The Planning '/
'of Investment Programs in the Steel Industry, John Hopkins Universi-'/
'ty Press, 1984. '/
/ / /;
out.tj = 2; // alignment of text: left
out.tw = textnarr; // width of text field
putpage$(out.ll+card(m)+7 > out.ws); // manual paging
put 'Table 1. Plant Data and Results':0 /'-------'/; // Table 1
out.cc = indent2; // current column
loop(i, put i.tl:<>); // column headings
put / / 'CAPACITY (metric tons)'; // Capacity
loop(m,
put / @indent1, m.te(m), @indent3; // row headings
loop(i, put k(m,i)); // numeric values
);
* Header Block with column headings for next page (will be used only if necessary)
puthd 'Table 1 (continued). Plant Data and Results':0 /
'-------------------'/;
out.hdcc = indent2;
loop(i, put i.tl:<>); // column headings
puthd /'';
* Main Window continued
if(out.ll+card(m)+sum((m,p)$b(m,p), 1)+3 > out.ws,
putpage; // manual paging
else put / /;
);
put 'UNUSED CAPACITY (metric tons)'; // Unused Capacity
loop(m,
put / @indent1, m.te(m), @indent3; // row headings
loop(i, put (k(m,i)-cc.l(m,i))); // numeric values
);
if(out.ll+card(m)+4 > out.ws,
putpage; // manual paging
else put / /;
);
put 'MARGINAL VALUE OF CAPACITY'/ @indent1 '(US$/ton)'; // Marginal Value of Capacity
loop(m,
put / @indent1, m.te(m), @indent3; // row headings
loop(i, put abs(cc.m(m,i))); // numeric values
);
Note that we set print control (.pc
) to ASCII formfeed. Below we illustrate how to use one of the print control settings that generate a delimited file. Observe that we group all global format parameters and settings near the top of the code. This way of organizing the code will make it easy to modify the structure of the report in the future as needed. Observe further, that the output items in the title block are locally formatted to be center aligned.
In the remainder of the code the actual report is written in the main window. The block of text at the beginning serves as a brief introduction to the report. Note that the core of the report is a table consisting of three subtables, where the subtables share the column headings. Before writing the table, we insert a test - the conditional putpage statement - to determine whether there is a sufficient number of lines on the current page to accommodate the size of the first subtable. Thus the put writing facility would start a new page if there were not enough rows. We repeat similar tests before the code for the other two subtables. Observe that we insert a header block with the column headings. If a new page had to be started since there were not enough rows for the second or the third subtable, the header block would contain the column headings of the table. (Users might want to experiment by reducing the file attribute page size (.ps
) to say, 30.) The report that will be generated follows:
MEXICO STEEL - SMALL STATIC MODEL 01/31/17 This report is based on selected data and results from the model MEXSS in the GAMS Library. This model analyzes the relative efficiency of five different plants in meeting the product requirements for ingot steel in three different markets. The model aims to find the pattern of production levels in the mills and shipments from the mills to the markets that will meet the market requirements at the least cost. Reference: Kendrick, D. A., Meeraus, A., Alatorre J., The Planning of Investment Programs in the Steel Industry, John Hopkins Universi- ty Press, 1984. Table 1. Plant Data and Results ------- ahmsa fundidora sicartsa hylsa hylsap CAPACITY (metric tons) blast furnaces 3.25 1.40 1.10 0.00 0.00 open hearth furnaces 1.50 0.85 0.00 0.00 0.00 basic oxygen converters 2.07 1.50 1.30 0.00 0.00 direct reduction units 0.00 0.00 0.00 0.98 1.00 electric arc furnaces 0.00 0.00 0.00 1.13 0.56 UNUSED CAPACITY (metric tons) blast furnaces 0.13 0.00 0.00 0.00 0.00 open hearth furnaces 0.00 0.00 0.00 0.00 0.00 basic oxygen converters 0.00 0.72 0.14 0.00 0.00 direct reduction units 0.00 0.00 0.00 0.00 0.39 electric arc furnaces 0.00 0.00 0.00 0.23 0.00 MARGINAL VALUE OF CAPACITY (US$/ton) blast furnaces 0.00 69.62 71.69 0.00 0.00 open hearth furnaces 53.76 1.72 2.09 138.03 145.02 basic oxygen converters 64.57 0.00 0.00 138.03 145.02 direct reduction units 0.00 0.00 0.00 80.08 0.00 electric arc furnaces 136.46 138.03 140.00 0.00 94.28
Assume we need the data reported in the first subtable above in a delimited file format in order to import it to other applications, like spreadsheets or databases. Consider the following code:
file out2 / 'out2.csv' /; out2.pc=5; put out2 'capacity (metric tons)'; loop(i, put i.tl); loop(m, put / m.te(m); loop(i, put k(m,i)); );
Note that we set the file attribute page control (.pc
) to 5. This means that non-numeric output items will be quoted and each output item will be delimited with commas. Observe that field widths, alignments and horizontal cursor relocations were completely avoided. The put file out2.put
will contain the following lines:
"capacity (metric tons)","ahmsa","fundidora","sicartsa","hylsa","hylsap" "blast furnaces",3.25,1.40,1.10,0.00,0.00 "open hearth furnaces",1.50,0.85,0.00,0.00,0.00 "basic oxygen converters",2.07,1.50,1.30,0.00,0.00 "direct reduction units",0.00,0.00,0.00,0.98,1.00 "electric arc furnaces",0.00,0.00,0.00,1.13,0.56
While a comma is the most commonly used delimiting character, other delimiters like a blank space (.pc=4
) and a tab (.pc=6
) may also be used.
For other examples of code that uses the put writing facility, see the various models in the GAMS Model Library.