Xpress NonLinear Formulae
Xpress NonLinear can handle formulae described in three different ways:
- Character strings
- The formula is written exactly as it would appear in, for example, the Extended MPS format used for text file input.
- Internal unparsed format
-
The tokens within the formula are replaced by a
{token type, token value} pair. The list of types and values is in the table below. - Internal parsed format
- The tokens are converted as in the unparsed format, but the order is changed so that the resulting array forms a reverse-Polish execution stack for direct evaluation by the system.
Parsed and unparsed formulae
All formulae input into Xpress NonLinear are parsed into a reverse-Polish execution stack. Tokens are identified by their type and a value. The table below shows the values used in interface functions.
All formulae are provided in the interface functions as two parallel arrays:
an integer array of token types;
a double array of token values.
The last token type in the array should be an end-of-formula token (XSLP_EOF, which evaluates to zero).
If the value required is an integer, it should still be provided in the array of token values as a double precision value.
Even if a token type requires no token value, it is best practice to initialize such values as zeros.
Type | Description | Value |
---|---|---|
XSLP_COL | column | index of matrix column. |
XSLP_CON | constant | (double) value. |
XSLP_CONSTRAINT | constraint | index of constraint. Note that constraints count from 1, so that the index of matrix row n is n + 1. |
XSLP_CV | character variable | index of character variable. |
XSLP_DEL | delimiter | XSLP_COMMA (1) = comma (",") |
XSLP_COLON (2) = colon (":") | ||
XSLP_EOF | end of formula | not required: use zero |
XSLP_FUN | user function | index of function |
XSLP_IFUN | internal function | index of function |
XSLP_LB | left bracket | not required: use zero |
XSLP_OP | operator | XSLP_UMINUS (1) = unary minus ("-") |
XSLP_EXPONENT (2) = exponent ("**" or "^") | ||
XSLP_MULTIPLY (3) = multiplication ("*") | ||
XSLP_DIVIDE (4) = division ("/") | ||
XSLP_PLUS (5) = addition ("+") | ||
XSLP_MINUS (6) = subtraction ("-") | ||
XSLP_RB | right bracket | not required: use zero |
XSLP_ROW | row | index of matrix row. |
XSLP_STRING | character string | internal index of character string |
XSLP_UNKNOWN | unidentified token | internal index of character string |
XSLP_VAR | variable | index of variable. Note that variables count from 1, so that the index of matrix column n is n + 1. |
XSLP_VARREF | reference to variable | index of variable. Note that variables count from 1, so that the index of matrix column n is n + 1. |
XSLP_UFARGTYPE | requirements and types of argument for a user function | bitmap of types (see below). |
XSLP_UFEXETYPE | linkage of a user function | bitmap of linkage information (see below). |
Argument types for user function definition are stored as a bit map. Each type is stored in 3 bits: bits 0-2 for argument 1, bits 3-5 for argument 2 and so on. The possible values for each argument are as follows:
0 | omitted |
1 | NULL |
2 | INTEGER |
3 | DOUBLE |
4 | VARIANT |
6 | CHAR |
The linkage type and other function information are stored as a bit map as follows:
Bits 0-2 | type of linkage: |
1 = User library or DLL | |
2 = Excel spreadsheet | |
3 = Excel macro | |
5 = MOSEL | |
7 = COM | |
Bits 3-4 | re-evaluation flags: |
0 = default | |
1 (Bit 3) = re-evaluation at each SLP iteration | |
2 (Bit 4) = re-evaluation when independent variables are outside tolerance | |
Bits 6-7 | derivative flags: |
0 = default | |
1 (Bit 6) = tangential derivatives | |
2 (Bit 7) = forward derivatives | |
Bit 8 | calling mechanism: |
0 = standard | |
1 = CDECL (Windows only) | |
Bit 24 | set if the function is multi-valued |
Bit 28 | set if the function is not differentiable |
Token types XSLP_ROW and XSLP_COL are used only when passing formulae into Xpress NonLinear. Any formulae recovered from Xpress NonLinear will use the XSLP_CONSTRAINT and XSLP_VAR token types which always count from 1.
When a formula is passed to Xpress NonLinear in "internal unparsed format" — that is, with the formula already converted into tokens — the full range of token types is permitted.
When a formula is passed to Xpress NonLinear in "parsed format" — that is, in reverse Polish — the following rules apply:
XSLP_DEL | comma is optional. |
XSLP_FUN | implies a following left-bracket, which is not included explicitly. |
XSLP_IFUN | implies a following left-bracket, which is not included explicitly. |
XSLP_LB | never used. |
XSLP_RB | only used to terminate the list of arguments to a function. |
XSLPgetccoef
Token type XSLP_UNKNOWN is returned by the parsing routines when a string cannot be identified as any other type of token. Token type XSLP_STRING is returned by the parsing routine where the token has been specifically identified as being a character string: the only case where this occurs at present is in the names of return arguments from user-defined multi-valued functions. The "value" field for both these token types is an index into the Xpress NonLinear string table and can be accessed using the XSLPgetstring function.
Example of an arithmetic formula
x2+4y(z-3)
Written as an unparsed formula, each token is directly transcribed as follows:
Type | Value |
---|---|
XSLP_VAR | index of x |
XSLP_OP | XSLP_EXPONENT |
XSLP_CON | 2 |
XSLP_OP | XSLP_PLUS |
XSLP_CON | 4 |
XSLP_OP | XSLP_MULTIPLY |
XSLP_VAR | index of y |
XSLP_OP | XSLP_MULTIPLY |
XSLP_LB | 0 |
XSLP_VAR | index of z |
XSLP_OP | XSLP_MINUS |
XSLP_CON | 3 |
XSLP_RB | 0 |
XSLP_EOF | 0 |
Written as a parsed formula (in reverse Polish), an evaluation order is established first, for example:
x 2 ^ 4 y * z 3 - * +
and this is then transcribed as follows:
Type | Value |
---|---|
XSLP_VAR | index of x |
XSLP_CON | 2 |
XSLP_OP | XSLP_EXPONENT |
XSLP_CON | 4 |
XSLP_VAR | index of y |
XSLP_OP | XSLP_MULTIPLY |
XSLP_VAR | index of z |
XSLP_CON | 3 |
XSLP_OP | XSLP_MINUS |
XSLP_OP | XSLP_MULTIPLY |
XSLP_OP | XSLP_PLUS |
XSLP_EOF | 0 |
Notice that the brackets used to establish the order of evaluation in the unparsed formula are not required in the parsed form.
Example of a formula involving a simple function
y*MyFunc(z,3)
Written as an unparsed formula, each token is directly transcribed as follows:
Type | Value |
---|---|
XSLP_VAR | index of y |
XSLP_OP | XSLP_MULTIPLY |
XSLP_FUN | index of MyFunc |
XSLP_LB | 0 |
XSLP_VAR | index of z |
XSLP_DEL | XSLP_COMMA |
XSLP_CON | 3 |
XSLP_RB | 0 |
XSLP_EOF | 0 |
Written as a parsed formula (in reverse Polish), an evaluation order is established first, for example:
y ) 3 , z MyFunc( *
and this is then transcribed as follows:
Type | Value |
---|---|
XSLP_VAR | index of y |
XSLP_RB | 0 |
XSLP_CON | 3 |
XSLP_DEL | XSLP_COMMA |
XSLP_VAR | index of z |
XSLP_FUN | index of MyFunc |
XSLP_OP | XSLP_MULTIPLY |
XSLP_EOF | 0 |
Notice that the function arguments are in reverse order, and that a right bracket is used as a delimiter to indicate the end of the argument list. The left bracket indicating the start of the argument list is implied by the XSLP_FUN token.
Example of a formula involving a complicated function
This example uses a function which takes two arguments and returns an array of results, which are identified by name. In the formula, the return value named VAL1 is being retrieved.
y*MyFunc(z,3:VAL1)
Written as an unparsed formula, each token is directly transcribed as follows:
Type | Value |
---|---|
XSLP_VAR | index of y |
XSLP_OP | XSLP_MULTIPLY |
XSLP_FUN | index of MyFunc |
XSLP_LB | 0 |
XSLP_VAR | index of z |
XSLP_DEL | XSLP_COMMA |
XSLP_CON | 3 |
XSLP_DEL | XSLP_COLON |
XSLP_STRING | index of VAL1 in string table |
XSLP_RB | 0 |
XSLP_EOF | 0 |
Written as a parsed formula (in reverse Polish), an evaluation order is established first, for example:
y ) VAL1 : 3 , z MyFunc( *
and this is then transcribed as follows:
Type | Value |
---|---|
XSLP_VAR | index of y |
XSLP_RB | 0 |
XSLP_STRING | index of VAL1 in string table |
XSLP_DEL | XSLP_COLON |
XSLP_CON | 3 |
XSLP_DEL | XSLP_COMMA |
XSLP_VAR | index of z |
XSLP_FUN | index of MyFunc |
XSLP_OP | XSLP_MULTIPLY |
XSLP_EOF | 0 |
Notice that the function arguments are in reverse order, including the name of the return value and the colon delimiter, and that a right bracket is used as a delimiter to indicate the end of the argument list.
Example of a formula defining a user function
User function definitions in XSLPadduserfuncs and XSLPloaduserfuncs are provided through the formula structure. Assume we wish to add the function defined in Extended MPS format as
MyFunc = Func1 (DOUBLE,INTEGER) MOSEL = MyModel = MyArray
We also want to evaluate the function only when its arguments have changed outside tolerances. This also requires function instances. In the definition of a user function, there is no distinction made between parsed and unparsed format: the tokens provide information and are interpreted in the order in which they are encountered. The function definition is as follows:
Type | Value |
---|---|
XSLP_STRING | index of Func1 in string table |
XSLP_UFARGTYPE | 26 (octal 32) |
XSLP_UFEXETYPE | 21 (Bit 4 set, and Bits 0-2 = 5) |
XSLP_STRING | index of MyModel in string table |
XSLP_STRING | index of MyArray in string table |
XSLP_EOF | 0 |
The string arguments are interpreted in the order in which they appear. Therefore, if any of the function parameters (param1 to param3 in Extended MPS format) is required, there must be entries for the internal function name and any preceding function parameters. If the fields are blank, use an XSLP_STRING token with a zero value.
The name of the function itself (MyFunc in this case) is provided through the function XSLPaddnames.