Initializing help system before first use

Adding the non-linear part of the problem

Be warned – this section is complicated, but it is the most efficient way – from SLP's point of view – to input formulae. See the next section for a much easier (but less efficient) way of inputting the formulae directly.

#define MAXTOKEN 200
#define MAXCOEF 20
...
  int Sin, Cos;
  ColIndex[MAXCOL];
  FormulaStart[MAXCOEF];
  Type[MAXTOKEN];
  double Value[MAXTOKEN], Factor[MAXCOEF];

The arrays for the non-linear part can often be re-used from the linear part. The new arrays are ColIndex (for the column index of the coefficients), FormulaStart and Factor for the coefficients, and Type and Value to hold the internal forms of the formulae.

  XSLPgetindex(sprob, XSLP_INTERNALFUNCNAMES, "SIN", &Sin);
  XSLPgetindex(sprob, XSLP_INTERNALFUNCNAMES, "COS", &Cos);

We will be using the Xpress NonLinear internal functions SIN and COS. The XSLPgetindex function finds the index of an Xpress NonLinear entity (character variable, internal or user function).

  nToken = 0;
  nCoef = 0;
  RowIndex[nCoef] = 0;
  ColIndex[nCoef] = nSide;
  Factor[nCoef] = 0.5;
  FormulaStart[nCoef++] = nToken;

For each coefficient, the following information is required:

RowIndex the index of the row.
ColIndex the index of the column.
FormulaStart the beginning of the internal formula array for the coefficient.
Factor this is optional. If used, it holds a constant multiplier for the formula. This is particularly useful where the same formula appears in several coefficients, but with different signs or scaling. The formula can be used once, with different factors.

  for (i=1; i<nSide-1; i++) {
    Type[nToken] = XSLP_COL;
    Value[nToken++] = nSide+i+1;
    Type[nToken] = XSLP_COL;
    Value[nToken++] = nSide+i;
    Type[nToken] = XSLP_OP;
    Value[nToken++] = XSLP_MULTIPLY;
    Type[nToken] = XSLP_RB;
    Value[nToken++] = 0;
    Type[nToken] = XSLP_COL;
    Value[nToken++] = i+1;
    Type[nToken] = XSLP_COL;
    Value[nToken++] = i;
    Type[nToken] = XSLP_OP;
    Value[nToken++] = XSLP_MINUS;
    Type[nToken] = XSLP_IFUN;
    Value[nToken++] = Sin;
    Type[nToken] = XSLP_OP
    Value[nToken++] = XSLP_MULTIPLY;
    if (i>1) {
      Type[nToken] = XSLP_OP;
      Value[nToken++] = XSLP_PLUS;
    }
  }

This looks very complicated, but it is really just rather large. We are using the "reverse Polish" or "parsed" form of the formula for area. The original formula, written in the normal way, would look like this:
RHO2 * RHO1 * SIN ( THETA2 - THETA1 ) + .......
In reverse Polish notation, tokens are pushed onto the stack or popped from it. Typically, this means that a binary operation A x B is written as A B x (push A, push B, pop A and B and push the result). The first term of our area formula then becomes:
RHO2 RHO1 * ) THETA2 THETA1 - SIN *
Notice that the right hand bracket appears as an explicit token. This allows the SIN function to identify where its argument list starts – and incidentally allows functions to have varying numbers of arguments.

Each token of the formula is written as two items – Type and Value.
Type is an integer and is one of the defined types of token, as given in the xslp.h header file. XSLP_CON, for example, is a constant; XSLP_COL is a column.
Value is a double precision value, and its meaning depends on the corresponding Type. For a Type of XSLP_CON, Value is the constant value; for XSLP_COL, Value is the column number; for XSLP_OP (arithmetic operation), Value is the operand number as defined in xslp.h; for a function (type XSLP_IFUN for internal functions, XSLP_FUN for user functions), Value is the function number.
A list of tokens for a formula is always terminated by a token of type XSLP_EOF.

The loop writes each term in order, and adds terms (using the XSLP_PLUS operator) after the first pass through the loop.

  for (i=1; i<nSide-1; i++) {
    for (j=i+1; j<nSide; j++) {
      RowIndex[nCoef] = iRow++;
      ColIndex[nCoef] = nSide;
      Factor[nCoef] = 1.0;
      FormulaStart[nCoef++] = nToken;

      Type[nToken] = XSLP_COL;
      Value[nToken++] = nSide+i;
      Type[nToken] = XSLP_CON;
      Value[nToken++] = 2;
      Type[nToken] = XSLP_OP;
      Value[nToken++] = XSLP_EXPONENT;
      Type[nToken] = XSLP_COL;
      Value[nToken++] = nSide+j;
      Type[nToken] = XSLP_CON;
      Value[nToken++] = 2;
      Type[nToken] = XSLP_OP;
      Value[nToken++] = XSLP_PLUS;
      Type[nToken] = XSLP_CON;
      Value[nToken++] = 2;
      Type[nToken] = XSLP_COL;
      Value[nToken++] = nSide+i;
      Type[nToken] = XSLP_OP;
      Value[nToken++] = XSLP_MULTIPLY;
      Type[nToken] = XSLP_COL;
      Value[nToken++] = nSide+j;
      Type[nToken] = XSLP_OP;
      Value[nToken++] = XSLP_MULTIPLY;
      Type[nToken] = XSLP_RB;
      Value[nToken++] = 0;
      Type[nToken] = XSLP_COL;
      Value[nToken++] = j;
      Type[nToken] = XSLP_COL;
      Value[nToken++] = i;
      Type[nToken] = XSLP_OP;
      Value[nToken++] = XSLP_MINUS;
      Type[nToken] = XSLP_IFUN;
      Value[nToken++] = Cos;
      Type[nToken] = XSLP_OP
      Value[nToken++] = XSLP_MULTIPLY;
      Type[nToken] = XSLP_OP;
      Value[nToken++] = XSLP_MINUS;
      Type[nToken] = XSLP_EOF;
      Value[nToken++] = 0;
    }
  }

This writes the formula for the distances between pairs of vertices. It follows the same principle as the previous formula, writing the formula in parsed form as:
RHOi 2 RHOj 2 + 2 RHOi * RHOj * ) THETAj THETAi - COS * -

XSLPloadcoefs(sprob, nCoef, RowIndex, ColIndex, Factor, FormulaStart, 1, Type, Value);

The XSLPloadcoefs is the most efficient way of loading non-linear coefficients into a problem. There is an XSLPaddcoefs function which is identical except that it does not delete any existing coefficients first. There is also an XSLPchgcoef function, which can be used to change individual coefficients one at a time. Because we are using internal parsed format, the "Parsed" flag in the argument list is set to 1.

© 2001-2020 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.