Basically I want to calculate a lending rate using a function like: lendingRate = f(type, amount ), where type = {long, short} and amount is a percentage which can be anything > 0. The function f is like a step function (or piecewise constant function), that looks up amount and returns the rate associated with the corresponding interval.
Here is one example to model a step function (piecewise constant function):
* Some scalars to do an assignment based on a certain values stored in lev
Scalar rho1,rho2,rho3,lev;
lev= 25;
rho1 = ifthen(lev<10, 8,
ifthen(lev<20, 8.8,
ifthen(lev<30, 9.6,
10.2)));
if( lev<10, rho2 = 8;
elseif lev<20, rho2 = 8.8
elseif lev<30, rho2 = 9.6
else rho2 = 10.2);
* note a subtle difference when lev could be negative. This formulation assumes
* that lev is positive. All the other ones assume the first range to be [-inf, 10]
Set type / long, short /,
r / r1*r4 /;
Table rate
r1 r2 r3 r4
max 10 20 30 inf
long 8 8.8 9.6 10.2
short 5 5.5 6.0 6.5;
rho3 = sum(r$(lev < rate('max',r) and lev > rate('max',r-1)), rate('long',r));
display rho1,rho2,rho3;
* Use in a model
Binary Variable b(r);
Variables lv,rhov;
Equation range1,range2,defrho,one;
Model m / all /;
range1(r).. lv =l= rate('max',r) + 100*(1-b(r));
range2(r-1).. lv =g= rate('max',r-1) - 100*(1-b(r));
one.. sum(r,b(r)) =e= 1;
defrho.. rhov =e= sum(r, rate('long',r)*b(r));
lv.lo=15;lv.up=25;
solve m us mip max rhov;
display b.l, lv.l, rhov.l;
Here is another example:
Set p /1*5/;
Parameter intercept(p) Interception points of piecewise constant function
/ 1 10, 2 20, 3 25, 4 30, 5 40 /
value(p) Value of piecewise constant function for arguments right of intercept(p)
/ 1 10, 2 20, 3 10, 4 0, 5 -10 /;
* We model f(x) = value(p) for x such that p <= 4 and intercept(p) <= x <= intercept(p+1) or intercept(5) <= x
* Note, that f(x) is not well defined when x equals to an intercept
Variable x, f;
x.lo = intercept('1')+1;
x.up = 50;
Binary Variable z(p) 'Indicate whether x > intercept(p)';
Equation e1(p) 'Force z(p) to be 1 if x > intercept(p)'
e2(p) 'Force x(p) to be >= intercept(p) if z(p) is 1'
fdef 'Define value of f in terms of z(p)';
Parameter M1(p) 'BigM values for e1'
M2(p) 'BigM values for e2';
e1(p).. x =l= intercept(p) + M1(p) * z(p);
e2(p).. x =g= intercept(p) - M2(p) * (1-z(p));
M1(p) = x.up - intercept(p);
M2(p) = intercept(p) - x.lo;
fdef.. f =e= sum(p, (value(p) - value(p-1)) * z(p));