massn.f 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. PROGRAM MASS
  2. C This program computes optimum mass entries in the bathtub model
  3. C
  4. C The main program and subroutine are in this file. Routines from
  5. C reading dat input and displaying output are in put in file
  6. C "auxiliary.f".
  7. C
  8. C The main program calls a first subroutines to read data input and then
  9. C calls the subroutine that computes the optimum entry rates.
  10. C
  11. C A SUMMARY OF THE SUBROUTINES
  12. C
  13. C UTIL : computes the objective function
  14. C D_UTIL : computes the gradient of the objective function
  15. C CONS : computes the value of the constraint. This version
  16. C has one constraint (the sum of the entry rates is equal to
  17. C one
  18. C D_CONS : computes the gradient of the constraint
  19. C SPLITLINE : for input, it takes the current approximation line with
  20. C respect variable m and breaks and evenly subdivides the largest
  21. C intervals into two intervals. Bu doing so we intend to get
  22. C a smoother approximation of the solution
  23. C
  24. C For the optimization step we use the fortran version IPOPT (the large-scale
  25. C optimization package):
  26. C
  27. C https://www.coin-or.org/Ipopt/ipopt-fortran.html
  28. C
  29. C TO RUN THIS PROGRAM
  30. C - install IPOPT (it requires LAPACK and BLAS)
  31. C - compile through a command like
  32. C gfortran -o massn massn.f auxiliary.f -llapack -lblas -lipopt
  33. C by providing the correct path to the libraries
  34. C - set data in file "params.dat"
  35. C - run the program
  36. C ./massn
  37. C
  38. C
  39. C KNOWN ISSUES AND POSSIBLE IMPROVEMENTS
  40. C
  41. C 1. This version does not explicitly set constraint on :
  42. C - last arrival time should be smaller than TMAX
  43. C - traffic density should be smaller than road jam capacity
  44. C and relies on the optimization to carry on implicitly these
  45. C constraints. This does not occur in all cases and fine tuning of
  46. C parameter M0, MBAR and ITMAX is frequently required for convergence.
  47. C
  48. C 2. M0 and MBAR are fixed. It is suggested to provide a large window in
  49. C the start. The solution will entail a first phase where without
  50. C entries. Similarly it will entail a last phase where entries are
  51. C equal to zero. A new of the computation can then be considered by
  52. C zooming a new window with higher M0 and smaller MBAR. This process
  53. C can be repeated until satisfactory values are obtained.
  54. C
  55. C 3. The Hessian is not provided to the optimizer. It uses finite
  56. C difference to approximate it (IQUASI = 6, in the options passed to
  57. C IPOPT).
  58. C
  59. C 4. The program does not produce any graphical output. For instance,
  60. C output table can be exported to a text file (redirect the output
  61. C using the unix standard "./massn > outfile") and then use gnuplot
  62. C or another program to make the plots (after deleting useless
  63. C lines).
  64. C
  65. C These issues will be addressed in the updates
  66. C
  67. C
  68. C NOTATION THROUGH AN EXAMPLE
  69. C - number of entry (and exit) points: N = 10
  70. C - number of entry points before within a cycle: NL = 2
  71. C - total number of breakpoints: N + NL = 12
  72. C
  73. C (0) t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11
  74. C (1) P----S-------P----S-------P----S-------P-----S-------P----S-----P--------S---
  75. C
  76. C (2) 0 Mb-4L L Mb-3L 2L Mb-2L 3L Mb-L 4L Mb (4+1)L Mb+L
  77. C
  78. C (3) 1 2 3 4 5 6 7 8 9 10 11 12
  79. C
  80. C (4) e1 e2 e3 e4 e5 e6 e7 e8 e9 e10
  81. C
  82. C (5) e1 e2 e3 e4 e5 e6 e7 e8 e9 e10
  83. C
  84. C (6) T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12
  85. C
  86. C
  87. C (0) t_i clock-time from m_i to m_(i+1)
  88. C (1) Primary (P) and secondary (S) breakpoints
  89. C (3) indices for variable m
  90. C (4) entries at each breakpoint m_i (at each breakpoint)
  91. C (5) exits at each breakpoint m_i (at each breakpoint)
  92. C (6) T_i clock-time at mile m_i
  93. IMPLICIT NONE
  94. DOUBLE PRECISION UT
  95. DOUBLE PRECISION R0, R1, S0, S1, VF, K, L, P, TMAX
  96. DOUBLE PRECISION M0, MBAR
  97. INTEGER ITMAX
  98. COMMON /MODELPARAM/ R0, R1, S0, S1, VF, K, L, P, TMAX
  99. COMMON /OTHERPARAM/ M0, MBAR, ITMAX
  100. C Read parameters from file "params.dat"
  101. CALL READPARAM("params.dat")
  102. PRINT '(11F9.2)', R0,R1,S0,S1,VF,K,L,P,TMAX,M0,MBAR
  103. C Call subroutine UTILOPT to compute the optimum entry rates
  104. CALL UTILOPT ( M0, MBAR , UT, ITMAX)
  105. C Print the value of the objective function
  106. PRINT*, UT
  107. END
  108. SUBROUTINE UTILOPT (M0,MBAR,F,ITMAX)
  109. C Computes entry masses at points m_i that maximize aggregate
  110. C utility given that M0 and MBAR are fixed
  111. IMPLICIT NONE
  112. DOUBLE PRECISION M0, MBAR
  113. INTEGER I, NCYC, NL, NMAX, IT, ITMAX
  114. PARAMETER (NMAX=10000)
  115. DOUBLE PRECISION U
  116. C Parameters of the problem
  117. DOUBLE PRECISION R0, R1, S0, S1, VF, K, L, P, TMAX
  118. C Variable definition for IPOPT
  119. INTEGER LRW, LIW
  120. PARAMETER ( LRW = 10000, LIW = 10000)
  121. INTEGER IW(LIW)
  122. DOUBLE PRECISION RW(LRW)
  123. DOUBLE PRECISION IPOPT
  124. INTEGER N, M
  125. DOUBLE PRECISION LAM(NMAX)
  126. DOUBLE PRECISION C(NMAX)
  127. DOUBLE PRECISION G(NMAX)
  128. DOUBLE PRECISION E(NMAX)
  129. INTEGER NLB, NUB
  130. INTEGER ILB(NMAX), IUB(NMAX)
  131. DOUBLE PRECISION BNDSL(NMAX), BNDSU(NMAX)
  132. DOUBLE PRECISION V_L(NMAX), V_U(NMAX)
  133. DOUBLE PRECISION DAT (NMAX)
  134. INTEGER IDAT (NMAX)
  135. INTEGER NARGS
  136. DOUBLE PRECISION ARGS (50)
  137. CHARACTER*20 CARGS(50)
  138. INTEGER IERR, ITER
  139. DOUBLE PRECISION F
  140. EXTERNAL UTIL, CONS, D_UTIL, D_CONS
  141. EXTERNAL EV_H_DUMMY,EV_HLV_DUMMY, EV_HOV_DUMMY, EV_HCV_DUMMY
  142. C End of definition of IPOPT variables
  143. COMMON /MODELPARAM/ R0, R1, S0, S1, VF, K, L, P, TMAX
  144. NCYC= FLOOR ( (MBAR-M0) / L )
  145. N = 2 * ( NCYC+ 1 )
  146. IF(MBAR.GT.L) THEN
  147. NL = 2
  148. ELSE
  149. NL =1
  150. ENDIF
  151. IDAT(1) = NCYC
  152. IDAT(2) = NL
  153. C Compute the breakpoints. This is the first approximation that will be
  154. C used.
  155. DO 10, I = 1, NCYC+ NL
  156. C Primary breakpoints
  157. DAT(2*I-1) = M0 + DBLE( I - 1 ) * L
  158. C Secondary breakpoints. Notice that :
  159. C MBAR + L - NCYCL + (I-1) * L = MBAR - (NCYC-I) * L
  160. DAT(2*I) = MBAR - DBLE ( NCYC- I + 1 ) * L
  161. 10 CONTINUE
  162. C Compute a simple initial solution
  163. DO 20, I = 1, N
  164. E(I) = ( DAT(I+1) - DAT(I) ) / ( ( NCYC + 1 ) * L )
  165. 20 CONTINUE
  166. C Set algorithmic parameters (for IPOPT)
  167. NARGS = 1
  168. ARGS(1) = 1.D-8
  169. CARGS = 'dtol'
  170. C MAIN LOOP
  171. C It starts by optimizing over the initial breakpoints, then
  172. C uses the obtained solution to increase the number of approximation
  173. C points. Variable ITMAX indicates the number of iterations (how many
  174. C time the approximation line) is subdivided.
  175. IT = 1
  176. 100 CONTINUE
  177. C Number of variable with lower bounds
  178. NLB = N
  179. C Indices of variables with lower bounds
  180. DO 1, I = 1, N
  181. ILB(I) = I
  182. 1 CONTINUE
  183. C Values of lower bounds
  184. DO 2, I = 1, N
  185. BNDSL(I) = 1.0D-6
  186. 2 CONTINUE
  187. C Number of variables with upper bounds
  188. NUB = 0
  189. C i.e. no uppers bounds on the entry rates
  190. C There is only one constraint on the problem (the sum of all entry
  191. C rates is one)
  192. M = 1
  193. PRINT* , N, NL, IT
  194. C Call IPOPT (the optimizer)
  195. F = - IPOPT(N, E, M, NLB, ILB, BNDSL, NUB, IUB, BNDSU, V_L, V_U,
  196. 1 LAM, C, LRW, RW, LIW, IW, ITER, IERR, UTIL, CONS, D_UTIL,
  197. 1 D_CONS, EV_H_DUMMY, EV_HLV_DUMMY, EV_HOV_DUMMY, EV_HCV_DUMMY,
  198. 1 DAT, IDAT, NARGS, ARGS, CARGS)
  199. PRINT '(A20,F9.3)' , 'Value of objective function : ', F
  200. PRINT '(F9.5)', SUM(E)
  201. IT = IT + 1
  202. IF(IT.LE.ITMAX) THEN
  203. CALL SPLITLINE(N, DAT,NL,E,0.80D0)
  204. IDAT(2) = NL
  205. GOTO 100
  206. ENDIF
  207. C Print the last solution obtained
  208. CALL STATDES(N, E, DAT, IDAT)
  209. RETURN
  210. END
  211. C ======================================
  212. C Computation of the objective function
  213. C (aggregate utility)
  214. C ======================================
  215. SUBROUTINE UTIL(N, E, U, DAT, IDAT)
  216. IMPLICIT NONE
  217. INTEGER I, N, NL, NMAX
  218. PARAMETER (NMAX=10000)
  219. DOUBLE PRECISION U, E(N)
  220. DOUBLE PRECISION DAT(NMAX)
  221. INTEGER IDAT(NMAX)
  222. C Variables used for intermediate computations
  223. DOUBLE PRECISION V(N+IDAT(2)-1), T(N+IDAT(2)-1), TT(N+IDAT(2))
  224. DOUBLE PRECISION UE, UX
  225. DOUBLE PRECISION SUME
  226. C Parameters of the problem
  227. DOUBLE PRECISION R0, R1, S0, S1, VF, K, L, P, TMAX
  228. COMMON /MODELPARAM/ R0, R1, S0, S1, VF, K, L, P, TMAX
  229. NL = IDAT(2)
  230. C Compute travel speed, travel time and clock-time on each interval
  231. I=1
  232. TT(I) = DAT(I) / VF
  233. SUME=E(I)
  234. V(I) = VF * ( 1.0D0 - P * SUME / K )
  235. T(I) = ( DAT(I+1) - DAT(I) ) / V(I)
  236. C PRINT*, V(I), VF, P, K, SUME,T(I),TT(I),DAT(2)- DAT(1)
  237. TT(I+1) = TT(I) + T(I)
  238. DO 1, I = 2, N + NL - 1
  239. IF(I.LE.NL) THEN
  240. SUME = SUME + E(I)
  241. ELSEIF (I.LE.N) THEN
  242. SUME = SUME + E(I) - E(I-NL)
  243. ELSE
  244. SUME = SUME - E(I-NL)
  245. ENDIF
  246. V(I) = MAX(0.D0,VF * ( 1.0D0 - P * SUME / K ))
  247. T(I) = ( DAT(I+1) - DAT(I) ) / V(I)
  248. TT(I+1) = TT(I) + T(I)
  249. C PRINT '(I5,5F9.3)', I,DAT(I),V(I), T(I), TT(I+1), SUME
  250. 1 CONTINUE
  251. C Compute entry and exit sub-utilities
  252. UE = 0.0D0
  253. UX = 0.0D0
  254. DO 20, I = 1, N
  255. UE = UE + R0 * DLOG( R1 * TT(I ) ) * E(I) * P
  256. UX = UX + S0 * DLOG( S1 * ( TMAX - TT(I + NL))) * E(I) * P
  257. C PRINT '(2I5,4F9.3)', I, NL,TMAX,TT(I+NL),UE, UX
  258. 20 CONTINUE
  259. C AGREGATE UTILITY
  260. C Notice that we consider the opposite of the utility since we set the
  261. C problem as a minimization program
  262. U = - ( UE + UX )
  263. RETURN
  264. END
  265. C =====================================================
  266. C Computation of the gradient of the objective function
  267. C =====================================================
  268. SUBROUTINE D_UTIL( N, E, G, DAT, IDAT)
  269. IMPLICIT NONE
  270. INTEGER N, NL, NMAX
  271. PARAMETER (NMAX=10000)
  272. DOUBLE PRECISION G(N), E(N)
  273. DOUBLE PRECISION DAT(NMAX)
  274. INTEGER IDAT(NMAX)
  275. DOUBLE PRECISION D_T(N+IDAT(2)-1), D_TT(N+IDAT(2),N)
  276. DOUBLE PRECISION D_UE(N,N), D_UX(N,N)
  277. DOUBLE PRECISION V(N+IDAT(2)-1), T(N+IDAT(2)-1), TT(N+IDAT(2))
  278. DOUBLE PRECISION SUME
  279. INTEGER I, J, II
  280. C Parameters of the problem
  281. DOUBLE PRECISION R0, R1, S0, S1, VF, K, L, P, TMAX
  282. COMMON /MODELPARAM/ R0, R1, S0, S1, VF, K, L, P, TMAX
  283. NL = IDAT(2)
  284. C Compute travel speed on each interval
  285. C This step is replicated from UTIL subroutine.
  286. I = 1
  287. TT(I) = DAT(I) / VF
  288. SUME = E(I)
  289. V(I) = MAX(0.0D0,VF * ( 1.D0 - P * SUME / K ))
  290. T(I) = ( DAT(I+1) - DAT(I) ) / V(I)
  291. TT(I+1) = TT(I) + T(I)
  292. C PRINT*, V(I), VF, P, K, SUME,T(I),TT(I),DAT(2)- DAT(1)
  293. DO 1, I = 2, N + NL - 1
  294. IF(I.LE.NL) THEN
  295. SUME = SUME + E(I)
  296. ELSEIF (I.LE.N) THEN
  297. SUME = SUME + E(I) - E(I-NL)
  298. ELSE
  299. SUME = SUME - E(I-NL)
  300. ENDIF
  301. V(I) = VF * ( 1.D0 - P * SUME / K )
  302. T(I) = ( DAT(I+1) - DAT(I) ) / V(I)
  303. TT(I+1) = TT(I) + T(I)
  304. C PRINT*, V(I), VF, P, K, SUME,T(I),TT(I),DAT(I+1), DAT(I)
  305. 1 CONTINUE
  306. C Compute the derivative
  307. C
  308. C d t_i m_(i+1) - m_i vf * P
  309. C ----- = ------------- * ------
  310. C d e_i v_i^2 K
  311. C
  312. DO 10, I = 1, N + NL - 1
  313. D_T(I) = (DAT(I+1) - DAT(I))/V(I)**2 * VF*P/K
  314. 10 CONTINUE
  315. C Compute the derivative
  316. C
  317. C /
  318. C | 0 if j <= i
  319. C |
  320. C |
  321. C d T_j | d t_i d t_(j-1)
  322. C ----- = / ----- + ... + --------- if i < j <=i+NL
  323. C d e_i \ d e_i d e_(j-1)
  324. C |
  325. C |
  326. C | d T_(i+NL)
  327. C | ---------- if j > i + NL
  328. C | d e_i
  329. C \
  330. C
  331. D_TT = 0.0D0
  332. DO 20, I = 1, N
  333. DO 20, J = I+1, N+NL
  334. IF (J.LE.I) THEN
  335. D_TT(J,I) = 0.0D0
  336. ELSEIF (J.LE.I+NL) THEN
  337. DO 22, II = I, J-1
  338. D_TT(J,I) = D_TT(J,I) + D_T(II)
  339. 22 CONTINUE
  340. ELSE
  341. D_TT(J,I) = D_TT(I+NL,I)
  342. ENDIF
  343. 20 CONTINUE
  344. C IMPACTS ON ENTRY SUBUTILITIES
  345. C An increase of the entry rate at T_i increases the size of the group
  346. C itself and delays the entry time for all groups that enter at T_j with
  347. C j > i.
  348. C Users who enter at T_N do not delay the entry of any other group. The
  349. C structure of the loop automatically takes into account this case since.
  350. C Indeed, for I=N, J varies varies from N+1 to N and, then, the loop is
  351. C not executed.
  352. D_UE = 0.0D0
  353. DO 30, I = 1, N
  354. D_UE(I, I) = R0 * DLOG( R1 * TT(I) ) * P
  355. DO 30, J = I+1, N
  356. D_UE(J, I) = R0 * D_TT(J,I) / TT(J) * E(J) * P
  357. 30 CONTINUE
  358. C IMPACTS ON EXIT SUBUTILITIES
  359. C An increase of the size of the group of users entering at T_i
  360. C has two impacts: (1) it delays the arrival of all groups entering at
  361. C T_{max(1,i-(NL-1))}, including the group itself, and (2) it increases
  362. C the size of the group of those entering at T_i.
  363. D_UX = 0.0D0
  364. DO 40, I = 1, N
  365. DO 40, J = MAX(I-(NL-1), 1), N
  366. D_UX(J, I) = - S0 * D_TT(J+NL,I) / (TMAX - TT(J+NL)) * E(J) * P
  367. 40 CONTINUE
  368. DO 45, I = 1, N
  369. D_UX(I, I) = D_UX(I, I) + S0 * DLOG( S1 * (TMAX - TT(I+NL)) ) * P
  370. 45 CONTINUE
  371. C TOTAL IMPACTS (the gradient)
  372. C Notice that we compute the gradient of - UTIL since we set
  373. C the problem as a minimization program.
  374. G = 0.0D0
  375. DO 50, I = 1, N
  376. DO 50, J = 1, N
  377. G(I) = G(I) - D_UE(J,I) - D_UX(J,I)
  378. C PRINT '(7F9.3)', G(I), E(1:6)
  379. 50 CONTINUE
  380. RETURN
  381. END
  382. C =========================================
  383. C Computation of the equality constraints
  384. C In this problem, there is only one constraint
  385. C stating that the sum of all entry rates
  386. C is equal to one :
  387. C
  388. C e_1 + e_2 + .. + e_n = 1
  389. C
  390. C =========================================
  391. SUBROUTINE CONS(N, E, M, C, DAT, IDAT)
  392. IMPLICIT NONE
  393. INTEGER N, M, NMAX
  394. PARAMETER (NMAX=10000)
  395. DOUBLE PRECISION C(M), E(N)
  396. DOUBLE PRECISION DAT(NMAX)
  397. INTEGER IDAT(NMAX)
  398. DOUBLE PRECISION SUME
  399. INTEGER I
  400. SUME = 0.D0
  401. DO 10, I = 1, N
  402. SUME = SUME + E(I)
  403. 10 CONTINUE
  404. C(1) = SUME - 1.D0
  405. RETURN
  406. END
  407. C =============================================
  408. C Computation of the Jacobian of the constraint
  409. C =============================================
  410. SUBROUTINE D_CONS(TASK, N, E, NZ, A, ACON, AVAR, DAT, IDAT)
  411. IMPLICIT NONE
  412. INTEGER TASK, N, NZ
  413. INTEGER NMAX, I
  414. PARAMETER (NMAX=10000)
  415. DOUBLE PRECISION E(N), A(NZ)
  416. INTEGER ACON(NZ), AVAR(NZ)
  417. DOUBLE PRECISION DAT(NMAX)
  418. INTEGER IDAT(NMAX)
  419. IF(TASK.EQ.0) THEN
  420. NZ = N
  421. ELSE
  422. DO 10, I = 1, N
  423. AVAR(I) = I
  424. ACON(I) = 1
  425. 10 CONTINUE
  426. DO 20, I = 1, N
  427. A(I) = 1.D0
  428. 20 CONTINUE
  429. ENDIF
  430. RETURN
  431. END
  432. C =============================================
  433. C Split interval
  434. C =============================================
  435. SUBROUTINE SPLITLINE(N, M, NL, E, THR)
  436. IMPLICIT NONE
  437. C Increases the number of approximation points by breaking the largest
  438. C intervals.
  439. C N the number of entry rates, or mile-points where entry occurs
  440. C M table containing the approximation points
  441. C NL index the last element between0 and L: we have M(NL+1) = L
  442. C THR intervals with length larger than THR * X are swplit into two
  443. C intervals, where X is the the length of the largest interval
  444. INTEGER NL, N, I, J, NMAX
  445. PARAMETER (NMAX=10000)
  446. DOUBLE PRECISION M(NMAX), E(NMAX)
  447. DOUBLE PRECISION THR
  448. DOUBLE PRECISION M2(NMAX), E2(NMAX)
  449. INTEGER N2,NPTS,NL2,NTOT
  450. DOUBLE PRECISION Y(NMAX), YMAX
  451. IF(N.LT.2) THEN
  452. PRINT*, "A table of legth 2 at least is expected"
  453. STOP
  454. ENDIF
  455. IF(THR.LE.0.0D0.OR.THR.GE.1.0D0) THEN
  456. PRINT*, "THR should be between 1/2 and 1."
  457. STOP
  458. ENDIF
  459. C Compute the length of the largest interval
  460. YMAX = M(2) - M(1)
  461. DO 10, I = 1, NL
  462. Y(I) = M(I+1) - M(I)
  463. IF(Y(I).GT.YMAX) YMAX = Y(I)
  464. 10 CONTINUE
  465. C Store some values
  466. N2 = N
  467. NL2 = NL
  468. NTOT = N + NL
  469. E2 = 0.0D0
  470. C Split intervals with length higher than
  471. C THR * YMAX and update indexes
  472. J = 0
  473. DO 20, I = 1, N+NL-1
  474. IF((M(I+1)-M(I)).GT.(THR*YMAX)) THEN
  475. M2(I+J ) = M(I)
  476. M2(I+J+1) = M(I) + (M(I+1) - M(I)) / 2.0D0
  477. J = J + 1
  478. IF(I.LE.NL) THEN
  479. E2(I+J ) = E(I)
  480. E2(I+J-1) = 0.0D0
  481. NL2 = NL2 + 1
  482. N2 = N2 + 1
  483. NTOT = NTOT + 1
  484. ELSEIF(I.LT.N) THEN
  485. E2(I+J ) = E(I)
  486. E2(I+J-1) = 0.0D0
  487. N2 = N2 + 1
  488. NTOT = NTOT + 1
  489. ELSE
  490. NTOT = NTOT + 1
  491. ENDIF
  492. ELSE
  493. M2(I+J) = M(I)
  494. E2(I+J) = E(I)
  495. ENDIF
  496. 20 CONTINUE
  497. E2(N2 ) = E(N)
  498. M2(NTOT) = M(N+NL)
  499. C Set valriables to new values
  500. M = M2
  501. E = E2
  502. N = N2
  503. NL = NL2
  504. RETURN
  505. END