* * $Id: hisran.F,v 1.1.1.1 1996/04/01 15:02:57 mclareni Exp $ * * $Log: hisran.F,v $ * Revision 1.1.1.1 1996/04/01 15:02:57 mclareni * Mathlib gen * * #include "gen/pilot.h" SUBROUTINE HISRAN(Y,N,XLO,XWID,XRAN) C SUBROUTINE TO GENERATE RANDOM NUMBERS C ACCORDING TO AN EMPIRICAL DISTRIBUTION C SUPPLIED BY THE USER IN THE FORM OF A HISTOGRAM C F. JAMES, MAY, 1976 DIMENSION Y(*) #if !defined(CERNLIB_F90) DATA IERR,NTRY,NXHRAN,NXHPRE/0,3HRAN,3HRAN,3HPRE/ #endif #if defined(CERNLIB_F90) INTEGER :: IERR = 0, NTRY = transfer('RAN ', 0), & NXHRAN = transfer('RAN ', 0), NXHPRE = transfer('PRE ', 0) #endif IF(Y(N).EQ.1.0) GOTO 200 WRITE(6,1001) Y(N) 1001 FORMAT('0SUBROUTINE HISRAN FINDS Y(N) NOT EQUAL TO 1.0 Y(N)=' +,E15.6/' ASSUMES USER HAS SUPPLIED HISTOGRAM RATHER THAN CUMUL', +'ATIVE DISTRIBUTION AND HAS FORGOTTEN TO CALL HISPRE'/) NTRY=NXHRAN GOTO 50 C INITIALIZE HISTOGRAM TO FORM CUMULATIVE DISTRIBUTION #if (defined(CERNLIB_CDC))&&(defined(CERNLIB_F4)) ENTRY HISPRE #endif #if !defined(CERNLIB_CDC)||!defined(CERNLIB_F4) ENTRY HISPRE(Y,N) #endif NTRY=NXHPRE 50 CONTINUE YTOT = 0. DO 100 I= 1, N IF(Y(I).LT.0.) GOTO 900 YTOT = YTOT + Y(I) 100 Y(I) = YTOT IF(YTOT.LE.0.) GOTO 900 YINV = 1.0/YTOT DO 110 I= 1, N 110 Y(I) = Y(I) * YINV Y(N) = 1.0 IF(NTRY.EQ.NXHPRE) RETURN C NOW GENERATE RANDOM NUMBER BETWEEN 0 AND ONE 200 CONTINUE YR = RNDM(-1) C AND TRANSFORM IT INTO THE CORRESPONDING X-VALUE L = LOCATF(Y,N,YR) IF(L.EQ.0) GOTO 240 IF(L.GT.0) GOTO 250 C USUALLY COME HERE. L = ABS(L) XRAN = XLO + XWID * (L +((YR-Y(L))/(Y(L+1)-Y(L)))) RETURN C POINT FALLS IN FIRST BIN. SPECIAL CASE 240 XRAN = XLO + XWID * (YR/Y(1)) RETURN C GUARD AGAINST SPECIAL CASE OF FALLING ON EMPTY BIN 250 XRAN = XLO + L * XWID RETURN 900 CONTINUE IERR = IERR + 1 IF(IERR.LT.6) WRITE(6,1000)NTRY 1000 FORMAT('0ERROR IN INPUT DATA FOR HIS',A3,' VALUES NOT ALL >0'/) WRITE(6,1002) (Y(K),K=1,N) 1002 FORMAT(1X,10F13.7) XRAN = 0. RETURN END