User function (general form)
PurposeThe general form of the user function includes possibilities for calculating and returning an array of values, including partial derivatives if appropriate. Additional features include optional information about the calling program.Synopsisfunction fName (aName:array(aRange:range) of real,
nName:array(nRange:range) of integer
[,iName:array(iRange:range) of string]
[,oName:array(oRange:range) of string]
[,dName:array(dRange:range) of string]
[,rName:array(rRange:range) of real]) : realArguments
aName an array of type real containing the actual values of the parameters to the function nName an array of type integer containing the function information array iName an array of type string containing the array of input names oName an array of type string containing the array of output names dName an array of type real containing the array of partial derivative flags rName an array of type real to contain the array of results from the functionExampleThe following is an example of a general Mosel user function which calculates the product of a set of numbers and also the partial derivatives with respect to each of them. It takes four parameters: the input values, the function information array, the array of partial derivative flags, and an array to hold the return values. The function itself returns zero for success (and would return nonzero for failure).function Product(Values:array(vRange:range) of real, FuncInfo:array(fRange:range) of integer, Deltas:array(dRange:range) of real, Return:array(rRange:range) of real) :real nValue := FuncInfo(fRange(1)) declarations Value: real Derivatives: array(1..nValue) of real end-declarations Value := 1 forall (i in 1..nValue) Derivatives(i) := 1 forall (i in 1..nValue) do Value := Value * Values(vRange(i)) forall (j in 1..nValue | j <> i) Derivatives(j) := Derivatives(j)* Values(vRange(i)) end-do Return(rRange(1)) := Value j := 1 forall (i in 1..nValue) do if Deltas(dRange(i)) <> 0 then j += 1 Return(rRange(j)) := Derivatives(i) end-if end-do returned := 0 end-functionThe number of input values is given in the first item in the FuncInfo array. For ease of explanation in this case, the partial derivatives are calculated for all the input variables (that is, for each item in the Values array). Deltas(i) is zero if a derivative is not required for the ith item, and nonzero if a derivative is required. This is tested in the final loop, when the Derivatives array is packed into the Return array.
The function is declared by using the SLPDATA("UF") procedure and can then be called using the Func wrapper as in the following example:
declarations X,Y: mpvar Values, Deltas, Results: array(1..100) of real FuncInfo: array(1..xslp_funcinfosize) of integer NullStr:dynamic array(1..1) of string XArray:array(1..6) of string end-declarations XArray := ["Values","FuncInfo","NullStr", "NullStr","Deltas","Results"] SLPDATA("UF","Product","", "DOUBLE,INTEGER,,,DOUBLE,DOUBLE", "Mosel","Model","XArray") Func("Product",X,Y) <= 10The presence of the Deltas argument in the function definition defines the function as calculating its own derivatives. There is no change in the way the function is written in constraints, and the system will decide when derivatives are required.
Further informationThe order and purpose of the arguments to a Mosel user function follow the standard layout for Xpress-SLP user functions as described in the Xpress-SLP reference manual.
On return, rName must contain the required values. The return value must be 0 if the function has completed successfully, or a positive value (
- aName
- The actual values of the parameters to the function are passed in the array aName
- nName
- This holds various information items about the function and its arguments. In particular:
- nName(1)
- is the number of parameters (the actual number of values in the array aName)
- nName(2)
- is the number of return values required. This is only important if the function returns multiple values and the actual number or order required may vary
- nName(3)
- is the number of sets of partial derivatives required. If the function is declared as providing its own derivatives, then nName(3) is the number required on this call to the function, which may be zero
- iName
- This is an optional argument, which is used if the function receives values by name rather than by position. If it is used, then the names of the arguments are provided in the same order as the values
- oName
- This is an optional argument, which is used if the function returns multiple values by name rather than by position. If it is used, then the names of the values are provided in the order in which the values are required
- dName
- This argument is only used when the function is declared as providing its own partial derivatives. If it is used, it will have one entry for each item in aName. The value in dName is nonzero if a partial derivative is required for the corresponding item in aName, and zero otherwise. A nonzero value can be used as a basis for numerical derivatives if required. The number of nonzero entries in dName is in nName(3)
- rName
- This argument is normally used when the function returns multiple values, either because it is a multi-valued function, or because it calculates its own derivatives.
1) if it failed.
If you have any comments or suggestions about these pages, please send mail to docs@dashoptimization.com.