(!****************************************************** Mosel User Guide Example Problems ================================= file recurse.mos ```````````````` Solving a non-linear problem by Sequential Linear Programming. (c) 2008 Fair Isaac Corporation author: S. Heipcke, 2001 *******************************************************!) model Recurse uses "mmxprs" forward procedure solve_recurse declarations T=6 ! Time horizon QUARTERS=1..T ! Range of time periods P,R,V: array(QUARTERS) of real ! Payments B: array(QUARTERS) of real ! Initial guess as to balances b(t) X: real ! Initial guess as to interest rate x interest: array(QUARTERS) of mpvar ! Interest net: array(QUARTERS) of mpvar ! Net balance: array(QUARTERS) of mpvar ! Balance x: mpvar ! Interest rate dx: mpvar ! Change to x eplus, eminus: array(QUARTERS) of mpvar ! + and - deviations end-declarations X:= 0.00 B:: [1, 1, 1, 1, 1, 1] P:: [-1000, 0, 0, 0, 0, 0] R:: [206.6, 206.6, 206.6, 206.6, 206.6, 0] V:: [-2.95, 0, 0, 0, 0, 0] ! net = payments - interest forall(t in QUARTERS) net(t) = (P(t)+R(t)+V(t)) - interest(t) ! Money balance across periods forall(t in QUARTERS) balance(t) = if(t>1, balance(t-1), 0) - net(t) forall(t in 2..T) ! Approximation of interest Interest(t):= -(365/92)*interest(t) + X*balance(t-1) + B(t-1)*dx + eplus(t) - eminus(t) = 0 Def:= X + dx = x ! Define the interest rate: x = X + dx Feas:= sum(t in QUARTERS) (eplus(t)+eminus(t)) ! Objective: get feasible interest(1) = 0 ! Initial interest is zero forall (t in QUARTERS) net(t) is_free forall (t in 1..T-1) balance(t) is_free balance(T) = 0 ! Final balance is zero dx is_free minimize(Feas) ! Solve the LP-problem solve_recurse ! Recursion loop ! Print the solution writeln("\nThe interest rate is ", getsol(x)) write(strfmt("t",5), strfmt(" ",4)) forall(t in QUARTERS) write(strfmt(t,5), strfmt(" ",3)) write("\nBalances ") forall(t in QUARTERS) write(strfmt(getsol(balance(t)),8,2)) write("\nInterest ") forall(t in QUARTERS) write(strfmt(getsol(interest(t)),8,2)) writeln !************************************************************************ ! Recursion loop: we recurse on X and the balance(t)'s. ! The 'B(t-1)' in rows Interest(t) get the prior value of balance(t-1) ! The 'X' in rows Interest(t) get the prior value of x ! The 'X' in row Def gets the prior value of x ! We say we have converged when the change in dx is less than 0 !************************************************************************ procedure solve_recurse declarations TOLERANCE=0 ! Convergence tolerance variation: real ! Variation of x BC: array(QUARTERS) of real bas: basis ! LP basis end-declarations setparam("zerotol", TOLERANCE) ! Set Mosel comparison tolerance variation:=1 ct:=0 while(variation>0) do savebasis(bas) ! Save the current basis ct+=1 forall(t in 2..T) BC(t-1):= getsol(balance(t-1)) ! Get solution values for balance(t)'s XC:= getsol(x) ! and x write("Round ", ct, " x:", getsol(x), " (variation:", variation,"), ") writeln("Simplex iterations: ", getparam("XPRS_SIMPLEXITER")) forall(t in 2..T) do ! Update coefficients Interest(t)+= (BC(t-1)-B(t-1))*dx B(t-1):=BC(t-1) Interest(t)+= (XC-X)*balance(t-1) end-do Def+= XC-X X:=XC oldxval:=XC ! Store solution value of x loadprob(Feas) ! Reload the problem into the optimizer loadbasis(bas) ! Reload previous basis minimize(Feas) ! Re-solve the LP-problem variation:= abs(getsol(x)-oldxval) ! Change in dx end-do end-procedure end-model