Viewing contents of file '../idllib/contrib/groupk/expdev.pro'
;+
; NAME:
; EXPDEV
;
; PURPOSE:
; Returns an exponentially distributed, positive, random deviate
; using RAN2( seed ) as the source of uniform deviates. The
; default unit mean and zero offset of the deviates may be modified
; by setting the appropriate keywords.
;
; CATEGORY:
; Math.
;
; CALLING SEQUENCE:
;
; Result = EXPDEV( Seed [,N] )
;
; INPUTS:
; Seed: Seed for the random number generator. (It can be undefined)
;
; OPTIONAL INPUTS:
; N: Number of deviates to return, (1=Default).
;
; OPTIONAL INPUT KEYWORD PARAMETERS:
; MEAN: Mean of the deviates, (1=Default).
;
; OFFSET: Offset of the deviates, (0=Default). The resulting
; exponential distribution and its mean is offset by
; this amount.
;
; SUM: Open upper limit to the sum of all the deviates,
; (i.e. TOTAL(EXPDEV(Seed,..)) < SUM), (0=Default).
; Deviates will be generated until their sum is equal to
; or greater than this cutoff. If this keyword is specified,
; then the number of deviates generated is returned in the
; optional argument, N.
;
; CUTOFF: Minimum possible value of the deviates, (1e-37=Default).
; If set, this value MUST be > 0.
;
; MODIFICATION HISTORY:
; Written by: Han Wen, October 1995.
; 02-NOV-1995 Formerly, EXPDT, changed keywords TAU -> OFFSET,
; AVG -> MEAN, added CUTOFF keyword.
; 24-NOV-1995 Return a scalar when called with 1 argument,
; (i.e. EXPDEV(Seed)).
; 03-JAN-1996 Bugfixes: TOTAL(dts)->TOTAL(dts,/DOUBLE),
; N = round(N) -> round(N) > 1
; 28-MAR-1996 This SPECIAL version for the AIX utilized RAN2
; instead of RANDOMU.
;-
function EXPDEV, Seed, N, MEAN=Mean, OFFSET=Offset, CUTOFF=Cutoff, SUM=Sum
NP = N_PARAMS()
if (NP lt 2) then N=1
if (N_ELEMENTS(Mean) eq 0) then Mean = 1 $
else if (Mean le 0) then message,'MEAN must be > 0.'
if (N_ELEMENTS(Offset) eq 0) then Offset = 0
if (N_ELEMENTS(Cutoff) eq 0) then Cutoff = 1.e-37 $
else if (Cutoff le 0) then message,'CUTOFF must be > 0.'
if (N_ELEMENTS(Sum) eq 0) then Sum = 0 $
else if (Sum le Offset) then begin
N = 0
dts = -1
return, dts
endif
if (Sum eq 0) then begin
pdf = 1./Mean * RAN2(Seed,N) > Cutoff
dts = Offset -Mean*alog(pdf*Mean)
if (NP lt 2) then dts=dts(0)
endif else begin
rho = 1./Mean
N = rho*Sum/(1.+rho*Offset) ; Estimate of how many
N = round(N) > 1 ; deviates to generate
nadd = 0L
pdf = rho * RAN2(Seed,N) > Cutoff
dts = Offset -Mean*alog(pdf*Mean)
tsum = TOTAL(dts,/DOUBLE)
; If sum of current deviates is LESS than SUM then
; generate additional deviates one at a time until the
; sum of all the deviates is > SUM.
if (tsum lt Sum) then begin
repeat begin
pdf = rho * RAN2(Seed) > Cutoff
new_dt = Offset -Mean*alog(pdf*Mean)
dts = [dts,new_dt]
tsum = tsum + new_dt
nadd = nadd + 1
endrep until (tsum ge Sum)
dts = dts(0:N+nadd-2)
if (N eq 0) and (nadd gt 2) then begin
N = nadd-2
dts = dts(1:N)
endif else N = N + nadd-1
; If the sum of current deviates is GREATER than or EQUAL to
; SUM then eliminate deviates one at a time until the
; sum of the remaining deviates is < SUM.
endif else begin
k = N
repeat begin
k = k-1
tsum = tsum - dts(k)
endrep until (tsum lt Sum)
N = k
if (N gt 0) then dts = dts(0:N-1) $
else dts = -1
endelse
if (N le 1) then dts=dts(0)
endelse
return,dts
end