Non-linear functions
Can model non-linear functions in the same way as incremental pricebreaks
- approximate the non-linear function with a piecewise linear function
- use an SOS2 to model the piecewise linear function
Non-linear function in a single variable

- x-coordinates of the points: R1, ..., R4
y-coordinates F1, ..., F4. So point 1 is (R1,F1) etc. - Let weights (decision variables) associated with point i be wi (i=1,...,4)
- Form convex combinations of the points using weights wi to get a combination point (x,y):
x = ∑i wi·Ri y = ∑i wi·Fi ∑i wi = 1 - Mosel implementation:
declarations I=1..4 x,y: mpvar w: array(I) of mpvar R,F: array(I) of real end-declarations ! ...assign values to arrays R and F... ! Define the SOS-2 with "reference row" coefficients from R Defx:= sum(i in I) R(i)*w(i) is_sos2 sum(i in I) w(i) = 1 ! The variable and the corresponding function value we want to approximate x = Defx y = sum(i in I) F(i)*w(i)
- BCL implementation:
XPRBprob prob("testsos"); XPRBvar x, y, w[I]; XPRBexpr Defx, le, ly; double R[I], F[I]; int i; // ...assign values to arrays R and F... // Create the decision variables x = prob.newVar("x"); y = prob.newVar("y"); for(i=0; i<I; i++) w[i] = prob.newVar("w"); // Define the SOS-2 with "reference row" coefficients from R for(i=0; i<I; i++) Defx += R[i]*w[i]; prob.newSos("Defx", XPRB_S2, Defx); for(i=0; i<I; i++) le += w[i]; prob.newCtr("One", le == 1); // The variable and the corresponding function value we want to approximate prob.newCtr("Eqx", x == Defx); for(i=0; i<I; i++) ly += F[i]*w[i]; prob.newCtr("Eqy", y == ly);
Non-linear function in two variables
Interpolation of a function f in two variables: approximate f at a point P by the corners C of the enclosing square of a rectangular grid (NB: the representation of P=(x,y) by the four points C obviously means a fair amount of degeneracy).

- x-coordinates of grid points: X1, ..., Xn
y-coordinates of grid points: Y1, ..., Ym. So grid points are (Xi,Yj). - Function evaluation at grid points: FXY11, ..., FXYnm
- Define weights (decision variables) associated with x and y coordinates, wxi respectively wyj, and for each grid point (X(i),Y(j)) define a variable wxyij
- Form convex combinations of the points using the weights to get a combination point (x,y) and the corresponding function approximation:
x = ∑i wxi·Xi y = ∑j wyj·Yj f = ∑ij wxyij·FXYij ∀ i=1,...,n: ∑j wxyij = wxi ∀ j=1,...,m: ∑i wxyij = wyj ∑i wxi = 1 ∑j wyj = 1 - Mosel implementation:
declarations RX,RY:range X: array(RX) of real ! x coordinate values of grid points Y: array(RY) of real ! y coordinate values of grid points FXY: array(RX,RY) of real ! Function evaluation at grid points end-declarations ! ... initialize data declarations wx: array(RX) of mpvar ! Weight on x coordinate wy: array(RY) of mpvar ! Weight on y coordinate wxy: array(RX,RY) of mpvar ! Weight on (x,y) coordinates x,y,f: mpvar end-declarations ! Definition of SOS (assuming coordinate values <>0) sum(i in RX) X(i)*wx(i) is_sos2 sum(j in RY) Y(j)*wy(j) is_sos2 ! Constraints forall(i in RX) sum(j in RY) wxy(i,j) = wx(i) forall(j in RY) sum(i in RX) wxy(i,j) = wy(j) sum(i in RX) wx(i) = 1 sum(j in RY) wy(j) = 1 ! Then x, y and f can be calculated using x = sum(i in RX) X(i)*wx(i) y = sum(j in RY) Y(j)*wy(j) f = sum(i in RX,j in RY) FXY(i,j)*wxy(i,j) ! f can take negative or positive values (unbounded variable) f is_free
XPRBprob prob("testsos"); XPRBvar x, y, f; XPRBvar wx[NX], wy[NY], wxy[NX][NY]; // Weights on coordinates XPRBexpr Defx, Defy, le, lexy, lx, ly; double DX[NX], DY[NY]; double FXY[NX][NY]; int i,j; // ... initialize data arrays DX, DY, FXY // Create the decision variables x = prob.newVar("x"); y = prob.newVar("y"); f = prob.newVar("f", XPRB_PL, -XPRB_INFINITY, XPRB_INFINITY); // Unbounded variable for(i=0; i<NX; i++) wx[i] = prob.newVar("wx"); for(j=0; j<NY; j++) wy[j] = prob.newVar("wy"); for(i=0; i<NX; i++) for(j=0; j<NY; j++) wxy[i][j] = prob.newVar("wxy"); // Definition of SOS for(i=0; i<NX; i++) Defx += X[i]*wx[i]; prob.newSos("Defx", XPRB_S2, Defx); for(j=0; j<NY; j++) Defy += Y[j]*wy[j]; prob.newSos("Defy", XPRB_S2, Defy); // Constraints for(i=0; i<NX; i++) { le = 0; for(j=0; j<NY; j++) le += wxy[i][j]; prob.newCtr("Sumx", le == wx[i]); } for(j=0; j<NY; j++) { le = 0; for(i=0; i<NX; i++) le += wxy[i][j]; prob.newCtr("Sumy", le == wy[j]); } for(i=0; i<NX; i++) lx += wx[i]; prob.newCtr("Convx", lx == 1); for(j=0; j<NY; j++) ly += wy[j]; prob.newCtr("Convy", ly == 1); // Calculate x, y and the corresponding function value f we want to approximate prob.newCtr("Eqx", x == Defx); prob.newCtr("Eqy", y == Defy); for(i=0; i<NX; i++) for(j=0; j<NY; j++) lexy += FXY[i][j]*wxy[i][j]; prob.newCtr("Eqy", f == lexy);
© 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.