| (!******************************************************
   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, rev. Jun. 2022
*******************************************************!)
model Recurse
 uses "mmxprs"
 forward procedure solverecurse
 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
 solverecurse                        ! Recursion loop
 
                                     ! Print the solution
 writeln("\nThe interest rate is ", x.sol)
 write(strfmt("t",5), strfmt(" ",4))
 forall(t in QUARTERS) write(strfmt(t,5), strfmt(" ",3))
 write("\nBalances ")
 setparam("realfmt", "%8.2f")
 forall(t in QUARTERS) write(balance(t).sol)
 write("\nInterest ")
 forall(t in QUARTERS) write(interest(t).sol)
 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 1.0E-6
!************************************************************************
 procedure solverecurse
  declarations
   TOLERANCE=0.000001                 ! 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.0
  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
 |