Viewing contents of file '../idllib/contrib/groupk/fasper.pro'
;+
; NAME:
; FASPER
;
; PURPOSE:
; Given abscissas x (which need not be equally spaced) and ordinates
; y, and given a desired oversampling factor ofac (a typical value
; being 4 or larger). this routine creates an array wk1 with a
; sequence of nout increasing frequencies (not angular frequencies)
; up to hifac times the "average" Nyquist frequency, and creates
; an array wk2 with the values of the Lomb normalized periodogram at
; those frequencies. The arrays x and y are not altered. This
; routine also returns jmax such that wk2(jmax) is the maximum
; element in wk2, and prob, an estimate of the significance of that
; maximum against the hypothesis of random noise. A small value of prob
; indicates that a significant periodic signal is present.
;
; CATEGORY:
; Numerical Recipes routines.
;
; CALLING SEQUENCE:
;
; FASPER, X, Y, Ofac, Hifac, Wk1, Wk2 [, Nout, Jmax, Prob]
;
; INPUTS:
; X: Abscissas array, (e.g. an array of times).
;
; Y: Ordinates array, (e.g. an array of corresponding counts).
;
; Ofac: Oversampling factor.
;
; Hifac: Hifac * "average" Nyquist frequency = highest frequency
; for which values of the Lomb normalized periodogram will
; be calculated.
;
; OUTPUTS:
; Wk1: An array of Lomb periodogram frequencies.
;
; Wk2: An array of corresponding values of the Lomb periodogram.
;
; OPTIONAL OUTPUTS:
; Nout: The dimension of Wk1 and Wk2, i.e. the number of frequencies
; calculated.
;
; Jmax: The array index corresponding to the MAX( Wk2 ).
;
; Prob: The False Alarm Probability (FAP) of the largest value of
; of Lomb normalized periodogram.
;
; MODIFICATION HISTORY:
; Written by: Han Wen, December 1994. (Adapted from a Numerical
; Recipes routine with the same name).
; 15-AUG-1996 Andrew Lee, Modified spread and fasper to use arrays
; starting at 0 instead of 1, and fixed some bugs where
; int was used instead of long.
;-
pro SPREAD, y, yy, n, x, m
;
; Given an array yy(0:n-1), extirpolate (spread) a value y into
; m actual array elements that best approximate the "fictional"
; (i.e., possible noninteger) array element number x. The weights
; used are coefficients of the Lagrange interpolating polynomial
nfac=[0,1,1,2,6,24,120,720,5040,40320,362880]
if (m gt 10) then message,'factorial table too small in spread'
ix=long(x)
if x eq float(ix) then yy(ix)=yy(ix)+y $
else begin
ilo= ( long(x-0.5*m+1.0) > 0 ) < (n-m)
ihi=ilo+m-1
nden=nfac(m)
fac=x-ilo
for j=ilo+1,ihi do fac = fac*(x-j)
yy(ihi) = yy(ihi) + y*fac/(nden*(x-ihi))
for j=ihi-1,ilo,-1 do begin
nden=(nden/(j+1-ilo))*(j-ihi)
yy(j) = yy(j) + y*fac/(nden*(x-j))
endfor
endelse
end
; (C) Copr. 1986-92 Numerical Recipes Software
pro FASPER, x, y, ofac, hifac, wk1, wk2, nout, jmax, prob
MACC = 4 ;Number of interpolation points per 1/4 cycle
;of highest frequency
; Check dimensions of input arrays
n = n_elements( x )
sz = size( y )
if n ne sz(1) then message, 'Incompatible arrays.'
nout=0.5*ofac*hifac*n
nfreqt=long(ofac*hifac*n*MACC) ;Size the FFT as next power
nfreq=64L ;of 2 above nfreqt.
while (nfreq lt nfreqt) do nfreq = ISHFT( nfreq,1 )
ndim=long(ISHFT( nfreq,1 ))
var=(stdev(y,ave))^2. ;Compute the mean, variance
;and range of the data.
xmin=MIN( x, MAX=xmax )
xdif=xmax-xmin
wk1 =complexarr(ndim) ;Extirpolate the data into
wk2 =complexarr(ndim) ;the workspaces.
fac=ndim/(xdif*ofac)
fndim=ndim
ck =(x-xmin)*fac MOD fndim
ckk =2.0*ck MOD fndim
for j=0L,n - 1 do begin
SPREAD, y(j)-ave,wk1,ndim,ck(j),MACC
SPREAD, 1.0,wk2,ndim,ckk(j),MACC
endfor
wk1 = FFT( wk1,1, /OVERWRITE ) ;Take the Fast Fourier Transforms.
wk2 = FFT( wk2,1, /OVERWRITE )
wk1 = wk1(1:nout)
wk2 = wk2(1:nout)
rwk1 = double( wk1 ) & iwk1 = imaginary( wk1 )
rwk2 = double( wk2 ) & iwk2 = imaginary( wk2 )
df=1.0/(xdif*ofac)
hypo2 = 2.0 * abs( wk2 ) ;Compute the Lomb value for each
hc2wt= rwk2/hypo2 ;frequency.
hs2wt= iwk2/hypo2
cwt = sqrt(0.5+hc2wt)
swt = SIGN(sqrt(0.5-hc2wt),hs2wt)
den = 0.5*n+hc2wt*rwk2+hs2wt*iwk2
cterm= (cwt*rwk1+swt*iwk1)^2./den
sterm= (cwt*iwk1-swt*rwk1)^2./(n-den)
wk1 = df*(findgen(nout)+1.)
wk2 = (cterm+sterm)/(2.0*var)
pmax = MAX( wk2, jmax )
expy =exp(-pmax) ;Estimate significance of largest
effm =2.0*(nout)/ofac ;peak value.
prob =effm*expy
if (prob gt 0.01) then prob=1.0-(1.0-expy)^effm
end
; (C) Copr. 1986-92 Numerical Recipes Software