source: PSPA/madxPSPA/src/matchsa.f90 @ 430

Last change on this file since 430 was 430, checked in by touze, 11 years ago

import madx-5.01.00

File size: 37.4 KB
Line 
1      subroutine mtsa(ncon,nvar,tol,calls,call_lim,vect,fun_vect,iseed  &
2     &,iprint,lb,nacp,ub,xopt,c,vm,xp)
3        use name_lenfi
4      implicit none
5!----------------------------------------------------------------------*
6! Purpose:                                                             *
7!   SA command.                                                        *
8! Attributes :                                                         *
9!   ncon      (int)     # constraints                                  *
10!   nvar      (int)     # variables                                    *
11!   iseed     (int)     initial seed                                   *
12!   iprint    (int)     print flag  (0 = minimum info printed)         *
13!   tol       (real)    Final tolerance for match.                     *
14!   calls     (int)     current call count                             *
15!   call_lim  (int)     current call limit                             *
16!   vect      (real)    variable values                                *
17!   fun_vect  (real)    function values                                *
18!   all other           working spaces for SA                          *
19!----------------------------------------------------------------------*
20      integer calls,call_lim,ncon,nvar,nacp(*),neps,n,m,ns,nt,          &
21     &iprint,iseed,iseed2,nacc,nobds,ier,i,iflag
22      parameter(neps=4)
23      double precision tol,t,vect(*),fun_vect(*),fopt,vmod
24      double precision rt,lb(*),ub(*),xopt(*),c(*),                     &
25     &vm(*),xp(*),fstar(neps)
26      integer j,next_vary,get_option,slope
27      double precision get_variable,val,c_min,c_max,step,opt
28      logical logmax,psum
29      common/forsa/m
30!     character*(name_len) name !uncomment when name_len.fi present
31      character*(name_len) name   !clear
32      n=nvar
33      m=ncon
34!     include 'match.fi'         !not used here i guess
35      psum=get_option('match_summary ') .ne. 0
36 1    continue
37      j = next_vary(name,name_len,c_min,c_max,step,slope,opt)
38      if (j .ne. 0)  then
39        val = get_variable(name)
40        lb(j)=c_min
41        ub(j)=c_max
42        c(j) =2.d0
43        vm(j)=1.d0
44        if(psum) write(*,830) name,val,c_min,c_max
45        vect(j) = val
46        goto 1
47      endif
48  830 format(a24,1x,1p,e16.8,3x,e16.8,3x,e16.8)
49! Choose SA parameters next:
50! The value of rt and ns as suggested by Corana
51      rt=0.85d0
52      ns = 20
53! The value of nt suggested by Corana is max(100, 5*nvar)
54      nt = max(100, 5*nvar)
55!      iprint=1
56!      iseed=1
57      iseed2 = iseed+1
58      logmax=.FALSE.
59! The initial temeprature T is best to be an user-defined parameter
60! set it to 10 here for brevery
61      t=10.
62      write(*,8800) n, t, rt, tol, ns, nt, neps, call_lim, iprint,      &
63     &iseed, iseed2
648800  format(/,' simulated annealing ',/,                               &
65     &/,' number of parameters: ',i3,                                   &
66     &/,' initial temp: ',g9.2, ' rt: ',g9.2,' eps:',g9.2,              &
67     &/,' ns: ',i3, '   nt: ',i4, '   neps: ',i2,                       &
68     &/,' calls: ',i10, '   iprint: ',i1, '   iseed: ',i4,              &
69     &'   iseed2: ',i4)
708001  format(/,' optimal function value: ',g20.13                       &
71     &/,' number of function evaluations:     ',i10,                    &
72     &/,' number of accepted evaluations:     ',i10,                    &
73     &/,' number of out of bound evaluations: ',i10,                    &
74     &/,' final temp: ', g20.13,'  ier: ', i3)
75      call prtvec(vect,n,'starting values')
76      call prtvec(vm,n,'initial step length')
77      call prtvec(lb,n,'lower bound')
78      call prtvec(ub,n,'upper bound')
79      !call prtvec(c,n,'c vector')
80      call sa(nvar,vect,logmax,rt,tol,ns,nt,neps,call_lim,lb,ub,        &
81     &c,iprint,iseed,iseed2,t,vm,xopt,fopt,nacc,calls,nobds,ier,        &
82     &fstar,xp,nacp)
83      call prtvec(xopt,n,'solution')
84      !call prtvec(vm,n,'final step length')
85      write(*,8001) fopt, calls, nacc, nobds, t, ier
86      do i=1,nvar
87        vect(i)=xopt(i)
88      enddo
89
90      call mtfcn(ncon,nvar,vect,fun_vect,iflag)
91
92      fopt = vmod(m,fun_vect)
93
94      print *," fopt again = ", fopt
95
96 9999 end
97
98      subroutine fcnsa(n,x,f)
99      implicit none
100      integer iflag,nf,n
101      double precision f,x(n),fvec(1000),vmod
102      common/forsa/nf
103      iflag=0
104      call mtfcn(nf,n,x,fvec,iflag)
105      f = vmod(nf, fvec)
106!     f=0
107!     do i=1,nf
108!     f=f+fvec(i)**2
109!     enddo
110!      f = dsqrt(f)
111      RETURN
112      END
113
114!* =====================================================================
115! GAMS : Source of SIMANN in OPT from NETLIB
116! ======================================================================
117! NIST Guide to Available Math Software.
118! Source for module SIMANN from package OPT.
119! Retrieved from NETLIB on Wed Oct  2 21:25:58 1996.
120! ======================================================================
121! Logic slightly modified by Dobrin Kaltchev in Nov 1998.
122! ABSTRACT:
123!   Simulated annealing is a global optimization method that distinguishes
124!   between different local optima. Starting from an initial point, the
125!   algorithm takes a step and the function is evaluated. When minimizing a
126!   function, any downhill step is accepted and the process repeats from this
127!   new point. An uphill step may be accepted. Thus, it can escape from local
128!   optima. This uphill decision is made by the Metropolis criteria. As the
129!   optimization process proceeds, the length of the steps decline and the
130!   algorithm closes in on the global optimum. Since the algorithm makes very
131!   few assumptions regarding the function to be optimized, it is quite
132!   robust with respect to non-quadratic surfaces. The degree of robustness
133!   can be adjusted by the user. In fact, simulated annealing can be used as
134!   a local optimizer for difficult functions.
135!
136!   This implementation of simulated annealing was used in "Global Optimization
137!   of Statistical Functions with Simulated Annealing," Goffe, Ferrier and
138!   Rogers, Journal of Econometrics, vol. 60, no. 1/2, Jan./Feb. 1994, pp.
139!   65-100. Briefly, we found it competitive, if not superior, to multiple
140!   restarts of conventional optimization routines for difficult optimization
141!   problems.
142!
143!   For more information on this routine, contact its author:
144!   Bill Goffe, bgoffe@whale.st.usm.edu
145!
146!      PROGRAM SIMANN
147!  This file is an example of the Corana et al. simulated annealing
148!  algorithm for multimodal and robust optimization as implemented
149!  and modified by Goffe, Ferrier and Rogers. Counting the above line
150!  ABSTRACT as 1, the routine itself (SA), with its supplementary
151!  routines, is on lines 232-990. A multimodal example from Judge et al.
152!  (FCN) is on lines 150-231. The rest of this file (lines 1-149) is a
153!  driver routine with values appropriate for the Judge example. Thus, this
154!  example is ready to run.
155!
156!  To understand the algorithm, the documentation for SA on lines 236-
157!  484 should be read along with the parts of the paper that describe
158!  simulated annealing. Then the following lines will then aid the user
159!  in becomming proficient with this implementation of simulated
160!  annealing.
161!
162!  Learning to use SA:
163!      Use the sample function from Judge with the following suggestions
164!  to get a feel for how SA works. When you've done this, you should be
165!  ready to use it on most any function with a fair amount of expertise.
166!    1. Run the program as is to make sure it runs okay. Take a look at
167!       the intermediate output and see how it optimizes as temperature
168!       (T) falls. Notice how the optimal point is reached and how
169!       falling T reduces VM.
170!    2. Look through the documentation to SA so the following makes a
171!       bit of sense. In line with the paper, it shouldn't be that hard
172!       to figure out. The core of the algorithm is described on pp. 68-70
173!       and on pp. 94-95. Also see Corana et al. pp. 264-9.
174!    3. To see how it selects points and makes decisions about uphill
175!       and downhill moves, set IPRINT = 3 (very detailed intermediate
176!       output) and MAXEVL = 100 (only 100 function evaluations to limit
177!       output).
178!    4. To see the importance of different temperatures, try starting
179!       with a very low one (say T = 10E-5). You'll see (i) it never
180!       escapes from the local optima (in annealing terminology, it
181!       quenches) & (ii) the step length (VM) will be quite small. This
182!       is a key part of the algorithm: as temperature (T) falls, step
183!       length does too. In a minor point here, note how VM is quickly
184!       reset from its initial value. Thus, the input VM is not very
185!       important. This is all the more reason to examine VM once the
186!       algorithm is underway.
187!    5. To see the effect of different parameters and their effect on
188!       the speed of the algorithm, try RT = .95 & RT = .1. Notice the
189!       vastly different speed for optimization. Also try NT = 20. Note
190!       that this sample function is quite easy to optimize, so it will
191!       tolerate big changes in these parameters. RT and NT are the
192!       parameters one should adjust to modify the runtime of the
193!       algorithm and its robustness.
194!    6. Try constraining the algorithm with either LB or UB.
195
196      SUBROUTINE SA(N,X,MAX,RT,EPS,NS,NT,NEPS,MAXEVL,LB,UB,C,IPRINT,    &
197     &ISEED1,ISEED2,T,VM,XOPT,FOPT,NACC,NFCNEV,NOBDS,IER,               &
198     &FSTAR,XP,NACP)
199      implicit none
200
201!  Version: 3.2
202!  Date: 1/22/94.
203!  Differences compared to Version 2.0:
204!     1. If a trial is out of bounds, a point is randomly selected
205!        from LB(i) to UB(i). Unlike in version 2.0, this trial is
206!        evaluated and is counted in acceptances and rejections.
207!        All corresponding documentation was changed as well.
208!  Differences compared to Version 3.0:
209!     1. If VM(i) > (UB(i) - LB(i)), VM is set to UB(i) - LB(i).
210!        The idea is that if T is high relative to LB & UB, most
211!        points will be accepted, causing VM to rise. But, in this
212!        situation, VM has little meaning; particularly if VM is
213!        larger than the acceptable region. Setting VM to this size
214!        still allows all parts of the allowable region to be selected.
215!  Differences compared to Version 3.1:
216!     1. Test made to see if the initial temperature is positive.
217!     2. WRITE statements prettied up.
218!     3. References to paper updated.
219!
220!  Synopsis:
221!  This routine implements the continuous simulated annealing global
222!  optimization algorithm described in Corana et al.'s article
223!  "Minimizing Multimodal Functions of Continuous Variables with the
224!  "Simulated Annealing" Algorithm" in the September 1987 (vol. 13,
225!  no. 3, pp. 262-280) issue of the ACM Transactions on Mathematical
226!  Software.
227!
228!  A very quick (perhaps too quick) overview of SA:
229!     SA tries to find the global optimum of an N dimensional function.
230!  It moves both up and downhill and as the optimization process
231!  proceeds, it focuses on the most promising area.
232!     To start, it randomly chooses a trial point within the step length
233!  VM (a vector of length N) of the user selected starting point. The
234!  function is evaluated at this trial point and its value is compared
235!  to its value at the initial point.
236!     In a maximization problem, all uphill moves are accepted and the
237!  algorithm continues from that trial point. Downhill moves may be
238!  accepted; the decision is made by the Metropolis criteria. It uses T
239!  (temperature) and the size of the downhill move in a probabilistic
240!  manner. The smaller T and the size of the downhill move are, the more
241!  likely that move will be accepted. If the trial is accepted, the
242!  algorithm moves on from that point. If it is rejected, another point
243!  is chosen instead for a trial evaluation.
244!     Each element of VM periodically adjusted so that half of all
245!  function evaluations in that direction are accepted.
246!     A fall in T is imposed upon the system with the RT variable by
247!  T(i+1) = RT*T(i) where i is the ith iteration. Thus, as T declines,
248!  downhill moves are less likely to be accepted and the percentage of
249!  rejections rise. Given the scheme for the selection for VM, VM falls.
250!  Thus, as T declines, VM falls and SA focuses upon the most promising
251!  area for optimization.
252!
253!  The importance of the parameter T:
254!     The parameter T is crucial in using SA successfully. It influences
255!  VM, the step length over which the algorithm searches for optima. For
256!  a small intial T, the step length may be too small; thus not enough
257!  of the function might be evaluated to find the global optima. The user
258!  should carefully examine VM in the intermediate output (set IPRINT =
259!  1) to make sure that VM is appropriate. The relationship between the
260!  initial temperature and the resulting step length is function
261!  dependent.
262!     To determine the starting temperature that is consistent with
263!  optimizing a function, it is worthwhile to run a trial run first. Set
264!  RT = 1.5 and T = 1.0. With RT > 1.0, the temperature increases and VM
265!  rises as well. Then select the T that produces a large enough VM.
266!
267!  For modifications to the algorithm and many details on its use,
268!  (particularly for econometric applications) see Goffe, Ferrier
269!  and Rogers, "Global Optimization of Statistical Functions with
270!  Simulated Annealing," Journal of Econometrics, vol. 60, no. 1/2,
271!  Jan./Feb. 1994, pp. 65-100.
272!  For more information, contact
273!              Bill Goffe
274!              Department of Economics and International Business
275!              University of Southern Mississippi
276!              Hattiesburg, MS  39506-5072
277!              (601) 266-4484 (office)
278!              (601) 266-4920 (fax)
279!              bgoffe@whale.st.usm.edu (Internet)
280!
281!  As far as possible, the parameters here have the same name as in
282!  the description of the algorithm on pp. 266-8 of Corana et al.
283!
284!  In this description, SP is single precision, DP is double precision,
285!  INT is integer, L is logical and (N) denotes an array of length n.
286!  Thus, DP(N) denotes a double precision array of length n.
287!
288!  Input Parameters:
289!    Note: The suggested values generally come from Corana et al. To
290!          drastically reduce runtime, see Goffe et al., pp. 90-1 for
291!          suggestions on choosing the appropriate RT and NT.
292!    N - Number of variables in the function to be optimized. (INT)
293!    X - The starting values for the variables of the function to be
294!        optimized. (DP(N))
295!    MAX - Denotes whether the function should be maximized or
296!          minimized. A true value denotes maximization while a false
297!          value denotes minimization. Intermediate output (see IPRINT)
298!          takes this into account. (L)
299!    RT - The temperature reduction factor. The value suggested by
300!         Corana et al. is .85. See Goffe et al. for more advice. (DP)
301!    EPS - Error tolerance for termination. If the final function
302!          values from the last neps temperatures differ from the
303!          corresponding value at the current temperature by less than
304!          EPS and the final function value at the current temperature
305!          differs from the current optimal function value by less than
306!          EPS, execution terminates and IER = 0 is returned. (EP)
307!    NS - Number of cycles. After NS*N function evaluations, each
308!         element of VM is adjusted so that approximately half of
309!         all function evaluations are accepted. The suggested value
310!         is 20. (INT)
311!    NT - Number of iterations before temperature reduction. After
312!         NT*NS*N function evaluations, temperature (T) is changed
313!         by the factor RT. Value suggested by Corana et al. is
314!         MAX(100, 5*N). See Goffe et al. for further advice. (INT)
315!    NEPS - Number of final function values used to decide upon termi-
316!           nation. See EPS. Suggested value is 4. (INT)
317!    MAXEVL - The maximum number of function evaluations. If it is
318!             exceeded, IER = 1. (INT)
319!    LB - The lower bound for the allowable solution variables. (DP(N))
320!    UB - The upper bound for the allowable solution variables. (DP(N))
321!         If the algorithm chooses X(I) .LT. LB(I) or X(I) .GT. UB(I),
322!         I = 1, N, a point is from inside is randomly selected. This
323!         This focuses the algorithm on the region inside UB and LB.
324!         Unless the user wishes to concentrate the search to a par-
325!         ticular region, UB and LB should be set to very large positive
326!         and negative values, respectively. Note that the starting
327!         vector X should be inside this region. Also note that LB and
328!         UB are fixed in position, while VM is centered on the last
329!         accepted trial set of variables that optimizes the function.
330!    C - Vector that controls the step length adjustment. The suggested
331!        value for all elements is 2.0. (DP(N))
332!    IPRINT - controls printing inside SA. (INT)
333!             Values: 0 - Nothing printed.
334!                     1 - Function value for the starting value and
335!                         summary results before each temperature
336!                         reduction. This includes the optimal
337!                         function value found so far, the total
338!                         number of moves (broken up into uphill,
339!                         downhill, accepted and rejected), the
340!                         number of out of bounds trials, the
341!                         number of new optima found at this
342!                         temperature, the current optimal X and
343!                         the step length VM. Note that there are
344!                         N*NS*NT function evalutations before each
345!                         temperature reduction. Finally, notice is
346!                         is also given upon achieveing the termination
347!                         criteria.
348!                     2 - Each new step length (VM), the current optimal
349!                         X (XOPT) and the current trial X (X). This
350!                         gives the user some idea about how far X
351!                         strays from XOPT as well as how VM is adapting
352!                         to the function.
353!                     3 - Each function evaluation, its acceptance or
354!                         rejection and new optima. For many problems,
355!                         this option will likely require a small tree
356!                         if hard copy is used. This option is best
357!                         used to learn about the algorithm. A small
358!                         value for MAXEVL is thus recommended when
359!                         using IPRINT = 3.
360!             Suggested value: 1
361!             Note: For a given value of IPRINT, the lower valued
362!                   options (other than 0) are utilized.
363!    ISEED1 - The first seed for the random number generator RANMAR.
364!             0 .LE. ISEED1 .LE. 31328. (INT)
365!    ISEED2 - The second seed for the random number generator RANMAR.
366!             0 .LE. ISEED2 .LE. 30081. Different values for ISEED1
367!             and ISEED2 will lead to an entirely different sequence
368!             of trial points and decisions on downhill moves (when
369!             maximizing). See Goffe et al. on how this can be used
370!             to test the results of SA. (INT)
371!
372!  Input/Output Parameters:
373!    T - On input, the initial temperature. See Goffe et al. for advice.
374!        On output, the final temperature. (DP)
375!    VM - The step length vector. On input it should encompass the
376!         region of interest given the starting value X. For point
377!         X(I), the next trial point is selected is from X(I) - VM(I)
378!         to  X(I) + VM(I). Since VM is adjusted so that about half
379!         of all points are accepted, the input value is not very
380!         important (i.e. is the value is off, SA adjusts VM to the
381!         correct value). (DP(N))
382!
383!  Output Parameters:
384!    XOPT - The variables that optimize the function. (DP(N))
385!    FOPT - The optimal value of the function. (DP)
386!    NACC - The number of accepted function evaluations. (INT)
387!    NFCNEV - The total number of function evaluations. In a minor
388!             point, note that the first evaluation is not used in the
389!             core of the algorithm; it simply initializes the
390!             algorithm. (INT).
391!    NOBDS - The total number of trial function evaluations that
392!            would have been out of bounds of LB and UB. Note that
393!            a trial point is randomly selected between LB and UB.
394!            (INT)
395!    IER - The error return number. (INT)
396!          Values: 0 - Normal return; termination criteria achieved.
397!                  1 - Number of function evaluations (NFCNEV) is
398!                      greater than the maximum number (MAXEVL).
399!                  2 - The starting value (X) is not inside the
400!                      bounds (LB and UB).
401!                  3 - The initial temperature is not positive.
402!                  99 - Should not be seen; only used internally.
403!
404!  Work arrays that must be dimensioned in the calling routine:
405!       RWK1 (DP(NEPS))  (FSTAR in SA)
406!       RWK2 (DP(N))     (XP    "  " )
407!       IWK  (INT(N))    (NACP  "  " )
408!
409!  Required Functions (included):
410!    EXPREP - Replaces the function EXP to avoid under- and overflows.
411!             It may have to be modified for non IBM-type main-
412!             frames. (DP)
413!    RMARIN - Initializes the random number generator RANMAR.
414!    RANMAR - The actual random number generator. Note that
415!             RMARIN must run first (SA does this). It produces uniform
416!             random numbers on [0,1]. These routines are from
417!             Usenet's comp.lang.fortran. For a reference, see
418!             "Toward a Universal Random Number Generator"
419!             by George Marsaglia and Arif Zaman, Florida State
420!             University Report: FSU-SCRI-87-50 (1987).
421!             It was later modified by F. James and published in
422!             "A Review of Pseudo-random Number Generators." For
423!             further information, contact stuart@ads.com. These
424!             routines are designed to be portable on any machine
425!             with a 24-bit or more mantissa. I have found it produces
426!             identical results on a IBM 3081 and a Cray Y-MP.
427!
428!  Required Subroutines (included):
429!    PRTVEC - Prints vectors.
430!    PRT1 ... PRT10 - Prints intermediate output.
431!    FCNSA - Function to be optimized. The form is
432!            SUBROUTINE FCNSA(N,X,F)
433!            INTEGER N
434!            DOUBLE PRECISION  X(N), F
435!            ...
436!            function code with F = F(X)
437!            ...
438!            RETURN
439!            END
440!          Note: This is the same form used in the multivariable
441!          minimization algorithms in the IMSL edition 10 library.
442!
443!  Machine Specific Features:
444!    1. EXPREP may have to be modified if used on non-IBM type main-
445!       frames. Watch for under- and overflows in EXPREP.
446!    2. Some FORMAT statements use G25.18; this may be excessive for
447!       some machines.
448!    3. RMARIN and RANMAR are designed to be protable; they should not
449!       cause any problems.
450
451!  Type all external variables.
452      DOUBLE PRECISION  X(*), LB(*), UB(*), C(*), VM(*), FSTAR(*),      &
453     &XOPT(*), XP(*), T, EPS, RT, FOPT
454      INTEGER  NACP(*), N, NS, NT, NEPS, NACC, MAXEVL, IPRINT,          &
455     &NOBDS, IER, NFCNEV, ISEED1, ISEED2
456      LOGICAL  MAX
457!  Type all internal variables.
458      DOUBLE PRECISION  F, FP, P, PP, RATIO
459      INTEGER  NUP, NDOWN, NREJ, NNEW, LNOBDS, H, I, J, M
460      LOGICAL  QUIT
461
462!  Type all functions.
463      DOUBLE PRECISION  EXPREP
464      REAL  RANMAR
465
466!  Initialize the random number generator RANMAR.
467      CALL RMARIN(ISEED1,ISEED2)
468!  Set initial values.
469      NACC = 0
470      NOBDS = 0
471      NFCNEV = 0
472      IER = 99
473
474      DO I = 1, N
475        XOPT(I) = X(I)
476        NACP(I) = 0
477      enddo
478
479      DO I = 1, NEPS
480        FSTAR(I) = 1.0D+20
481      enddo
482
483!  If the initial temperature is not positive, notify the user and
484!  return to the calling routine.
485      IF (T .LE. 0.0) THEN
486        WRITE(*,'(/,''  THE INITIAL TEMPERATURE IS NOT POSITIVE.'')')
487!         '',
488!     1             /,''  RESET THE VARIABLE T. ''/)')
489        IER = 3
490        RETURN
491      END IF
492
493!  If the initial value is out of bounds, notify the user and return
494!  to the calling routine.
495      DO I = 1, N
496        IF ((X(I) .GT. UB(I)) .OR. (X(I) .LT. LB(I))) THEN
497          CALL PRT1
498          IER = 2
499          RETURN
500        END IF
501
502      enddo
503
504!  Evaluate the function with input X and return value as F.
505
506      CALL FCNSA(N,X,F)
507
508!  If the function is to be minimized, switch the sign of the function.
509!  Note that all intermediate and final output switches the sign back
510!  to eliminate any possible confusion for the user.
511      IF(.NOT. MAX) F = -F
512      NFCNEV = NFCNEV + 1
513      FOPT = F
514      FSTAR(1) = F
515      IF(IPRINT .GE. 1) CALL PRT2(MAX,N,X,F)
516
517!  Start the main loop. Note that it terminates if (i) the algorithm
518!  succesfully optimizes the function or (ii) there are too many
519!  function evaluations (more than MAXEVL).
520100   NUP = 0
521      NREJ = 0
522      NNEW = 0
523      NDOWN = 0
524      LNOBDS = 0
525
526      DO M = 1,NT
527        DO J = 1, NS
528          DO H = 1, N
529
530!  Generate XP, the trial value of X. Note use of VM to choose XP.
531            DO I = 1, N
532              IF (I .EQ. H) THEN
533999             XP(I) = X(I) + (RANMAR()*2.- 1.) * VM(I)
534              ELSE
535                XP(I) = X(I)
536              END IF
537
538!  If XP is out of bounds, select a point in bounds for the trial.
539
540              IF((XP(I) .LT. LB(I)) .OR. (XP(I) .GT. UB(I))) THEN
541                XP(I) = LB(I) + (UB(I) - LB(I))*RANMAR()
542                LNOBDS = LNOBDS + 1
543                NOBDS = NOBDS + 1
544                IF(IPRINT .GE. 3) CALL PRT3(MAX,N,XP,X,F)
545              END IF
546
547            enddo
548
549            IF((XP(h) .LT. LB(h)) .OR. (XP(h) .GT. UB(h))) THEN
550              XP(h) = LB(h) + (UB(h) - LB(h))*RANMAR()
551              LNOBDS = LNOBDS + 1
552              NOBDS = NOBDS + 1
553              IF(IPRINT .GE. 3) CALL PRT3(MAX,N,XP,X,F)
554            END IF
555
556
557!  Evaluate the function with the trial point XP and return as FP.
558            CALL FCNSA(N,XP,FP)
559            IF(.NOT. MAX) FP = -FP
560            NFCNEV = NFCNEV + 1
561            IF(IPRINT .GE. 3) CALL PRT4(MAX,N,XP,X,FP,F)
562
563!  If too many function evaluations occur, terminate the algorithm.
564            IF(NFCNEV .GE. MAXEVL) THEN
565              CALL PRT5
566              IF (.NOT. MAX) FOPT = -FOPT
567              IER = 1
568              RETURN
569            END IF
570
571!  Accept the new point if the function value increases.
572            IF(FP .Gt. F) THEN
573              IF(IPRINT .GE. 3) THEN
574                WRITE(*,'(''  POINT ACCEPTED'')')
575              END IF
576              DO I = 1, N
577                X(I) = XP(I)
578              enddo
579              F = FP
580              NACC = NACC + 1
581              NACP(H) = NACP(H) + 1
582              NUP = NUP + 1
583
584!  If greater than any other point, record as new optimum.
585              IF (FP .GT. FOPT) THEN
586                IF(IPRINT .GE. 3) THEN
587                  WRITE(*,'(''  NEW OPTIMUM'')')
588                END IF
589                DO I = 1, N
590                  XOPT(I) = XP(I)
591                enddo
592                FOPT = FP
593
594                NNEW = NNEW + 1
595              END IF
596
597!  If the point is lower, use the Metropolis criteria to decide on
598!  acceptance or rejection.
599            ELSE
600              P = EXPREP((FP - F)/T)
601              PP = RANMAR()
602              IF (PP .LT. P) THEN
603                IF(IPRINT .GE. 3) CALL PRT6(MAX)
604                DO I = 1, N
605                  X(I) = XP(I)
606                enddo
607                F = FP
608                NACC = NACC + 1
609                NACP(H) = NACP(H) + 1
610                NDOWN = NDOWN + 1
611              ELSE
612                NREJ = NREJ + 1
613                IF(IPRINT .GE. 3) CALL PRT7(MAX)
614              END IF
615            END IF
616
617          enddo
618        enddo
619
620!  Adjust VM so that approximately half of all evaluations are accepted.
621        DO I = 1, N
622          RATIO = DBLE(NACP(I)) /DBLE(NS)
623          IF (RATIO .GT. .6) THEN
624            VM(I) = VM(I)*(1. + C(I)*(RATIO - .6)/.4)
625          ELSE IF (RATIO .LT. .4) THEN
626            VM(I) = VM(I)/(1. + C(I)*((.4 - RATIO)/.4))
627          END IF
628          IF (VM(I) .GT. (UB(I)-LB(I))) THEN
629            VM(I) = UB(I) - LB(I)
630          END IF
631        enddo
632
633        IF(IPRINT .GE. 2) THEN
634          CALL PRT8(N,VM,XOPT,X)
635        END IF
636
637        DO I = 1, N
638          NACP(I) = 0
639        enddo
640
641      enddo
642
643      IF(IPRINT .GE. 1) THEN
644        CALL PRT9(MAX,N,T,XOPT,VM,FOPT,NUP,NDOWN,NREJ,LNOBDS,NNEW)
645      END IF
646
647!  Check termination criteria.
648      QUIT = .FALSE.
649      FSTAR(1) = F
650      IF ((FOPT - FSTAR(1)) .LE. EPS) QUIT = .TRUE.
651      DO I = 1, NEPS
652        IF (ABS(F - FSTAR(I)) .GT. EPS) QUIT = .FALSE.
653      enddo
654
655!  Terminate SA if appropriate.
656      IF (QUIT) THEN
657        DO I = 1, N
658          X(I) = XOPT(I)
659        enddo
660        IER = 0
661        IF (.NOT. MAX) FOPT = -FOPT
662        IF(IPRINT .GE. 1) CALL PRT10
663        RETURN
664      END IF
665
666!  If termination criteria is not met, prepare for another loop.
667      T = RT*T
668      DO I = NEPS, 2, -1
669        FSTAR(I) = FSTAR(I-1)
670      enddo
671      F = FOPT
672      DO I = 1, N
673        X(I) = XOPT(I)
674      enddo
675
676!  Loop again.
677      GO TO 100
678
679      END
680
681      FUNCTION  EXPREP(RDUM)
682      implicit none
683!  This function replaces exp to avoid under- and overflows and is
684!  designed for IBM 370 type machines. It may be necessary to modify
685!  it for other machines. Note that the maximum and minimum values of
686!  EXPREP are such that they has no effect on the algorithm.
687
688      DOUBLE PRECISION  RDUM, EXPREP
689
690      IF (RDUM .GT. 174.) THEN
691        EXPREP = 3.69D+75
692      ELSE IF (RDUM .LT. -180.) THEN
693        EXPREP = 0.0
694      ELSE
695        EXPREP = EXP(RDUM)
696      END IF
697
698      RETURN
699      END
700
701      subroutine RMARIN(IJ,KL)
702      implicit none
703!  This subroutine and the next function generate random numbers. See
704!  the comments for SA for more information. The only changes from the
705!  orginal code is that (1) the test to make sure that RMARIN runs first
706!  was taken out since SA assures that this is done (this test didn't
707!  compile under IBM's VS Fortran) and (2) typing ivec as integer was
708!  taken out since ivec isn't used. With these exceptions, all following
709!  lines are original.
710
711! This is the initialization routine for the random number generator
712!     RANMAR()
713! NOTE: The seed variables can have values between:    0 <= IJ <= 31328
714!                                                      0 <= KL <= 30081
715      real s,t
716      real U(97), C, CD, CM
717      integer IJ,KL,i,j,k,l,ii,jj,m
718      integer I97, J97
719      common /raset1/ U, C, CD, CM, I97, J97
720      if( IJ .lt. 0  .or.  IJ .gt. 31328  .or.                          &
721     &KL .lt. 0  .or.  KL .gt. 30081 ) then
722        print '(A)',' The first random number seed must have a value'
723        print '(A)',' between 0 and 31328'
724        print '(A)',' The second seed must have a value between 0 and'
725        print '(A)',' 30081'
726        stop
727      endif
728      i = mod(IJ/177, 177) + 2
729      j = mod(IJ    , 177) + 2
730      k = mod(KL/169, 178) + 1
731      l = mod(KL,     169)
732      do ii = 1, 97
733        s = 0.0
734        t = 0.5
735        do jj = 1, 24
736          m = mod(mod(i*j, 179)*k, 179)
737          i = j
738          j = k
739          k = m
740          l = mod(53*l+1, 169)
741          if (mod(l*m, 64) .ge. 32) then
742            s = s + t
743          endif
744          t = 0.5 * t
745        enddo
746        U(ii) = s
747      enddo
748      C = 362436.0 / 16777216.0
749      CD = 7654321.0 / 16777216.0
750      CM = 16777213.0 /16777216.0
751      I97 = 97
752      J97 = 33
753      return
754      end
755
756      real function ranmar()
757      implicit none
758      real U(97), C, CD, CM, uni
759      integer I97, J97
760      common /raset1/ U, C, CD, CM, I97, J97
761      uni = U(I97) - U(J97)
762      if( uni .lt. 0.0 ) uni = uni + 1.0
763      U(I97) = uni
764      I97 = I97 - 1
765      if(I97 .eq. 0) I97 = 97
766      J97 = J97 - 1
767      if(J97 .eq. 0) J97 = 97
768      C = C - CD
769      if( C .lt. 0.0 ) C = C + CM
770      uni = uni - C
771      if( uni .lt. 0.0 ) uni = uni + 1.0
772      RANMAR = uni
773      return
774      END
775
776      SUBROUTINE PRT1
777      implicit none
778!  This subroutine prints intermediate output, as does PRT2 through
779!  PRT10. Note that if SA is minimizing the function, the sign of the
780!  function value and the directions (up/down) are reversed in all
781!  output to correspond with the actual function optimization. This
782!  correction is because SA was written to maximize functions and
783!  it minimizes by maximizing the negative a function.
784
785      WRITE(*,'(/,''THE STARTING VALUE (X) IS OUTSIDE THE BOUNDS '')')
786      WRITE(*,'(/,''(LB AND UB). EXECUTION TERMINATED WITHOUT ANY'')')
787      WRITE(*,'(/,''OPTIMIZATION. RESPECIFY X, UB OR LB SO THAT  '')')
788      WRITE(*,'(/,''LB(I) .LT. X(I) .LT. UB(I), I = 1, N. ''/)')
789
790      RETURN
791      END
792
793      SUBROUTINE PRT2(MAX,N,X,F)
794      implicit none
795
796      DOUBLE PRECISION  X(*), F
797      INTEGER  N
798      LOGICAL  MAX
799
800      WRITE(*,'(''  '')')
801      CALL PRTVEC(X,N,'INITIAL X')
802      IF (MAX) THEN
803        WRITE(*,'(''  INITIAL F: '',/, G25.18)') F
804      ELSE
805        WRITE(*,'(''  INITIAL F: '',/, G25.18)') -F
806      END IF
807
808      RETURN
809      END
810
811      SUBROUTINE PRT3(MAX,N,XP,X,F)
812      implicit none
813
814      DOUBLE PRECISION  XP(*),X(*),F
815      INTEGER  N
816      LOGICAL  MAX
817
818      WRITE(*,'(''  '')')
819      CALL PRTVEC(X,N,'CURRENT X')
820      IF (MAX) THEN
821        WRITE(*,'(''  CURRENT F: '',G25.18)') F
822      ELSE
823        WRITE(*,'(''  CURRENT F: '',G25.18)') -F
824      END IF
825      CALL PRTVEC(XP,N,'TRIAL X')
826      WRITE(*,'(''  POINT REJECTED SINCE OUT OF BOUNDS'')')
827
828      RETURN
829      END
830
831      SUBROUTINE PRT4(MAX,N,XP,X,FP,F)
832      implicit none
833
834      DOUBLE PRECISION  XP(*), X(*), FP, F
835      INTEGER  N
836      LOGICAL  MAX
837
838      WRITE(*,'(''  '')')
839      CALL PRTVEC(X,N,'CURRENT X')
840      IF (MAX) THEN
841        WRITE(*,'(''  CURRENT F: '',G25.18)') F
842        CALL PRTVEC(XP,N,'TRIAL X')
843        WRITE(*,'(''  RESULTING F: '',G25.18)') FP
844      ELSE
845        WRITE(*,'(''  CURRENT F: '',G25.18)') -F
846        CALL PRTVEC(XP,N,'TRIAL X')
847        WRITE(*,'(''  RESULTING F: '',G25.18)') -FP
848      END IF
849
850      RETURN
851      END
852
853      SUBROUTINE PRT5
854      implicit none
855
856      WRITE(*, '(/,''TOO MANY FUNCTION EVALUATIONS; CONSIDER '',/)')
857      WRITE(*, '(/,''INCREASING MAXEVL OR EPS, OR DECREASING '',/)')
858      WRITE(*, '(/,''NT OR RT. THESE RESULTS ARE LIKELY TO BE '',/)')
859      WRITE(*, '(/,''POOR.'',/)')
860
861      RETURN
862      END
863
864      SUBROUTINE PRT6(MAX)
865      implicit none
866
867      LOGICAL  MAX
868
869      IF (MAX) THEN
870        WRITE(*,'(''  THOUGH LOWER, POINT ACCEPTED'')')
871      ELSE
872        WRITE(*,'(''  THOUGH HIGHER, POINT ACCEPTED'')')
873      END IF
874
875      RETURN
876      END
877
878      SUBROUTINE PRT7(MAX)
879      implicit none
880
881      LOGICAL  MAX
882
883      IF (MAX) THEN
884        WRITE(*,'(''  LOWER POINT REJECTED'')')
885      ELSE
886        WRITE(*,'(''  HIGHER POINT REJECTED'')')
887      END IF
888
889      RETURN
890      END
891
892      SUBROUTINE PRT8(N,VM,XOPT,X)
893      implicit none
894
895      DOUBLE PRECISION  VM(*), XOPT(*), X(*)
896      INTEGER  N
897
898      WRITE(*,'(/''INTERMEDIATE RESULTS AFTER'',/)')
899      WRITE(*,'(/'' STEP LENGTH ADJUSTMENT'',/)')
900      CALL PRTVEC(VM,N,'NEW STEP LENGTH (VM)')
901      CALL PRTVEC(XOPT,N,'CURRENT OPTIMAL X')
902      CALL PRTVEC(X,N,'CURRENT X')
903      WRITE(*,'('' '')')
904
905      RETURN
906      END
907
908      SUBROUTINE PRT9(MAX,N,T,XOPT,VM,FOPT,NUP,NDOWN,NREJ,LNOBDS,NNEW)
909      implicit none
910
911      DOUBLE PRECISION  XOPT(*), VM(*), T, FOPT
912      INTEGER  N, NUP, NDOWN, NREJ, LNOBDS, NNEW, TOTMOV
913      LOGICAL  MAX
914
915      TOTMOV = NUP + NDOWN + NREJ
916
917      WRITE(*,'(/,''INTERMEDIATE RESULTS BEFORE'',/)')
918      WRITE(*,'(/,  ''  NEXT TEMPERATURE REDUCTION'',/)')
919      WRITE(*,'(''  CURRENT TEMPERATURE:            '',G12.5)') T
920      IF (MAX) THEN
921        WRITE(*,'(''  MAX FUNCTION VALUE SO FAR:  '',G25.18)') FOPT
922        WRITE(*,'(''  TOTAL MOVES:                '',I8)') TOTMOV
923        WRITE(*,'(''     UPHILL:                  '',I8)') NUP
924        WRITE(*,'(''     ACCEPTED DOWNHILL:       '',I8)') NDOWN
925        WRITE(*,'(''     REJECTED DOWNHILL:       '',I8)') NREJ
926        WRITE(*,'(''  OUT OF BOUNDS TRIALS:       '',I8)') LNOBDS
927        WRITE(*,'(''  NEW MAXIMA THIS TEMPERATURE:'',I8)') NNEW
928      ELSE
929        WRITE(*,'(''  MIN FUNCTION VALUE SO FAR:  '',D25.18)') -FOPT
930        WRITE(*,'(''  TOTAL MOVES:                '',I8)') TOTMOV
931        WRITE(*,'(''     DOWNHILL:                '',I8)')  NUP
932        WRITE(*,'(''     ACCEPTED UPHILL:         '',I8)')  NDOWN
933        WRITE(*,'(''     REJECTED UPHILL:         '',I8)')  NREJ
934        WRITE(*,'(''  TRIALS OUT OF BOUNDS:       '',I8)')  LNOBDS
935        WRITE(*,'(''  NEW MINIMA THIS TEMPERATURE:'',I8)')  NNEW
936      END IF
937      CALL PRTVEC(XOPT,N,'CURRENT OPTIMAL X')
938      CALL PRTVEC(VM,N,'STEP LENGTH (VM)')
939      WRITE(*,'('' '')')
940
941      RETURN
942      END
943
944      SUBROUTINE PRT10
945      implicit none
946
947      WRITE(*,'(/,''  SA ACHIEVED TERMINATION CRITERIA. IER = 0. '',/)')
948
949      RETURN
950      END
951
952      SUBROUTINE PRTVEC(VECTOR,NCOLS,NAME)
953      implicit none
954!  This subroutine prints the double precision vector named VECTOR.
955!  Elements 1 thru NCOLS will be printed. NAME is a character variable
956!  that describes VECTOR. Note that if NAME is given in the call to
957!  PRTVEC, it must be enclosed in quotes. If there are more than 10
958!  elements in VECTOR, 10 elements will be printed on each line.
959
960      integer i,j,ll,lines
961      INTEGER NCOLS
962      DOUBLE PRECISION VECTOR(NCOLS)
963      CHARACTER *(*) NAME
964
965      WRITE(*,1001) NAME
966
967      IF (NCOLS .GT. 10) THEN
968        LINES = INT(NCOLS/10.)
969
970        DO I = 1, LINES
971          LL = 10*(I - 1)
972          WRITE(*,1000) (VECTOR(J),J = 1+LL, 10+LL)
973        enddo
974
975        WRITE(*,1000) (VECTOR(J),J = 11+LL, NCOLS)
976      ELSE
977        WRITE(*,1000) (VECTOR(J),J = 1, NCOLS)
978      END IF
979
980 1000 FORMAT( 10(G12.5,1X))
981 1001 FORMAT(/,25X,A)
982
983      RETURN
984      END
Note: See TracBrowser for help on using the repository browser.