Initializing help system before first use

User Functions

Topics covered in this chapter:

Callbacks and user functions

Callbacks and user functions both provide mechanisms for connecting user-written functions to Xpress NonLinear. However, they have different capabilities and are not interchangeable.

A callback is called at a specific point in the SLP optimization process (for example, at the start of each SLP iteration). It has full access to all the problem data and can, in principle, change the values of any items — although not all such changes will necessarily be acted upon immediately or at all.

A user function is essentially the same as any other mathematical function, used in a formula to calculate the current value of a coefficient. The function is called when a new value is needed; for efficiency, user functions are not usually called if the value is already known (for example, when the function arguments are the same as on the previous call). Therefore, there is no guarantee that a user function will be called at any specific point in the optimization procedure or at all.

Although a user function is normally free-standing and needs no access to problem or other data apart from that which it receives through its argument list, there are facilities to allow it to access the problem and its data if required. The following limitations should be observed:

  1. The function should not make use of any variable data which is not in its list of arguments;
  2. The function should not change any of the problem data.

The reasons for these restrictions are as follows:

  1. Xpress NonLinear determines which variables are linked to a formula by examining the list of variables and arguments to functions in the formula. If a function were to access and use the value of a variable not in this list, then incorrect relationships would be established, and incorrect or incomplete derivatives would be calculated. The predicted and actual values of the coefficient would then always be open to doubt.
  2. Xpress NonLinear generally allows problem data to be changed between function calls, and also by callbacks called from within an Xpress NonLinear function. However, user functions are called at various points during the optimization and no checks are generally made to see if any problem data has changed. The effects of any such changes will therefore at best be unpredictable.

For a description of how to access the problem data from within a user function, see the section on "More complicated user functions" later in this chapter.

User function interface

In its simplest form, a user function is exactly the same as any other mathematical function: it takes a set of arguments (constants or values of variables) and returns a value as its result. In this form, which is the usual implementation, the function needs no information apart from the values of its arguments. It is possible to create more complicated functions which do use external data in some form.

Xpress NonLinear distinguishes six different types of user functions.

  • A user function is called a map, if it takes and returns a single value.
  • A user function is called a mapvec, if it takes an array of inputs, and returns a single evaluation value.
  • A user function is called a multimap, if it takes an array of inputs, and also returns an array of evaluation values.
  • A mapdelta user function is an extended version of a map that also returns its own partial derivatives when requested
  • A mapvecdelta user function is an extended version of a mapvec that also returns its own partial derivatives when requested
  • A multimapdelta user function is an extended version of a multimap that also returns its own partial derivatives when requested

User Function declaration in native languages

This section describes how to declare a user function in C. The general shape of the declaration is shown. Not all the possible arguments will necessarily be used by any particular function, and the actual arguments required will depend on the way the function is declared to Xpress NonLinear.

User function declaration in C

If the function is placed in a library, XSLPimportlibfunc may be used to retrieve a pointer to be passed to XSLPadduserfunction.

A user function can be included in the executable program which calls Xpress NonLinear.

A multimapdelta function's deltas is an array with the same number of items as inputvalues. It is used as an indication of which derivatives (if any) are required on a particular function call. If deltas[i] is zero then a derivative for input variable i is not required and must not be returned. If deltas[i] is nonzero then a derivative for input variable i is required and must be returned.

When no derivatives are calculated, the array of return values simply contains the results.
When derivatives are calculated, the array contains the values and the derivatives as follows (DVi is the ith variable for which derivatives are required, which may not be the same as the ith input value):
 Result1
 Derivative of Result1 w.r.t. DV1
 Derivative of Result1 w.r.t. DV2
 ...
 Derivative of Result1 w.r.t. DVn
 Result2
 Derivative of Result2 w.r.t. DV1
 Derivative of Result2 w.r.t. DV2
 ...
 Derivative of Result2 w.r.t. DVn
 ...
 Derivative of Resultm w.r.t. DVn

It is therefore important to check whether derivatives are required and, if so, how many.

The return value of the user functions that return an int (as opposed to the evaluation value) is a status code indicating whether the function has completed normally. Possible values are:

0
No errors: the function has completed normally.
1
The function has encountered an error. This will terminate the optimization.
-1
The calling function must estimate the function value from the last set of values calculated. This will cause an error if no values are available.

Programming Techniques for User Functions

This section is principally concerned with the programming of large or complicated user functions, perhaps taking a potentially large number of input values and calculating a large number of results. However, some of the issues raised are also applicable to simpler functions.

The first part describes in more detail some of the possible arguments to the function. The remainder of the section looks at function instances, function objects and direct calls to user functions.

Deltas

The Deltas array has the same dimension as InputValues and is used to indicate which of the input variables should be used to calculate derivatives. If Deltas[i] is zero, then no derivative should be returned for input variable i. If Deltas[i] is nonzero, then a derivative is required for input variable i. The value of Deltas[i] can be used as a suggested perturbation for numerical differentiation (a negative sign indicates that if a one-sided derivative is calculated, then a backward one is preferred). If derivatives are calculated analytically, or without requiring a specific perturbation, then Deltas can be interpreted simply as an array of flags indicating which derivatives are required.

Return values and ReturnArray

The ReturnArray array is provided for those user functions which return more than one value, either because they do calculate more than one result, or because they also calculate derivatives. The function must either return the address of an array which holds the values, or pass the values to the calling program through the ReturnArray array.

The total number of values returned depends on whether derivatives are being calculated. The total number of values (and hence the minimum size of the array) is nRet*(nDeriv+1). Xpress NonLinear guarantees that ReturnArray will be large enough to hold the total number of values requested.

