| 1 | *
 | 
|---|
| 2 | * $Id: mnderi.F,v 1.1.1.1 2003-06-11 14:18:26 cmv Exp $
 | 
|---|
| 3 | *
 | 
|---|
| 4 | * $Log: not supported by cvs2svn $
 | 
|---|
| 5 | * Revision 1.2  1996/03/15 18:02:43  james
 | 
|---|
| 6 | *     Modified Files:
 | 
|---|
| 7 | * mnderi.F eliminate possible division by zero
 | 
|---|
| 8 | * mnexcm.F suppress print on STOP when print flag=-1
 | 
|---|
| 9 | *          set FVAL3 to flag if FCN already called with IFLAG=3
 | 
|---|
| 10 | * mninit.F set version 96.03
 | 
|---|
| 11 | * mnlims.F remove arguments, not needed
 | 
|---|
| 12 | * mnmigr.F VLEN -> LENV in debug print statement
 | 
|---|
| 13 | * mnparm.F move call to MNRSET to after NPAR redefined, to zero all
 | 
|---|
| 14 | * mnpsdf.F eliminate possible division by zero
 | 
|---|
| 15 | * mnscan.F suppress printout when print flag =-1
 | 
|---|
| 16 | * mnset.F  remove arguments in call to MNLIMS
 | 
|---|
| 17 | * mnsimp.F fix CSTATU so status is PROGRESS only if new minimum
 | 
|---|
| 18 | * mnvert.F eliminate possible division by zero
 | 
|---|
| 19 | *
 | 
|---|
| 20 | * Revision 1.1.1.1  1996/03/07 14:31:29  mclareni
 | 
|---|
| 21 | * Minuit
 | 
|---|
| 22 | *
 | 
|---|
| 23 | *
 | 
|---|
| 24 | #include "minuit/pilot.h"
 | 
|---|
| 25 |       SUBROUTINE MNDERI(FCN,FUTIL)
 | 
|---|
| 26 | #include "minuit/d506dp.inc"
 | 
|---|
| 27 | CC        Calculates the first derivatives of FCN (GRD),
 | 
|---|
| 28 | CC        either by finite differences or by transforming the user-
 | 
|---|
| 29 | CC        supplied derivatives to internal coordinates,
 | 
|---|
| 30 | CC        according to whether ISW(3) is zero or one.
 | 
|---|
| 31 | CC
 | 
|---|
| 32 | #include "minuit/d506cm.inc"
 | 
|---|
| 33 |       EXTERNAL FCN,FUTIL
 | 
|---|
| 34 |       LOGICAL LDEBUG
 | 
|---|
| 35 |       CHARACTER CBF1*22
 | 
|---|
| 36 |       NPARX = NPAR
 | 
|---|
| 37 |       LDEBUG = (IDBG(2) .GE. 1)
 | 
|---|
| 38 |       IF (AMIN .EQ. UNDEFI)  CALL MNAMIN(FCN,FUTIL)
 | 
|---|
| 39 |       IF (ISW(3) .EQ. 1)  GO TO 100
 | 
|---|
| 40 |       IF (LDEBUG) THEN
 | 
|---|
| 41 | C                       make sure starting at the right place
 | 
|---|
| 42 |         CALL MNINEX(X)
 | 
|---|
| 43 |         NPARX = NPAR
 | 
|---|
| 44 |         CALL FCN(NPARX,GIN,FS1,U,4,FUTIL)
 | 
|---|
| 45 |         NFCN = NFCN + 1
 | 
|---|
| 46 |         IF (FS1 .NE. AMIN) THEN
 | 
|---|
| 47 |            DF = AMIN - FS1
 | 
|---|
| 48 |            WRITE (CBF1(1:12),'(G12.3)') DF
 | 
