Data input from file
With Mosel, there are several different ways of reading and writing data from and to external files. For simplicity's sake we shall limit the discussion here to files in text format. Mosel also provides specific modules to exchange data with spreadsheets and databases, for instance using an ODBC connection, but this is beyond the scope of this book and the interested reader is refered to the documentation of these modules (see the Mosel Language Reference Manual and the whitepaper Using ODBC and other database interfaces with Mosel).
The data file folio.dat that we are going to work with has the following contents:
! Data file for `folio*.mos' RET: [("treasury") 5 ("hardware") 17 ("theater") 26 ("telecom") 12 ("brewery") 8 ("highways") 9 ("cars") 7 ("bank") 6 ("software") 31 ("electronics") 21 ] RISK: ["hardware" "theater" "telecom" "software" "electronics"] NA: ["treasury" "hardware" "theater" "telecom"]
Just as in model files, single-line comments preceded by ! may be used in data files. Every data entry is labeled with the name given to the corresponding entity in the model. Data items may be separated by blanks, tabulations, line breaks, or commas.
We modify the Mosel model from Chapter 3 as follows:
declarations SHARES: set of string ! Set of shares RISK: set of string ! Set of high-risk values among shares NA: set of string ! Set of shares issued in N.-America RET: array(SHARES) of real ! Estimated return in investment end-declarations initializations from "folio.dat" RISK RET NA end-initializations declarations frac: array(SHARES) of mpvar ! Fraction of capital used per share end-declarations
As opposed to the previous model foliolp.mos, all index sets and the data array are now declared without fixing their contents: their size is not known at their creation and they are initialized later with data from the file folio.dat. Optionally, after the initialization from file, we may finalize the sets to make them static. This will make more efficient the handling of any arrays indexed by these sets, and more importantly, this allows Mosel to check for `out of range' errors that cannot be detected if the sets are allowed to grow dynamically. (Note that sets and arrays in Mosel can also be explicitly marker as dynamic in order to prevent them from being finalized/fixed.)
finalize(SHARES); finalize(RISK); finalize(NA)
Notice that we do not initialize explicitly the set SHARES, it is filled automatically when the array RET is read. Notice further that we only declare the decision variables after initializing the data, and hence when their index set is known.