Viewing contents of file '../idllib/contrib/meron/seqlim.pro'
Function Seqlim, svl, rvl, zero_pad = zpd, error = erv, status = stat

;+
; NAME:
;	SEQLIM
; VERSION:
;	3.0
; PURPOSE:
;	Estimates limits of infinite sequences.
; CATEGORY:
;	Mathematical Function (General).
; CALLING SEQUENCE:
;	Result = SEQLIM( SVL [, RVL ] [, keywords])
; INPUTS:
;    SVL
;	Numeric vector containing consecutive terms of the sequence.  At least
;	two terms are needed.
; OPTIONAL INPUT PARAMETERS:
;    RVL
;	Numeric vector, same length as SVL.  Contains estimates of the 
;	deviations of the terms of SVL from the limit.  Usually RVL is 
;	generated internally, since if good estimates of the deviations from 
;	the limit do exist, SEQLIM is not needed.
; KEYWORD PARAMETERS:
;    /ZERO_PAD
;	Switch.  Used only when RVL is not provided, specifies how a difference
;	series is generated from the terms of SVL.  When ZERO_PAD is set, it
;	implies a zero term preceding the first term of SVL, i.e. SVL has the
;	form of [0, SVL(0), SVL(1),...], giving rise to a difference series of 
;	the form [SVL(0), SVL(1) - SVL(0), ...].  If ZERO_PAD is not set, the
;	difference series is [SVL(1) - SVL(0), ...].  Therefore, at least four
;	sequence values are needed in the absence of ZERO_PAD but only 3 when
;	ZERO_PAD is set.
;    ERROR
;	Optional output, see below.
;    STATUS
;	Ditto.
; OUTPUTS:
;	Returns the limit estimate if one is found, otherwise returns machine
;	maximum.
; OPTIONAL OUTPUT PARAMETERS:
;    ERROR
;	The name of the variable to receive the estimated error of the returned
;	limit value.  If the sequence doesn't seem to converge, returns machine
;	maximum.
;    STATUS
;	The name of the variable to receive convergence status information.
;	Returns 1 if the sequence converges, 0 otherwise.
; COMMON BLOCKS:
;	None.
; SIDE EFFECTS:
;	None.
; RESTRICTIONS:
;	None.
; PROCEDURE:
;	Uses Neville's interpolation algorithm.  Calls CAST, ISNUM and 
;	SERIES_SUM from MIDL.
; MODIFICATION HISTORY:
;	Created 15-JUN-1992 by Mati Meron.
;	Completely rewritten 30-SEP-1998 by Mati Meron.
;-

    on_error, 1
    sinf = machar(double=Isnum(svl,/double,typ=styp))
    if styp eq 6 then wtyp = 9 else wtyp = 5
    erv = sinf.xmax
    lim = erv
    stat = 0

    kl = n_elements(svl) - 1
    rl = n_elements(rvl) - 1

    if rl ge 0 then begin
	if rl eq kl then begin
	    ws = Cast(svl,wtyp)
	    wr = Cast(rvl,wtyp)
	    if kl ge 1 then begin
		kf = (where([1,abs(wr(1:rl))- abs(wr(0:rl-1))] ge 0,nd))(nd-1)
		if kf lt kl then begin
		    q = ws
		    lim = q(kl)
		    l = kl
		    while l gt kf do begin
			l = l - 1
			for k = l+1, kl do q(k) = $
			    (wr(l)*q(k) - wr(k)*q(k-1))/(wr(l) - wr(k))
			nerv = abs(q(kl) - lim)
			if nerv le erv then begin
			    lim = q(kl)
			    erv = nerv
			endif else kf = kl
		    endwhile
		    stat = 1
		endif
	    endif else begin
		lim = ws(0)
		stat = 3
	    endelse
	endif else message, 'incompatible data lengths'
    endif else begin
	zpfl = keyword_set(zpd)
	if kl ge (3 - zpfl) then begin
	    if zpfl then lim = Series_sum(svl-[0,svl], err= terv, stat= stat) $
	    else lim = svl(0) + Series_sum(svl(1:*)-svl, err= terv, stat= stat)
	    erv = erv < terv
	endif else begin
	    if kl ge 1 and max(svl, min = mis) eq mis then begin
		lim = svl(0)
		stat = 3
	    endif else message, 'insufficient data!', /continue
	endelse
    endelse

    erv = Cast(erv,4,styp,/fix)
    return, Cast(lim,4,styp,/fix)
end