A function which calculates and returns a single value can use the ReturnArray array provided that the declarations of the function in Xpress NonLinear and in the native language both include the appropriate argument definition.

functions which use the ReturnArray array must also return a status code as their return value. Zero is the normal return value. A nonzero value is an error code which will cause any formula evaluation to stop and will normally interrupt any optimization or other procedure.

Returning Derivatives

A multi-valued function which does not calculate its own derivatives will return its results as a one-dimensional array.

As already described, when derivatives are calculated as well, the order is changed, so that the required derivatives follow the value for each result. That is, the order becomes:
A,

∂A
∂X1
,
∂A
∂X2
, ...
∂A
∂Xn
, B,
∂B
∂X1
,
∂B
∂X2
, ...
∂B
∂Xn
, ...
∂Z
∂Xn

where A, B, Z are the return values, and X1, X2, Xn, are the input (independent) variables (in order) for which derivatives have been requested.

Not all calls to a user function necessarily require derivatives to be calculated. Check FunctionInfo for the number of derivatives required (it will be zero if only a value calculation is needed), and Deltas for the indications as to which independent variables are required to produce derivatives. Xpress NonLinear will not ask for, nor will it expect to receive, derivatives for function arguments which are actually constant in a particular problem. A function which provides uncalled-for derivatives will cause errors in subsequent calculations and may cause other unexpected side-effects if it stores values outside the expected boundaries of the return array.

Function Instances

Xpress NonLinear defines an instance of a user function to be a unique combination of function and arguments. For functions which return an array of values, the specific return argument is ignored when determining instances. Thus, given the following formulae:
 f(x) + f(y) + g(x,y : 1)
 f(y)*f(x)*g(x,y : 2)
 f(z)
the following instances are created:
f(x)
f(y)
f(z)
g(x,y)
(A function reference of the form g(x,y:n) means that g is a multi-valued function of x and y, and we want the nth return value.)

Xpress NonLinear regards as complicated any user function which returns more than one value, which uses input or return names, or which calculates its own derivatives. All complicated functions give rise to function instances, so that each function is called only once for each distinct combination of arguments.

Functions which are not regarded as complicated are normally called each time a value is required.

Note that conditional re-evaluation of the function is only possible if it generates function instances.

Using function instances can improve the performance of a problem, because the function is called only once for each combination of arguments, and is not re-evaluated if the values have not changed significantly. If the function is computationally intensive, the improvement can be significant.

Xpress NonLinear normally expects to obtain a set of partial derivatives from a user function at a particular base-point and then to use them as required, depending on the evaluation settings for the various functions. If for any reason this is not appropriate, then the integer control parameter XSLP_EVALUATE can be set to 1, which will force re-evaluation every time.
A function instance is not re-evaluated if all of its arguments are unchanged.
A simple function which does not have a function instance is evaluated every time.

If XSLP_EVALUATE is not set, then it is still possible to by-pass the re-evaluation of a function if the values have not changed significantly since the last evaluation. If the input values to a function have all converged to within their strict convergence tolerance (CTOL, ATOL_A, ATOL_R), and bit 4 of XSLP_FUNCEVAL is set to 1, then the existing values and derivatives will continue to be used. At the option of the user, an individual function, or all functions, can be re-evaluated in this way or at each SLP iteration. If a function is not re-evaluated, then all the required values will be calculated from the base point and the partial derivatives; the input and return values used in making the original function calculation are unchanged.

Bits 3-5 of integer control parameter XSLP_FUNCEVAL determine the nature of function evaluations. The meaning of each bit is as follows:

Bit 3
evaluate functions whenever independent variables change.
Bit 4
evaluate functions when independent variables change outside tolerances.
Bit 5
apply evaluation mode to all functions.
If bits 3-4 are zero, then the settings for the individual functions are used.
If bit 5 is zero, then the settings in bits 3-4 apply only to functions which do not have their own specific evaluation modes set.

Examples:

Bits 3-5 = 1 (set bit 3)
Evaluate functions whenever their input arguments (independent variables) change, unless the functions already have their own evaluation options set.
Bits 3-5 = 5 (set bits 3 and 5)
Evaluate all functions whenever their input arguments (independent variables) change.
Bits 3-5 = 6 (set bits 4 and 5)
Evaluate functions whenever input arguments (independent variables) change outside tolerance. Use existing calculation to estimate values otherwise.

Bits 6-8 of integer control parameter XSLP_FUNCEVAL determine the nature of derivative calculations. The meaning of each bit is as follows:

Bit 6
tangential derivatives.
Bit 7
forward derivatives.
Bit 8
apply evaluation mode to all functions.
If bits 6-7 are zero, then the settings for the individual functions are used.
If bit 8 is zero, then the settings in bits 6-7 apply only to functions which do not have their own specific derivative calculation modes set.

Examples:

Bits 6-8 = 1 (set bit 6)
Use tangential derivatives for all functions which do not already have their own derivative options set.
Bits 6-8 = 5 (set bits 6 and 8)
Use tangential derivatives for all functions.
Bits 6-8 = 6 (set bits 7 and 8)
Use forward derivatives for all functions.

The following constants are provided for setting these bits:

Setting bit 3 XSLP_RECALC
Setting bit 4 XSLP_TOLCALC
Setting bit 5 XSLP_ALLCALCS
Setting bit 6 XSLP_2DERIVATIVE
Setting bit 7 XSLP_1DERIVATIVE
Setting bit 8 XSLP_ALLDERIVATIVES

When analytical derivatives are used, for user functions not returning their own derivatives, SLP will calculate approximated derivatives using finite differences for instantiated functions and use these values when deriving analytical derivatives.


© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.