|---|
| 49 |            CALL MNWARN('D','MNDERI',
 | 
|---|
| 50 |      +         'function value differs from AMIN by '//CBF1(1:12) )
 | 
|---|
| 51 |            AMIN = FS1
 | 
|---|
| 52 |         ENDIF
 | 
|---|
| 53 |           WRITE
 | 
|---|
| 54 |      +   (ISYSWR,'(/''  FIRST DERIVATIVE DEBUG PRINTOUT.  MNDERI''/
 | 
|---|
| 55 |      +   '' PAR    DERIV     STEP      MINSTEP   OPTSTEP '',
 | 
|---|
| 56 |      +   '' D1-D2    2ND DRV'')')
 | 
|---|
| 57 |       ENDIF
 | 
|---|
| 58 |       DFMIN = 8. * EPSMA2*(ABS(AMIN)+UP)
 | 
|---|
| 59 |       VRYSML = 8.* EPSMAC**2
 | 
|---|
| 60 |       IF (ISTRAT .LE. 0) THEN
 | 
|---|
| 61 |          NCYC = 2
 | 
|---|
| 62 |          TLRSTP = 0.5
 | 
|---|
| 63 |          TLRGRD = 0.1
 | 
|---|
| 64 |       ELSE IF (ISTRAT .EQ. 1) THEN
 | 
|---|
| 65 |          NCYC = 3
 | 
|---|
| 66 |          TLRSTP = 0.3
 | 
|---|
| 67 |          TLRGRD = 0.05
 | 
|---|
| 68 |       ELSE
 | 
|---|
| 69 |          NCYC = 5
 | 
|---|
| 70 |          TLRSTP = 0.1
 | 
|---|
| 71 |          TLRGRD = 0.02
 | 
|---|
| 72 |       ENDIF
 | 
|---|
| 73 | C                                loop over variable parameters
 | 
|---|
| 74 |       DO 60  I=1,NPAR
 | 
|---|
| 75 |       EPSPRI = EPSMA2 + ABS(GRD(I)*EPSMA2)
 | 
|---|
| 76 | C         two-point derivatives always assumed necessary
 | 
|---|
| 77 | C         maximum number of cycles over step size depends on strategy
 | 
|---|
| 78 |       XTF = X(I)
 | 
|---|
| 79 |       STEPB4 = 0.
 | 
|---|
| 80 | C                               loop as little as possible here!
 | 
|---|
| 81 |       DO 45 ICYC= 1, NCYC
 | 
|---|
| 82 | C                 ........ theoretically best step
 | 
|---|
| 83 |       OPTSTP = SQRT(DFMIN/(ABS(G2(I))+EPSPRI))
 | 
|---|
| 84 | C                     step cannot decrease by more than a factor of ten
 | 
|---|
| 85 |       STEP = MAX(OPTSTP, ABS(0.1*GSTEP(I)))
 | 
|---|
| 86 | C                 but if parameter has limits, max step size = 0.5
 | 
|---|
| 87 |       IF (GSTEP(I).LT.ZERO .AND. STEP.GT.0.5)  STEP=0.5
 | 
|---|
| 88 | C                 and not more than ten times the previous step
 | 
|---|
| 89 |       STPMAX = 10.*ABS(GSTEP(I))
 | 
|---|
| 90 |       IF (STEP .GT. STPMAX)  STEP = STPMAX
 | 
|---|
| 91 | C                 minimum step size allowed by machine precision
 | 
|---|
| 92 |       STPMIN = MAX(VRYSML, 8.*ABS(EPSMA2*X(I)))
 | 
|---|
| 93 |       IF (STEP .LT. STPMIN)  STEP = STPMIN
 | 
|---|
| 94 | C                 end of iterations if step change less than factor 2
 | 
|---|
| 95 |       IF (ABS((STEP-STEPB4)/STEP) .LT. TLRSTP)  GO TO 50
 | 
|---|
| 96 | C         take step positive
 | 
|---|
| 97 |       GSTEP(I) = SIGN(STEP, GSTEP(I))
 | 
|---|
| 98 |       STEPB4 = STEP
 | 
|---|
| 99 |       X(I) = XTF + STEP
 | 
|---|
| 100 |       CALL MNINEX(X)
 | 
|---|
| 101 |       CALL FCN(NPARX,GIN,FS1,U,4,FUTIL)
 | 
|---|
| 102 |       NFCN=NFCN+1
 | 
|---|
| 103 | C         take step negative
 | 
|---|
| 104 |       X(I) = XTF - STEP
 | 
|---|
| 105 |       CALL MNINEX(X)
 | 
|---|
| 106 |       CALL FCN(NPARX,GIN,FS2,U,4,FUTIL)
 | 
|---|
| 107 |       NFCN=NFCN+1
 | 
|---|
| 108 |       GRBFOR = GRD(I)
 | 
|---|
| 109 |       GRD(I) = (FS1-FS2)/(2.0*STEP)
 | 
|---|
| 110 |       G2(I) = (FS1+FS2-2.0*AMIN)/(STEP**2)
 | 
|---|
| 111 |       X(I) = XTF
 | 
|---|
| 112 |       IF (LDEBUG) THEN
 | 
|---|
| 113 |          D1D2 = (FS1+FS2-2.0*AMIN)/STEP
 | 
|---|
| 114 |          WRITE (ISYSWR,41) I,GRD(I),STEP,STPMIN,OPTSTP,D1D2,G2(I)
 | 
|---|
| 115 |    41    FORMAT (I4,2G11.3,5G10.2)
 | 
|---|
| 116 |       ENDIF
 | 
|---|
| 117 | C         see if another iteration is necessary
 | 
|---|
| 118 |       IF (ABS(GRBFOR-GRD(I))/(ABS(GRD(I))+DFMIN/STEP) .LT. TLRGRD)
 | 
|---|
| 119 |      +        GO TO 50
 | 
|---|
| 120 |    45 CONTINUE
 | 
|---|
| 121 | C                           end of ICYC loop. too many iterations
 | 
|---|
| 122 |       IF (NCYC .EQ. 1)  GO TO 50
 | 
|---|
| 123 |          WRITE (CBF1,'(2E11.3)')  GRD(I),GRBFOR
 | 
|---|
| 124 |          CALL MNWARN('D','MNDERI',
 | 
|---|
| 125 |      +         'First derivative not converged. '//CBF1)
 | 
|---|
| 126 |    50 CONTINUE
 | 
|---|
| 127 | C
 | 
|---|
| 128 |    60 CONTINUE
 | 
|---|
| 129 |       CALL MNINEX(X)
 | 
|---|
| 130 |       RETURN
 | 
|---|
| 131 | C                                        .  derivatives calc by fcn
 | 
|---|
| 132 |   100 DO 150 IINT= 1, NPAR
 | 
|---|
| 133 |       IEXT = NEXOFI(IINT)
 | 
|---|
| 134 |       IF (NVARL(IEXT) .GT. 1)  GO TO 120
 | 
|---|
| 135 |       GRD(IINT) = GIN(IEXT)
 | 
|---|
| 136 |       GO TO 150
 | 
|---|
| 137 |   120 DD = (BLIM(IEXT)-ALIM(IEXT))*0.5 *COS(X(IINT))
 | 
|---|
| 138 |       GRD(IINT) = GIN(IEXT)*DD
 | 
|---|
| 139 |   150 CONTINUE
 | 
|---|
| 140 |   200 RETURN
 | 
|---|
| 141 |       END
 | 
|---|