# GAMS Support Wiki

### Site Tools

gams:model_a_step_function

# How do I model a step function (piecewise constant function)?

Q: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.

```* 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 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));``` 