The GAMS modeling language is a domain specific language tailored towards mathematical optimization. The language reflects the basic building blocks (symbols) of an algebraic optimization model:
While declaring the symbols in the GAMS language is rather straightforward and concise, defining their values (which must be done prior to running the optimization for exogenous symbols like sets, parameters and scalars) might be comparatively cumbersome. In many applications, the actual data for the symbols is also already stored in some other location like a file or database. In order to have an efficient way to load data into a model, store the solution results and in general exchange information with other applications, the GDX file format was conceived.
Information contained inside a GDX fileRecords are mapping from the domain of the symbol to the value space with up to 5 fields (level, marginal, lower bound, upper bound, scale)
The actual data might be stored verbatim or compressed (using zlib).
Please note: a GDX file does not store a model formulation or executable statements.
For efficiency reasons (both read/write-speeds and disk usage) the GDX format is a binary format that cannot be easily processed using a text editor. Hence, looking at the contents of a GDX file is ideally done via a graphical user interface like the GDX viewer included in GAMS Studio or the gdxdump
console utility included in the GAMS distribution. In order to write conversion utilities between GDX and various other data file formats, an API is needed. This API has the following features:
The GDX API is very powerful with fine-grained control and is also used at GAMS internally.
Setting up and building GDX Accessing GDX from a custom applicationThe GDX API can be directly accessed from C/C++ via the library contained in this repository. Although there is a main GDX object for representing a file in this interface, it is mostly procedural and offers many functions operating on elementary data types instead of a sophisticated class hierarchy.
For an easier to use object-oriented interface GAMS offers wrappers for multiple programming languages including:
Even more abstraction is offered by the GAMS Transfer libraries for Python and R.
The GDX library is written in C++17 and built via CMake.
The fastest way to build the GDX library (static and dynamic) locally is by running the following spells:
git clone https://github.com/GAMS-dev/gdx.git
cd gdx
git clone https://github.com/madler/zlib zlib
cmake -DNO_TESTS=ON -DNO_EXAMPLES=ON -DNO_TOOLS=ON .
cmake --build .
Running this on Linux creates the dynamic library libgdxcclib64.so
and the static library libgdx-static.a
.
This repository contains a GitLab CI YAML that describes a pipeline which
Please run
git clone https://github.com/madler/zlib zlib
inside the root-directory of the gdx
-repository to make the zlib compression library available.
doctest and apigenerator are included in this repo (as file and submodule respectively).
Dependencies:
Build tools:
A full detailed Doxygen-generated API reference is available here.
Introduction into using GDX APIThis document describes the Application Programmers Interface (API) for the GDX library. The GDX library is used to read or write GDX files. A GDX file is a file that stores the values of one or more GAMS symbols such as sets, parameters, variables, and equations. GDX files can be used to prepare data for a GAMS model, present results of a GAMS model, store results of the same model using different parameters etc. A GDX file does not store a model formulation or executable statements.
GDX files are binary files that are portable between different platforms. They are written using the byte ordering native to the hardware platform they are created on, but can be read on a platform using a different byte ordering.
To read or write data, we need to be able to reference the set elements used to represent the index space for symbols with one or more dimensions. The API provides three interface models for this purpose:
n
dimensional element is represented as an array of strings.n
dimensional element is represented as an array of integers. The integer used for each index position is obtained from the API after registering the string representation with the API.n
dimensional element is represented as an array of integers. The integer used for each index position is defined by the user. Before such an element can be used, its value and string has to be registered.Creating a GDX file and writing one or more symbols to the file requires a number of steps:
Steps 3 - 6 can be repeated to write any number of symbols to the file. Once a symbol has been written to the file, it cannot be replaced. Currently, there are no facilities to overwrite a symbol or append data to an existing file.
The following sections illustrate the basic steps for each type of interface. The method of writing (string, raw, or mapped) can be selected for each symbol; it cannot be changed while writing a symbol.
Most code samples reference the following auxiliary function ReportGDXError
to report the latest GDX error when the most recent call to the GDX API has reported a problem (usually by returning false
).
void ReportGDXError(TGXFileObj &gdx) { std::array<char, GMS_SSSIZE> S; std::cout << "**** Fatal GDX Error" << std::endl; gdx.gdxErrorStr(gdx.gdxGetLastError(), S.data()); std::cout << "**** " << S.data() << std::endl; exit(1); }Writing data using strings
The String based interface is suitable when we want to use a string based index and do not want to maintain a mapping from strings to integers.
Before writing data using a string based interface we can register strings for the unique elements, but this step is optional. The only reason to register the strings beforehand is to enter the strings in a given order which may have advantages later in the modelling stage.
if(!gdx.gdxDataWriteStrStart("Demand","Demand data",1,dt_par,0)) ReportGDXError(); IndxS[0] = "New-York"; Values[0] = 324.0; gdx.gdxDataWriteStr(IndxS,Values); IndxS[0] = "Chicago"; Values[0] = 299.0; gdx.gdxDataWriteStr(IndxS,Values); if(!gdx.gdxDataWriteDone()) ReportGDXError();
In this example we write two records for a parameter that has a dimension of one.
Writing data using integers (raw)The Raw interface is suitable when we want to manage our own list of unique elements, and use an integer based index. The Raw interface assumes that the integers assigned to the strings range from one to the number of strings registered.
Before we can write data using the Raw interface, we have to register the strings for the unique elements. The GDX routines will assign an integer to the string that increases by one for every string registered.
if(!gdx.gdxUELRegisterRawStart()) ReportGDXError(); gdx.gdxUELRegisterRaw("New-York"); gdx.gdxUELRegisterRaw("Chicago"); if(!gdx.gdxUELRegisterDone()) ReportGDXError(); if(!gdx.gdxDataWriteRawStart("Demand","Demand data",1,dt_par,0)) ReportGDXError(); IndxI[0] = 1; Values[0] = 324.0; gdx.gdxDataWriteRaw(IndxI,Values); IndxI[0] = 2; Values[0] = 299.0; gdx.gdxDataWriteRaw(IndxI,Values); if(!gdx.gdxDataWriteDone()) ReportGDXError();Writing data using integers (mapped)
The Mapped interface is suitable when we want to manage our own list of unique elements, and use an integer based index. The mapped interface lets us select our own mapping between strings for the unique elements and their integer equivalent. The integers assigned to the unique elements should be greater equal one, and be unique for each element.
Before we can write data using the Mapped interface, we have to register the strings for the unique elements.
if(!gdx.gdxUELRegisterMapStart()) ReportGDXError(); gdx.gdxUELRegisterMap(1000,"New-York"); gdx.gdxUELRegisterMap(2000,"Chicago"); if(!gdx.gdxUELRegisterDone()) ReportGDXError(); if(!gdx.gdxDataWriteMapStart("Demand","Demand data",1,dt_par,0)) ReportGDXError(); IndxI[0] = 1000; Values[0] = 324.0; gdx.gdxDataWriteRaw(IndxI,Values); IndxI[0] = 2000; Values[0] = 299.0; gdx.gdxDataWriteRaw(IndxS,Values); if(!gdx.gdxDataWriteDone()) ReportGDXError();
In this example we register two unique elements, and write a parameter of dimension one.
Reading data from a GDX fileOpening an existing GDX file and reading one or more symbols from the file requires a number of steps:
Steps 3 - 6 can be repeated to read any number of symbols from the file.
The following sections illustrate the basic steps for each type of interface. The method of writing (string, raw or mapped) can be selected for each symbol; it cannot be changed while writing a symbol.
Reading data using stringsReading data using strings does not require any unique element registration.
if(!gdx.gdxFindSymbol("x",SyNr)) { std::cout << "**** Could not find symbol X" << std::endl; exit(1); } gdx.gdxSymbolInfo(SyNr,SyName,SyDim,SyTyp); if(SyDim != 1 || SyTyp != dt_par) { std::cout << "**** X is not a one dimensional parameter" << std::endl; exit(1); } if(!gdx.gdxDataReadStrStart(SyNr,NrRecs)) ReportGDXError(); std::cout << "Parameter X has " << NrRecs << " records" << std::endl; while(gdx.gdxDataReadStr(IndxS,Values,N)) std::cout << "Record = " << IndxS[0] << " " << Values[0] << '\n'; if(!gdx.gdxDataReadDone()) ReportGDXError();
In this example we find the symbol by its name, and before reading the data we verify that the symbol represents a one dimensional parameter.
Reading data using integers (raw)Reading data using integers in Raw mode does not require the registration of unique elements. The read routine returns an integer for which we can find the string representation.
if(!gdx.gdxFindSymbol("x",SyNr) { std::cout << "**** Could not find symbol X" << std::endl; exit(1); } gdx.gdxSymbolInfo(SyNr,SyName,SyDim,SyTyp); if(SyDim != 1 || SyTyp != dt_par) { std::cout << "**** X is not a one dimensional parameter" << std::endl; exit(1); } if(!gdx.gdxDataReadRawStart(SyNr,NrRecs)) ReportGDXError(); std::cout << "Parameter X has ",NrRecs," records"); while(gdx.gdxDataReadRaw(IndxI,Values,N)) { std::cout << "Record = " << IndxI[0] << " = " << Values[0]; gdx.gdxUMUelGet(IndxI[0],S,UsrMap); std::cout << " with string = " << S << '\n'; } if(!gdx.gdxDataReadDone()) ReportGDXError();
In this example we find the symbol by its name, and before reading the data we verify that the symbol represents a one dimensional parameter. When reading the data, we get a unique element as an integer. The integer value is used to get the corresponding string for the unique element.
Reading data using integers (Mapped)Reading data using integers in Mapped mode requires the registration of unique elements. The read routine returns an integer for which we can find the string representation.
When the gdx file contains data elements that we never registered, the read function will not return these elements, they will be added to an internal list of error records instead.
if(!gdx.gdxUELRegisterMapStart()) ReportGDXError(); gdx.gdxUELRegisterMap(1000,"New-York"); gdx.gdxUELRegisterMap(2000,"Chicago"); if(!gdx.gdxUELRegisterDone()) ReportGDXError(); if(!gdx.gdxFindSymbol("x",SyNr)) { std::cout << "**** Could not find symbol X" << std::endl; exit(1); } gdx.gdxSymbolInfo(SyNr,SyName,SyDim,SyTyp); if(SyDim != 1 || SyTyp != dt_par) { std::cout << "**** X is not a one dimensional parameter" << std::endl; exit(1); } if(!gdx.gdxDataReadMapStart(SyNr,NrRecs)) ReportGDXError(); std::cout << "Parameter X has " << NrRecs << " records" << std::endl; for(int N{}; N<NrRecs; N++) { if(gdx.gdxDataReadMap(N,IndxI,Values,N)) { std::cout << "Record = " << N << " " << IndxI[0] << " = " << Values[0]; GetUEL(gdx,IndxI[0],S); std::cout << " with string = " << S << '\n'; } } if(!gdx.gdxDataReadDone()) ReportGDXError(); NrRecs = gdx.gdxDataErrorCount(); if(NrRecs > 0) std::cout << NrRecs << " records were skipped" << std::endl;
In this example we register a few unique elements using our \own integer values. After verifying that we can find the symbol and that the symbol represents a one dimensional parameter we can read the data. The index for the parameter is returned using the integers we used when registering our elements. When we read the records in sequence, the index returned will be sorted with the first index position the most significant.
After reading the data, we print the number of records that were skipped in the read routine.
Reading data using a filterReading data using a filter allows us to control the action for every index position. The type of action is specified using action codes and needs to be specified for every index position. The actual reading of the records is done with the gdxDataReadMap function.
Action code Description UnMapped (-2) No mapping is performed; the value of the unique element is the value as stored in the GDX file. Use gdxUMUelGet to get the string representation. Checked (0) Map the unique element value to the user defined value. Use gdxGetUEL to get the string representation. If a user mapping was not defined for this element,Referring to the following GAMS fragment, we want to read the parameter A
. The set I
is the domain for the first index; there is no domain for the second index position:
Set I /.../;
Parameter A(I,*);
Assuming we have read set I
already, the following code snapshot illustrates how to read parameter A
.
// We wish to only read the values of A when the first label is either "New-York" or "Chicago" // For this, we assign a unique value to each one of the label, here we choose 1000 and 2000 // Then, we register a filter with a unique ID, here 123. // Note that a filter ID cannot be reused. The filter is immutable after its creation gdx.gdxUELRegisterMapStart(); gdx.gdxUELRegisterMap( 1000, "New-York" ); gdx.gdxUELRegisterMap( 2000, "Chicago" ); gdx.gdxUELRegisterDone(); // Register the filter for set I; reference this filter with integer 123 (filter number) if(!gdx.gdxFilterRegisterStart(123)) ReportGDXError(); gdx.gdxFilterRegister(1000); gdx.gdxFilterRegister(2000); if(!gdx.gdxFilterRegisterDone()) ReportGDXError(); // set the filter actions std::array filterAction { 123, //filter for I gdx::DOMC_EXPAND // expand (=-1) }; // Remember highest mapped value in variable LastMapped int NrUnMapped, LastMapped; gdx.gdxUMUelInfo(NrUnMapped, LastMapped); // Read parameter A as a 2 dimensional parameter int SyNr; if(!gdx.gdxFindSymbol("A", SyNr) { std::cout << "**** Could not find symbol A" << std::endl; exit(1); } std::array<char, GMS_SSSIZE> SyName; int SyDim, SyTyp; gdx.gdxSymbolInfo(SyNr, SyName.data(), SyDim, SyTyp); if(SyDim != 2 || SyTyp != dt_par) { std::cout << "**** A is not a two dimensional parameter" << std::endl; exit(1); } int NrRecs; if(!gdx.gdxDataReadFilteredStart(SyNr, filterAction.data(), NrRecs)); ReportGDXError(); int DimFrst; for(int N{1}; N<=NrRecs; N++) { if(gdx.gdxDataReadMap(N, IndxI, Values, DimFrst)) { // do something to process the record read (index, values) } } if(!gdx.gdxDataReadDone() ReportGDXError(); // see if there are new unique elements int NewLastMapped; gdx.gdxUMUelInfo(NrUnMapped, NewLastMapped); if(NewLastMapped > LastMapped) { for(int N{LastMapped + 1}; N<=NewLastMapped; N++) { std::array<char, GMS_SSSIZE> S {}; gdx.gdxGetUel(N,S.data()); std::cout << "New element " << N << " = " << S.data() << '\n'; } }
A runnable version of this example can be found in the unit test suite under /src/tests/gdxtests.cpp
as test case with the name "Test filter example from README".
In GAMS we can use acronyms in places where we can use a floating point number as in the following example:
set i /i1*i5/;
acronym acro1, acro2;
parameter A(i) /i1=1, i2=acro1, i3=3, i4=acro2, i5=5/;
display A;
The result of the display statement looks like:
---- 4 PARAMETER A
i1 1.000, i2 acro1, i3 3.000, i4 acro2, i5 5.000
As we write data to a GDX file, the system keeps track which acronyms were used in the data written. Before we close the GDX file, we share the identifiers used for each acronym used. When reading a GDX file, we share all acronym identifiers and their corresponding index before reading any data. Doing so will replace the acronym indices stored in the GDX file by the one we provide.
The example below illustrates these steps.
TGXFileObj gdx; TgdxUELIndex UELS; TgdxValues Vals; int FDim, N, NrRecs, ErrNr, acrindx; std::array<char, GMS_SSSIZE> ErrMsg, acrtext, acrname; //Check the library if(!gdxGetReadyX(ErrMsg)) { std::cout << "Error loading GDX library, msg = " << ErrMsg << std::endl; exit(1); } //Create GDX object and open file for writing gdx.gdxCreateX( ErrMsg); gdx.gdxOpenWriteEx( "test.gdx", "testing", 0, ErrNr); //register some unique elements gdx.gdxUELRegisterRawStart(); for(int N{}; N<5; N++) gdx.gdxUELRegisterRaw( "uel" + std::to_string(N)); gdx.gdxUELRegisterDone(); //write a parameter with two acronyms gdx.gdxDataWriteRawStart( "symb1", "text for symb1", 1, dt_par, 0); for(int N{}; N<5; N++) { UELS[0] = N; Vals[vallevel] = (N == 1 || N == 3) ? gdx.gdxAcronymValue( N) : N; gdx.gdxDataWriteRaw( UELS, Vals); } gdx.gdxDataWriteDone(); //provide the names for the acronyms used for(int N{}; N<gdx.gdxAcronymCount(); N++) { gdx.gdxAcronymGetInfo( N, acrname, acrtext, acrindx); if(acrindx == 2) gdx.gdxAcronymSetInfo( N, "acro1", "Some text for acro1", acrindx) else if(acrindx == 4) gdx.gdxAcronymSetInfo( N, "acro2", "Some text for acro2", acrindx) } //final check for errors before we close the file N = gdx.gdxClose(); if(N) { gdxErrorStr(Nil, N, ErrMsg); std::cout << "Error writing file = " << ErrMsg << std::endl; exit(1); } gdx.gdxFree(); //open the file we just created gdx.gdxCreateX( ErrMsg); gdx.gdxOpenRead( "test.gdx", ErrNr); if(ErrNr) { std::cout << "Error opening file, nr = " << ErrNr << std::endl; exit(1); } //give acronym indices using the name of the acronym gdx.gdxAcronymSetInfo( 1, "acro1", "", 1000); gdx.gdxAcronymSetInfo( 2, "acro2", "", 1001); //read the parameter gdx.gdxDataReadRawStart( 1, NrRecs); while(gdx.gdxDataReadRaw( UELs, Vals, FDim)) { N = gdx.gdxAcronymIndex( Vals[vallevel]); if(!N) std::cout << Vals[vallevel]) else std::cout << "Acronym: index = " << N << '\n'; } gdx.gdxDataReadDone(); ErrNr = gdx.gdxClose(); //final error check before closing the file if(ErrNr) { gdxErrorStr(nil, ErrNr, ErrMsg); std::cout << "Error reading file = ", ErrMsg); exit(1); } gdx.gdxFree();
The following table organizes the functions by category:
Category Functions File (Open/Close) gdxOpenRead gdxOpenWrite gdxClose System/Symbol gdxSystemInfo gdxSymbolInfo gdxSymbolInfoX Information gdxFindSymbol gdxGetUEL Unique elements gdxUELRegisterRawStart gdxUELRegisterMapStart gdxUELRegisterStrStart gdxUELRegisterRaw gdxUELRegisterMap gdxUELRegisterStr gdxUELRegisterDone gdxGetUEL gdxUMUelInfo gdxUMUelGet gdxUMFindUEL Write Data gdxDataWriteRawStart gdxDataWriteMapStart gdxDataWriteStrStart gdxDataWriteRaw gdxDataWriteMap gdxDataWriteStr gdxDataWriteDone Read Data gdxDataReadRawStart gdxDataReadMapStart gdxDataReadStrStart gdxDataReadRaw gdxDataReadMap gdxDataReadStr gdxDataReadFilteredStart gdxDataReadDone gdxDataErrorCount gdxDataErrorRecord Text for UELs gdxAddSetText gdxSetTextNodeNr gdxGetElemText gdxSetHasText Filters gdxFilterRegisterStart gdxFilterRegister gdxFilterRegisterDone gdxFilterExists Special values gdxResetSpecialValues gdxSetSpecialValues gdxGetSpecialValues gdxMapValue Errors gdxGetLastError gdxErrorCount gdxErrorStr Version/Information gdxSetTraceLevel gdxFileVersion gdxGetDLLVersion Longest symbol UEL gdxSymbMaxLength gdxUELMaxLength gdxSymbIndxMaxLength Acronyms gdxAcronymIndex gdxAcronymValue gdxAcronymCount gdxAcronymGetInfo gdxAcronymSetInfoSome GDX operations only make sense after running other routines for preparation beforehand. For example, writing records to a symbol in raw mode can only be done after the symbol has been "opened" for writing in raw mode. Hence, the GDX operations follow a state machine like logic that prevents the user from executing operations that are not sensible in the current state of the GDX object. The routines documented below follow certain input / output state transitions. Routines not documented below have no special state requirements.
Diagram for general operationsgraph TD f_notopen -->|gdxOpenRead| fr_init f_notopen -->|gdxOpenWrite| fr_init f_notopen -->|gdxOpenWriteEx| fr_init f_init -->|gdxClose| f_notopen fw_init -->|gdxClose| f_notopen fr_init -->|gdxSymbMaxLength| fr_init fr_init -->|gdxUELMaxLength| fr_init fr_init -->|gdxSymbIndxMaxLength| fr_init fr_init -->|gdxAcronymSetInfo| fr_init fw_init -->|gdxAcronymSetInfo| fw_initLoading Diagram for read operations
graph TD fr_init -->|gdxDataReadRawStart*| fr_raw_data fr_init -->|gdxDataReadMapStart*| fr_map_data fr_init -->|gdxDataReadStrStart*| fr_str_data fr_init -->|gdxDataReadFilteredStart*| fr_map_data fr_raw_data -->|gdxDataReadRaw**| fr_raw_data fr_raw_data -->|gdxDataReadRaw**| fr_init fr_map_data -->|gdxDataReadMap**| fr_map_data fr_map_data -->|gdxDataReadMap**| fr_init fr_str_data -->|gdxDataReadStr**| fr_str_data fr_str_data -->|gdxDataReadStr**| fr_init fr_raw_data -->|gdxDataReadDone| fr_init fr_map_data -->|gdxDataReadDone| fr_init fr_str_data -->|gdxDataReadDone| fr_init fr_init -->|gdxFilterRegisterStart| fr_filter fr_filter -->|gdxFilterRegister| fr_filter fr_filter -->|gdxFilterRegisterDone| fr_init fr_init -->|gdxFilterExists| fr_initLoading
*
denotes symbol having data. Transition to fr_init
if the symbol is empty.**
stay in fr_{raw,map,str}_data
iff. there are more records to read, move to fr_init
otherwise.graph TD fw_init -->|gdxDataWriteRawStart| fw_raw_data fw_init -->|gdxDataWriteMapStart| fw_map_data fw_init -->|gdxDataWriteStrStart| fw_str_data fw_raw_data -->|gdxDataWriteRaw| fw_raw_data fw_map_data -->|gdxDataWriteMap| fw_map_data fw_str_data -->|gdxDataWriteStr| fw_str_data fw_raw_data -->|gdxDataWriteDone| fw_init fw_map_data -->|gdxDataWriteDone| fw_init fw_str_data -->|gdxDataWriteDone| fw_initLoading Diagram for UEL operations
graph TD fr_init -->|gdxUELRegisterRawStart| f_raw_elem f_raw_elem -->|gdxUELRegisterRaw| f_raw_elem fr_init -->|gdxUELRegisterRawStart| f_map_elem f_map_elem -->|gdxUELRegisterRaw| f_map_elem fr_init -->|gdxUELRegisterRawStart| f_str_elem f_str_elem -->|gdxUELRegisterRaw| f_str_elem f_raw_elem -->|gdxUELRegisterDone| fr_init f_map_elem -->|gdxUELRegisterDone| fr_init f_str_elem -->|gdxUELRegisterDone| fr_initLoading
In this modified version of the trnsport.gms model, we use an external program to generate data for the demand parameter. After we solve the model, we write the solution to a GDX file, and call the external program again to read the variable from the GDX file.
$Title trnsport model using gdx files
$EOLCOM //
Sets
i canning plants / seattle, san-diego /
j markets / new-york, chicago, topeka / ;
Parameter
a(i) capacity of plant i in cases
/ seattle 350
san-diego 600 /
b(j) demand at market j in cases ;
Table d(i,j) distance in thousands of miles
new-york chicago topeka
seattle 2.5 1.7 1.8
san-diego 2.5 1.8 1.4 ;
Scalar f freight in dollars per case per thousand miles /90/ ;
Parameter c(i,j) transport cost in thousands of dollars per case ;
c(i,j) = f * d(i,j) / 1000 ;
Variables
x(i,j) shipment quantities in cases
z total transportation costs in thousands of dollars ;
Positive Variable x ;
Equations
cost define objective function
supply(i) observe supply limit at plant i
demand(j) satisfy demand at market j ;
// These lines execute during the compilation phase
// The GAMS system directory is passed the the program so it knows where
// to look for the gdxcclib library
$call 'gdxexdp.exe %gams.sysdir%' // create demand data
$GDXIN demanddata.gdx // open data file
$LOAD b=demand // load parameter b (named 'demand' in file)
$GDXIN // close data file
cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ;
supply(i) .. sum(j, x(i,j)) =l= a(i) ;
demand(j) .. sum(i, x(i,j)) =g= b(j) ;
Model transport /all/ ;
Solve transport using lp minimizing z ;
Display b,x.l, x.m ;
// These lines execute during the execution phase
execute_unload 'results.gdx',x; // write variable x to the gdx file
execute 'gdxexdp.exe %gams.sysdir% results.gdx'; // do something with the solution
/* Use this command to compile the example: cl gdxdumpc.c ../../gmstest/apifiles/C/api/gdxcc.c ../../gmstest/apifiles/C/api/gclgms.c -I../../gmstest/apifiles/C/api/ */ #include <stdio.h> #include <string.h> #include "gdxcc.h" #include "gclgms.h" char *val2str(gdxHandle_t Tptr, double val, char *s) { int sv; if (gdxAcronymName(Tptr, val, s)) { return s; } else { gdxMapValue(Tptr, val, &sv); if (sv_normal != sv) sprintf(s,"%s", gmsSVText[sv]); else sprintf(s,"%g", val); return s; } } int main (int argc, char *argv[]) { int rc,i,j,NrSy,NrUel,ADim,ACount,AUser,AUser2,NRec,FDim,IDum, BadUels=0; int ATyp, ATyp2; char msg[GMS_SSSIZE], FileVersion[GMS_SSSIZE], FileProducer[GMS_SSSIZE], sName[GMS_SSSIZE], sName2[GMS_SSSIZE], sText[GMS_SSSIZE], UelName[GMS_SSSIZE]; gdxHandle_t Tptr=NULL; char DomainIDs[GMS_MAX_INDEX_DIM][GMS_SSSIZE]; char *DP[GMS_MAX_INDEX_DIM]; double Vals[GMS_VAL_MAX], dv[GMS_VAL_MAX]; int Keys[GMS_MAX_INDEX_DIM]; char *dn, c; GDXSTRINDEXPTRS_INIT(DomainIDs,DP); if (argc != 2) { printf("Usage: gdxdumpc gdxfile\n"); exit(1); } gdxCreate (&Tptr,msg,sizeof(msg)); if (NULL==Tptr) { printf("Could not create GDX object:\n%s\n",msg); exit(1); } rc = gdxOpenRead(Tptr, argv[1], &i); if (0==rc) { gdxErrorStr(Tptr,i,msg); printf("Could not read GDX file %s:\n%s (rc=%d)\n",argv[1],msg,rc); exit(1); } rc = gdxGetLastError(Tptr); if (rc) { gdxErrorStr(Tptr,rc,msg); printf("Problems processing GDX file %s:\n%s (rc=%d)\n",argv[1],msg,rc); exit(1); } gdxFileVersion(Tptr, FileVersion, FileProducer); gdxSystemInfo(Tptr,&NrSy,&NrUel); printf("* File version : %s\n",FileVersion); printf("* Producer : %s\n",FileProducer); printf("* Symbols : %d\n",NrSy); printf("* Unique Elements: %d\n",NrUel); /* Acroynms */ for (i=1; i<=gdxAcronymCount(Tptr); i++) { gdxAcronymGetInfo(Tptr, i, sName, sText, &rc); printf("Acronym %s", sName); if (strlen(sText)) printf(" '%s'", sText); printf(";\n"); } /* Symbolinfo */ printf("$ontext\n"); for (i=1; i<=NrSy; i++) { gdxSymbolInfo(Tptr, i, sName, &ADim, &ATyp); gdxSymbolInfoX(Tptr, i, &ACount, &rc, sText); printf("%-15s %3d %-12s %s\n", sName, ADim, gmsGdxTypeText[ATyp],sText); } printf("$offtext\n"); printf("$onempty onembedded \n"); for (i=1; i<=NrSy; i++) { gdxSymbolInfo(Tptr, i, sName, &ADim, &ATyp); gdxSymbolInfoX(Tptr, i, &ACount, &AUser, sText); if (GMS_DT_VAR == ATyp || GMS_DT_EQU == ATyp) printf("$ontext\n"); if (GMS_DT_VAR == ATyp) { if (AUser < 0 || AUser>=GMS_VARTYPE_MAX) AUser = GMS_VARTYPE_FREE; memcpy(dv,gmsDefRecVar[AUser],GMS_VAL_MAX*sizeof(double)); dn = (char *) gmsVarTypeText[AUser]; } else if (GMS_DT_EQU == ATyp) { if (AUser < 0 || AUser>=GMS_EQUTYPE_MAX) AUser = GMS_EQUTYPE_E; memcpy(dv,gmsDefRecEqu[AUser],GMS_VAL_MAX*sizeof(double)); } else dv[GMS_VAL_LEVEL] = 0.0; if (0 == ADim && GMS_DT_PAR == ATyp) /* Scalar */ printf("Scalar"); else { if (GMS_DT_VAR == ATyp) printf("%s ",dn); printf("%s",gmsGdxTypeText[ATyp]); } if (GMS_DT_ALIAS == ATyp) { gdxSymbolInfo(Tptr, AUser, sName2, &j, &ATyp2); printf(" (%s, %s);\n", sName, sName2); } else { printf(" %s", sName); if (ADim > 0) { gdxSymbolGetDomain(Tptr, i, Keys); printf("("); for (j=0; j<ADim; j++) { if (Keys[j]==0) strcpy(sName,"*"); else gdxSymbolInfo(Tptr, Keys[j], sName, &AUser2, &ATyp2); if (j < ADim-1) printf("%s,",sName); else printf("%s)",sName); } } if (strlen(sText)) printf(" '%s'", sText); } if (0 == ACount) { if (0 == ADim && GMS_DT_PAR == ATyp) /* Scalar */ printf(" / 0.0 /;\n"); else if (GMS_DT_ALIAS != ATyp) printf(" / /;\n"); } else { printf(" /\n"); gdxDataReadRawStart (Tptr, i, &NRec); while (gdxDataReadRaw(Tptr,Keys,Vals,&FDim)) { if ((GMS_DT_VAR == ATyp || GMS_DT_EQU == ATyp) && 0 == memcmp(Vals,dv,GMS_VAL_MAX*sizeof(double))) /* all default records */ continue; if (GMS_DT_PAR == ATyp && 0.0 == Vals[GMS_VAL_LEVEL]) continue; for (j=1; j<=ADim; j++) { if (1==gdxUMUelGet(Tptr, Keys[j-1], UelName, &IDum)) printf("'%s'", UelName); else { printf("L__",Keys[j-1]); BadUels++; } if (j < ADim) printf ("."); } if (GMS_DT_PAR == ATyp) printf(" %s\n", val2str(Tptr, Vals[GMS_VAL_LEVEL], msg)); else if (GMS_DT_SET == ATyp) if (Vals[GMS_VAL_LEVEL]) { j = (int) Vals[GMS_VAL_LEVEL]; gdxGetElemText(Tptr, j, msg, &IDum); printf(" '%s'\n", msg); } else printf("\n"); else if (GMS_DT_VAR == ATyp || GMS_DT_EQU == ATyp) { printf(" ."); c='('; for (j=GMS_VAL_LEVEL; j<GMS_VAL_MAX; j++) { if (Vals[j] != dv[j]) { if (GMS_VAL_SCALE == j && GMS_DT_VAR == ATyp && AUser != GMS_VARTYPE_POSITIVE && AUser != GMS_VARTYPE_NEGATIVE && AUser != GMS_VARTYPE_FREE) printf("%c prior %s", c, val2str(Tptr, Vals[GMS_VAL_SCALE], msg)); else printf("%c %s %s", c, gmsValTypeText[j]+1, val2str(Tptr, Vals[j], msg)); if ( '(' == c) c = ','; } } printf(" )\n"); } } } printf("/;\n"); j=1; while (gdxSymbolGetComment(Tptr, i, j++, msg)) printf("* %s\n", msg); if (GMS_DT_VAR == ATyp || GMS_DT_EQU == ATyp) printf("$offtext\n"); printf("\n"); } printf("$offempty offembedded \n"); if (BadUels > 0) printf("**** %d reference(s) to unique elements without a string representation\n", BadUels); gdxFree(&Tptr); }
/* Use this command to compile the example: cl xp_example1.cpp ../C/api/gdxcc.c -I../C/api */ #include <string> #include <cstring> #include <cstdlib> #include <iostream> #include "gdxcc.h" using namespace std; static gdxStrIndexPtrs_t Indx; static gdxStrIndex_t IndxXXX; static gdxValues_t Values; void ReportGDXError(gdxHandle_t PGX) { char S[GMS_SSSIZE]; cout << "**** Fatal GDX Error" << endl; gdxErrorStr(PGX, gdxGetLastError(PGX), S); cout << "**** " << S << endl; exit(1); } void ReportIOError(int N, const string &msg) { cout << "**** Fatal I/O Error = " << N << " when calling " << msg << endl; exit(1); } void WriteData(gdxHandle_t PGX, const char *s, const double V) { strcpy(Indx[0], s); Values[GMS_VAL_LEVEL] = V; gdxDataWriteStr(PGX, (const char **)Indx, Values); } int main(int argc, char *argv[]) { gdxHandle_t PGX = NULL; char Msg[GMS_SSSIZE], Producer[GMS_SSSIZE], Sysdir[GMS_SSSIZE], VarName[GMS_SSSIZE]; int ErrNr; int VarNr; int NrRecs; int N; int Dim; int VarTyp; int D; if (argc < 2 || argc > 3) { cout << "**** xp_Example1: incorrect number of parameters" << endl; exit(1); } strcpy(Sysdir, argv[1]); cout << "xp_Example1 using GAMS system directory: " << Sysdir << endl; if (!gdxCreateD(&PGX, Sysdir, Msg, sizeof(Msg))) { cout << "**** Could not load GDX library" << endl << "**** " << Msg << endl; exit(1); } gdxGetDLLVersion(PGX, Msg); cout << "Using GDX DLL version: " << Msg << endl; GDXSTRINDEXPTRS_INIT(IndxXXX, Indx); if (2 == argc) { /* Write demand data */ gdxOpenWrite(PGX, "demanddata.gdx", "xp_example1", &ErrNr); if (ErrNr) ReportIOError(ErrNr, "gdxOpenWrite"); if (!gdxDataWriteStrStart(PGX, "Demand", "Demand data", 1, GMS_DT_PAR, 0)) ReportGDXError(PGX); WriteData(PGX, "New-York", 324.0); WriteData(PGX, "Chicago", 299.0); WriteData(PGX, "Topeka", 274.0); if (!gdxDataWriteDone(PGX)) ReportGDXError(PGX); cout << "Demand data written by example1" << endl; } else { gdxOpenRead(PGX, argv[2], &ErrNr); if (ErrNr) ReportIOError(ErrNr, "gdxOpenRead"); gdxFileVersion(PGX, Msg, Producer); cout << "GDX file written using version: " << Msg << endl; cout << "GDX file written by: " << Producer << endl; if (!gdxFindSymbol(PGX, "x", &VarNr)) { cout << "**** Could not find variable X" << endl; exit(1); } gdxSymbolInfo(PGX, VarNr, VarName, &Dim, &VarTyp); if (Dim != 2 || GMS_DT_VAR != VarTyp) { cout << "**** X is not a two dimensional variable: " << Dim << ":" << VarTyp << endl; exit(1); } if (!gdxDataReadStrStart(PGX, VarNr, &NrRecs)) ReportGDXError(PGX); cout << "Variable X has " << NrRecs << " records" << endl; while (gdxDataReadStr(PGX, Indx, Values, &N)) { if (0 == Values[GMS_VAL_LEVEL]) continue; /* skip level 0.0 is default */ for (D = 0; D < Dim; D++) cout << (D ? '.' : ' ') << Indx[D]; cout << " = " << Values[GMS_VAL_LEVEL] << endl; } cout << "All solution values shown" << endl; gdxDataReadDone(PGX); } if (ErrNr = gdxClose(PGX)) ReportIOError(ErrNr, "gdxClose"); return 0; }
Module xp_example1 '/////////////////////////////////////////////////////////////// '// This program generates demand data for a modified version // '// of the trnsport model or reads the solution back from a // '// gdx file. // '// // '// Calling convention: // '// Case 1: // '// Parameter 1: GAMS system directory // '// The program creates a GDX file with demand data // '// Case 2: // '// Parameter 1: GAMS system directory // '// Parameter 2: gdxfile // '// The program reads the solution from the GDX file // '// Paul van der Eijk Jun-12, 2002 // '/////////////////////////////////////////////////////////////// Dim PGX As IntPtr Sub ReportGDXError(ByVal PGX As IntPtr) Dim S As String = String.Empty Console.WriteLine("**** Fatal GDX Error") gdxErrorStr(0, gdxGetLastError(PGX), S) Console.WriteLine("**** " & S) End End Sub Sub ReportIOError(ByVal N As Integer) Console.WriteLine("**** Fatal I/O Error = " & N) End End Sub Sub WriteData(ByVal s As String, ByVal V As Double) Dim Indx(maxdim) As String 'TgdxStrIndex Dim Values(val_max) As Double 'TgdxValues Indx(0) = s Values(val_level) = V gdxDataWriteStr(PGX, Indx, Values) End Sub Dim Msg As String Dim Sysdir As String Dim Producer As String Dim ErrNr, rc As Integer Dim Indx(maxdim) As String 'TgdxStrIndex Dim Values(val_max) As Double 'TgdxValues Dim VarNr As Integer Dim NrRecs As Integer Dim N As Integer Dim Dimen As Integer Dim VarName As String Dim VarTyp As Integer Sub Main() If Environment.GetCommandLineArgs().Length <> 2 And Environment.GetCommandLineArgs().Length <> 3 Then Console.WriteLine("**** XP_Example1: incorrect number of parameters") End End If Sysdir = Environment.GetCommandLineArgs(1) Console.WriteLine("XP_Example1 using GAMS system directory: " & Sysdir) If Not gdxCreateD(PGX, Sysdir, Msg) Then Console.WriteLine("**** Could not load GDX library") Console.WriteLine("**** " & Msg) Exit Sub End If gdxGetDLLVersion(PGX, Msg) Console.WriteLine("Using GDX DLL version: " & Msg) If Environment.GetCommandLineArgs().Length = 2 Then 'write demand data gdxOpenWrite(PGX, "demanddata.gdx", "xp_example1", ErrNr) If ErrNr <> 0 Then ReportIOError(ErrNr) End If If gdxDataWriteStrStart(PGX, "Demand", "Demand data", 1, dt_par, 0) = 0 Then ReportGDXError(PGX) End If WriteData("New-York", 324.0) WriteData("Chicago", 299.0) WriteData("Topeka", 274.0) If gdxDataWriteDone(PGX) = 0 Then ReportGDXError(PGX) End If Console.WriteLine("Demand data written by xp_example1") Else rc = gdxOpenRead(PGX, Environment.GetCommandLineArgs(2), ErrNr) 'Environment.GetCommandLineArgs(1) "trnsport.gdx" If ErrNr <> 0 Then ReportIOError(ErrNr) End If 'read x variable back (non-default level values only) gdxFileVersion(PGX, Msg, Producer) Console.WriteLine("GDX file written using version: " & Msg) Console.WriteLine("GDX file written by: " & Producer) If gdxFindSymbol(PGX, "x", VarNr) = 0 Then Console.WriteLine("**** Could not find variable X") Exit Sub End If gdxSymbolInfo(PGX, VarNr, VarName, Dimen, VarTyp) If (Dimen <> 2) Or (VarTyp <> dt_var) Then Console.WriteLine("**** X is not a two dimensional variable") Exit Sub End If If gdxDataReadStrStart(PGX, VarNr, NrRecs) = 0 Then ReportGDXError(PGX) End If Console.WriteLine("Variable X has " & NrRecs & " records") While gdxDataReadStr(PGX, Indx, Values, N) <> 0 If Values(val_level) = 0.0 Then 'skip level = 0.0 is default Continue While End If For D = 1 To Dimen Console.Write(Indx(D - 1)) If D < Dimen Then Console.Write(".") End If Next Console.WriteLine(" = " & Values(val_level)) End While Console.WriteLine("All solution values shown") gdxDataReadDone(PGX) End If ErrNr = gdxClose(PGX) If ErrNr <> 0 Then ReportIOError(ErrNr) End If End Sub End Module
import argparse import sys from gams.core import gdx if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("sysDir") parser.add_argument("gdxFile", nargs="?", default=None) args = parser.parse_args() print(f"Using GAMS system directory: {args.sysDir}") gdx_h = gdx.new_gdxHandle_tp() rc = gdx.gdxCreateD(gdx_h, args.sysDir, gdx.GMS_SSSIZE) if not rc[0]: raise Exception(rc[1]) print(f"Using GDX DLL version: {gdx.gdxGetDLLVersion(gdx_h)[1]}") if args.gdxFile is None: if not gdx.gdxOpenWrite(gdx_h, "demanddata.gdx", "xp_example1")[0]: raise Exception("Error gdxOpenWrite") if not gdx.gdxDataWriteStrStart( gdx_h, "Demand", "Demand data", 1, gdx.GMS_DT_PAR, 0 ): raise Exception("Error gdxDataWriteStrStart") values = gdx.doubleArray(gdx.GMS_VAL_MAX) values[gdx.GMS_VAL_LEVEL] = 324.0 gdx.gdxDataWriteStr(gdx_h, ["New-York"], values) values[gdx.GMS_VAL_LEVEL] = 299.0 gdx.gdxDataWriteStr(gdx_h, ["Chicago"], values) values[gdx.GMS_VAL_LEVEL] = 274.0 gdx.gdxDataWriteStr(gdx_h, ["Topeka"], values) if not gdx.gdxDataWriteDone(gdx_h): raise Exception("Error gdxDataWriteDone") print("Demand data written") else: if not gdx.gdxOpenRead(gdx_h, sys.argv[2])[0]: raise Exception("Error gdxOpenRead") file_version, producer = gdx.gdxFileVersion(gdx_h)[1:] print(f"GDX file written using version: {file_version}") print(f"GDX file written by: {producer}") rc, sym_nr = gdx.gdxFindSymbol(gdx_h, "x") if not rc: raise Exception("Symbol x not found") dim, sym_type = gdx.gdxSymbolInfo(gdx_h, sym_nr)[2:] if dim != 2 or sym_type != gdx.GMS_DT_VAR: raise Exception( f"x is not a two dimensional variable:\ndim = {dim}\ntype = {sym_type}" ) rc, nr_recs = gdx.gdxDataReadStrStart(gdx_h, sym_nr) if not rc: raise Exception( f"Error in gdxDataReadStrStart: {gdx.gdxErrorStr(gdx_h, gdx.gdxGetLastError(gdx_h))[1]}" ) print(f"Variable x has {nr_recs} records") for i in range(nr_recs): rc, elements, values, afdim = gdx.gdxDataReadStr(gdx_h) if not rc: raise Exception( f"Error in gdxDataReadStr: {gdx.gdxErrorStr(gdx_h, gdx.gdxGetLastError(gdx_h))[1]}" ) level = values[gdx.GMS_VAL_LEVEL] if level != 0: elements = [elements[d] for d in range(dim)] print(f"{'.'.join(elements)} = {level}") print("All solution values shown") gdx.gdxDataReadDone(gdx_h) if gdx.gdxClose(gdx_h): raise Exception("Error in gdxClose") if not gdx.gdxFree(gdx_h): raise Exception("Error in gdxFree") print("All done")
/////////////////////////////////////////////////////////////// // This program generates demand data for a modified version // // of the trnsport model or reads the solution back from a // // gdx file. // // // // Calling convention: // // Case 1: // // Parameter 1: GAMS system directory // // The program creates a GDX file with demand data // // Case 2: // // Parameter 1: GAMS system directory // // Parameter 2: gdxfile // // The program reads the solution from the GDX file // // Paul van der Eijk Jun-12, 2002 // /////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace xp_example1 { class xp_example1 { static gdxcs gdx; static void ReportGDXError() { string S = string.Empty; Console.WriteLine("**** Fatal GDX Error"); gdx.gdxErrorStr(gdx.gdxGetLastError(), ref S); Console.WriteLine("**** " + S); Environment.Exit(1); } static void ReportIOError(int N) { Console.WriteLine("**** Fatal I/O Error = " + N); Environment.Exit(1); } static void WriteData(string s, double V) { string[] Indx = new string[gamsglobals.maxdim]; double[] Values = new double[gamsglobals.val_max]; Indx[0] = s; Values[gamsglobals.val_level] = V; gdx.gdxDataWriteStr(Indx, Values); } static int Main(string[] args) { string Msg = string.Empty; string Sysdir; string Producer = string.Empty; int ErrNr = 0; int rc; string[] Indx = new string[gamsglobals.maxdim]; double[] Values = new double[gamsglobals.val_max]; int VarNr = 0; int NrRecs = 0; int N = 0; int Dimen = 0; string VarName = string.Empty; int VarTyp = 0; int D; if (Environment.GetCommandLineArgs().Length != 2 && Environment.GetCommandLineArgs().Length != 3) { Console.WriteLine("**** XP_Example1: incorrect number of parameters"); return 1; } String[] arguments = Environment.GetCommandLineArgs(); Sysdir = arguments[1]; Console.WriteLine("XP_Example1 using GAMS system directory: " + Sysdir); gdx = new gdxcs(Sysdir, ref Msg); if (Msg != string.Empty) { Console.WriteLine("**** Could not load GDX library"); Console.WriteLine("**** " + Msg); return 1; } gdx.gdxGetDLLVersion(ref Msg); Console.WriteLine("Using GDX DLL version: " + Msg); if (Environment.GetCommandLineArgs().Length == 2) { //write demand data gdx.gdxOpenWrite("demanddata.gdx", "xp_example1", ref ErrNr); if (ErrNr != 0) xp_example1.ReportIOError(ErrNr); if (gdx.gdxDataWriteStrStart("Demand", "Demand data", 1, gamsglobals.dt_par, 0) == 0) ReportGDXError(); WriteData("New-York", 324.0); WriteData("Chicago", 299.0); WriteData("Topeka", 274.0); if (gdx.gdxDataWriteDone() == 0) ReportGDXError(); Console.WriteLine("Demand data written by xp_example1"); } else { rc = gdx.gdxOpenRead(arguments[2], ref ErrNr); if (ErrNr != 0) ReportIOError(ErrNr); //read x variable back (non-default level values only) gdx.gdxFileVersion(ref Msg, ref Producer); Console.WriteLine("GDX file written using version: " + Msg); Console.WriteLine("GDX file written by: " + Producer); if (gdx.gdxFindSymbol("x", ref VarNr) == 0) { Console.WriteLine("**** Could not find variable X"); return 1; } gdx.gdxSymbolInfo(VarNr, ref VarName, ref Dimen, ref VarTyp); if (Dimen != 2 || VarTyp != gamsglobals.dt_var) { Console.WriteLine("**** X is not a two dimensional variable"); return 1; } if (gdx.gdxDataReadStrStart(VarNr, ref NrRecs) == 0) ReportGDXError(); Console.WriteLine("Variable X has " + NrRecs + " records"); while (gdx.gdxDataReadStr(ref Indx, ref Values, ref N) != 0) { if(Values[gamsglobals.val_level] == 0.0) //skip level = 0.0 is default continue; for (D=0; D<Dimen; D++) { Console.Write(Indx[D]); if (D < Dimen-1) Console.Write("."); } Console.WriteLine(" = " + Values[gamsglobals.val_level]); } Console.WriteLine("All solution values shown"); gdx.gdxDataReadDone(); } ErrNr = gdx.gdxClose(); if (ErrNr != 0) ReportIOError(ErrNr); return 0; } } }
package com.gams.xp_examples; import com.gams.api.*; public class xp_example1 { static final int maxdim = 20; static final int val_level = 0; static final int val_marginal = 1; static final int val_lower = 2; static final int val_upper = 3; static final int val_scale = 4; static final int val_max = 5; static final int dt_set = 0; static final int dt_par = 1; static final int dt_var = 2; static final int dt_equ = 3; static final int dt_alias = 4; static final int dt_max = 5; static gdx gdxio = new gdx(); static String[] Indx = new String[maxdim]; static double[] Values = new double[val_max]; static void ReportGDXError() { String[] S = new String[1]; System.out.println("**** Fatal GDX Error"); gdxio.ErrorStr(gdxio.GetLastError(), S); System.out.println("**** " + S[0]); System.exit(1); } static void ReportIOError(int N, String msg ) { System.out.println("**** Fatal I/O Error = " + N + " when calling " + msg); System.exit(1); } static void WriteData(String s, double V) { Indx[0] = s; Values[val_level] = V; gdxio.DataWriteStr(Indx,Values); } public static void main (String[] args) { String[] Msg = new String[1]; String[] Producer = new String[1]; String Sysdir; int[] ErrNr = new int[1]; int[] VarNr = new int[1]; int[] NrRecs = new int[1]; int[] N = new int[1]; int[] Dim = new int[1]; String[] VarName = new String[1]; int[] VarTyp = new int[1]; int D; if (args.length < 1 || args.length > 2) { System.out.println("**** Example1: incorrect number of parameters"); System.exit(1); } Sysdir = args[0]; System.out.println("Example1 using GAMS system directory: " + Sysdir); if (gdxio.CreateD(Sysdir, Msg) != 1) { System.out.println("**** Could not load GDX library"); System.out.println("**** " + Msg[0]); System.exit(1); } gdxio.GetDLLVersion(Msg); System.out.println("Using GDX DLL version: " + Msg[0]); if (1 == args.length) { /* Write demand data */ gdxio.OpenWrite("demanddata.gdx", "example1", ErrNr); if (ErrNr[0] != 0) ReportIOError(ErrNr[0],"gdxOpenWrite"); if (gdxio.DataWriteStrStart("Demand","Demand data",1,dt_par,0) != 1) ReportGDXError(); WriteData("New-York",324.0); WriteData("Chicago" ,299.0); WriteData("Topeka" ,274.0); if (gdxio.DataWriteDone() != 1) ReportGDXError(); System.out.println("Demand data written by example1\n"); } else { gdxio.OpenRead(args[1], ErrNr); if (ErrNr[0] != 0) ReportIOError(ErrNr[0],"gdxOpenRead"); gdxio.FileVersion(Msg,Producer); System.out.println("GDX file written using version: " + Msg[0]); System.out.println("GDX file written by: " + Producer[0]); if (gdxio.FindSymbol("x",VarNr) != 1) { System.out.println("**** Could not find variable X"); System.exit(1); } gdxio.SymbolInfo(VarNr[0],VarName,Dim,VarTyp); if (Dim[0] != 2 || dt_var != VarTyp[0]) { System.out.println("**** X is not a two dimensional variable: " + Dim[0] + ":" + VarTyp[0]); System.exit(1); } if (gdxio.DataReadStrStart(VarNr[0],NrRecs) != 1) ReportGDXError(); System.out.println("Variable X has " + NrRecs[0] + " records"); while (gdxio.DataReadStr(Indx,Values,N) != 0) { if (0 == Values[val_level]) continue; /* skip level 0.0 is default */ for (D=0; D<Dim[0]; D++) { System.out.print(Indx[D]); if (D<Dim[0]-1) System.out.print("."); } System.out.println(" = " + Values[val_level]); } System.out.println("All solution values shown"); gdxio.DataReadDone(); } ErrNr[0] = gdxio.Close(); if (ErrNr[0] != 0) ReportIOError(ErrNr[0],"gdxClose"); if (gdxio.Free() != 1) { System.out.println("Problems unloading the GDX DLL"); System.exit(1); } } }
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4