* * $Id: mncros.F,v 1.1.1.1 1996/03/07 14:31:29 mclareni Exp $ * * $Log: mncros.F,v $ * Revision 1.1.1.1 1996/03/07 14:31:29 mclareni * Minuit * * #include "minuit/pilot.h" SUBROUTINE MNCROS(FCN,AOPT,IERCR,FUTIL) #include "minuit/d506dp.inc" CC Find point where MNEVAL=AMIN+UP, along the line through CC XMIDCR,YMIDCR with direction XDIRCR,YDIRCR, where X and Y CC are parameters KE1CR and KE2CR. If KE2CR=0 (from MINOS), CC only KE1CR is varied. From MNCONT, both are varied. CC Crossing point is at CC (U(KE1),U(KE2)) = (XMID,YMID) + AOPT*(XDIR,YDIR) CC #include "minuit/d506cm.inc" CHARACTER CHERE*10, CHARAL*28, CHSIGN*4 PARAMETER (CHERE='MNCROS ', MLSB=3, MAXITR=15, TLR=0.01) DIMENSION FLSB(MLSB),ALSB(MLSB), COEFF(3) LOGICAL LDEBUG EXTERNAL FCN,FUTIL DATA CHARAL/' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'/ LDEBUG = (IDBG(6) .GE. 1) AMINSV = AMIN C convergence when F is within TLF of AIM and next prediction C of AOPT is within TLA of previous value of AOPT AIM = AMIN + UP TLF = TLR*UP TLA = TLR XPT(1) = 0.0 YPT(1) = AIM CHPT(1) = ' ' IPT = 1 IF (KE2CR .EQ. 0) THEN XPT(2) = -1.0 YPT(2) = AMIN CHPT(2) = '.' IPT = 2 ENDIF C find the largest allowed A AULIM = 100. DO 100 IK= 1, 2 IF (IK .EQ. 1) THEN KEX = KE1CR ZMID = XMIDCR ZDIR = XDIRCR ELSE IF (KE2CR .EQ. 0) GO TO 100 KEX = KE2CR ZMID = YMIDCR ZDIR = YDIRCR ENDIF IF (NVARL(KEX) .LE. 1) GO TO 100 IF (ZDIR .EQ. ZERO) GO TO 100 ZLIM = ALIM(KEX) IF (ZDIR .GT. ZERO) ZLIM = BLIM(KEX) AULIM = MIN(AULIM,(ZLIM-ZMID)/ZDIR) 100 CONTINUE C LSB = Line Search Buffer C first point ANEXT = 0. AOPT = ANEXT LIMSET = .FALSE. IF (AULIM .LT. AOPT+TLA) LIMSET = .TRUE. CALL MNEVAL(FCN,ANEXT,FNEXT,IEREV,FUTIL) C debug printout: IF (LDEBUG) WRITE (ISYSWR,'(A,I8,A,F10.5,A,2F10.5)') + ' MNCROS: calls=',NFCN,' AIM=',AIM,' F,A=',FNEXT,AOPT IF (IEREV .GT. 0) GO TO 900 IF (LIMSET .AND. FNEXT .LE. AIM) GO TO 930 IPT = IPT + 1 XPT(IPT) = ANEXT YPT(IPT) = FNEXT CHPT(IPT)= CHARAL(IPT:IPT) ALSB(1) = ANEXT FLSB(1) = FNEXT FNEXT = MAX(FNEXT,AMINSV+0.1*UP) AOPT = SQRT((UP)/(FNEXT-AMINSV)) - 1.0 IF (ABS(FNEXT-AIM) .LT. TLF) GO TO 800 C IF (AOPT .LT. -HALF) AOPT = -HALF IF (AOPT .GT. ONE) AOPT = ONE LIMSET = .FALSE. IF (AOPT .GT. AULIM) THEN AOPT = AULIM LIMSET = .TRUE. ENDIF CALL MNEVAL(FCN,AOPT,FNEXT,IEREV,FUTIL) C debug printout: IF (LDEBUG) WRITE (ISYSWR,'(A,I8,A,F10.5,A,2F10.5)') + ' MNCROS: calls=',NFCN,' AIM=',AIM,' F,A=',FNEXT,AOPT IF (IEREV .GT. 0) GO TO 900 IF (LIMSET .AND. FNEXT .LE. AIM) GO TO 930 ALSB(2) = AOPT IPT = IPT + 1 XPT(IPT) = ALSB(2) YPT(IPT) = FNEXT CHPT(IPT)= CHARAL(IPT:IPT) FLSB(2) = FNEXT DFDA = (FLSB(2)-FLSB(1))/ (ALSB(2)-ALSB(1)) C DFDA must be positive on the contour IF (DFDA .GT. ZERO) GO TO 460 300 CALL MNWARN('D',CHERE,'Looking for slope of the right sign') MAXLK = MAXITR - IPT DO 400 IT= 1, MAXLK ALSB(1) = ALSB(2) FLSB(1) = FLSB(2) AOPT = ALSB(1) + 0.2*REAL(IT) LIMSET = .FALSE. IF (AOPT .GT. AULIM) THEN AOPT = AULIM LIMSET = .TRUE. ENDIF CALL MNEVAL(FCN,AOPT,FNEXT,IEREV,FUTIL) C debug printout: IF (LDEBUG) WRITE (ISYSWR,'(A,I8,A,F10.5,A,2F10.5)') + ' MNCROS: calls=',NFCN,' AIM=',AIM,' F,A=',FNEXT,AOPT IF (IEREV .GT. 0) GO TO 900 IF (LIMSET .AND. FNEXT .LE. AIM) GO TO 930 ALSB(2) = AOPT IPT = IPT + 1 XPT(IPT) = ALSB(2) YPT(IPT) = FNEXT CHPT(IPT)= CHARAL(IPT:IPT) FLSB(2) = FNEXT DFDA = (FLSB(2)-FLSB(1))/ (ALSB(2)-ALSB(1)) IF (DFDA .GT. ZERO) GO TO 450 400 CONTINUE CALL MNWARN('W',CHERE,'Cannot find slope of the right sign') GO TO 950 450 CONTINUE C we have two points with the right slope 460 AOPT = ALSB(2) + (AIM-FLSB(2))/DFDA FDIST = MIN(ABS(AIM -FLSB(1)),ABS(AIM -FLSB(2))) ADIST = MIN(ABS(AOPT-ALSB(1)),ABS(AOPT-ALSB(2))) TLA = TLR IF (ABS(AOPT) .GT. ONE) TLA = TLR*ABS(AOPT) IF (ADIST .LT. TLA .AND. FDIST .LT. TLF) GO TO 800 IF (IPT .GE. MAXITR) GO TO 950 BMIN = MIN(ALSB(1),ALSB(2)) - 1.0 IF (AOPT .LT. BMIN) AOPT = BMIN BMAX = MAX(ALSB(1),ALSB(2)) + 1.0 IF (AOPT .GT. BMAX) AOPT = BMAX C Try a third point LIMSET = .FALSE. IF (AOPT .GT. AULIM) THEN AOPT = AULIM LIMSET = .TRUE. ENDIF CALL MNEVAL(FCN,AOPT,FNEXT,IEREV,FUTIL) C debug printout: IF (LDEBUG) WRITE (ISYSWR,'(A,I8,A,F10.5,A,2F10.5)') + ' MNCROS: calls=',NFCN,' AIM=',AIM,' F,A=',FNEXT,AOPT IF (IEREV .GT. 0) GO TO 900 IF (LIMSET .AND. FNEXT .LE. AIM) GO TO 930 ALSB(3) = AOPT IPT = IPT + 1 XPT(IPT) = ALSB(3) YPT(IPT) = FNEXT CHPT(IPT)= CHARAL(IPT:IPT) FLSB(3) = FNEXT INEW = 3 C now we have three points, ask how many