Viewing contents of file '../idllib/astron/contrib/freudenreich/biweight_mean.pro'
FUNCTION  BIWEIGHT_MEAN,Y,SIGMA, WEIGHTs
;
;+
; NAME:
;	BIWEIGHT_MEAN 
;
; PURPOSE:
;	Calculate the center and dispersion (like mean and sigma) of a 
;	distribution using bisquare weighting.
;
; CALLING SEQUENCE:
;	Mean = BIWEIGHT_MEAN( Vector, [ Sigma, Weights ] ) 
;
; INPUTS:
;	Vector = Distribution in vector form
;
; OUTPUT:
;	Mean - The location of the center.
;
; OPTIONAL OUTPUT ARGUMENTS:
;
;	Sigma = An outlier-resistant measure of the dispersion about the 
;	center, analogous to the standard deviation. The half-width of the 95%
;	confidence interval = |STUDENT_T( .95, .7*(N-1) )*SIGMA/SQRT(N)|,
;	where N = number of points.  
;
;	Weights = The weights applied to the data in the last iteration.
;
;SUBROUTINE CALLS:
;	MED, which calculates a median
;
; REVISION HISTORY
;	Written,  H. Freudenreich, STX, 12/89
;	Modified 2/94, H.T.F.: use a biweighted standard deviation rather than
;		median absolute deviation.
;	Modified 2/94, H.T.F.: use the fractional change in SIGMA as the 
;		convergence criterion rather than the change in center/SIGMA.
;-

  ON_ERROR,2
  maxit = 20 ; Allow 20 iterations
  eps = 1.0e-24

  n = n_elements(y)
  close_enough =.03*sqrt(.5/(n-1)) ; compare to fractional change in width

  diff = 1.0e30
  itnum = 0

; As an initial estimate of the center, use the median:
  y0=med(y)

; Calculate the weights:
  dev = y-y0
  sigma = robust_sigma( dev ) 

  if sigma lt EPS then begin
;    The median is IT. Do we need the weights?
     if n_elements(weights) gt 0 then begin
;       Flag any value away from the median:
        limit=3.*sigma
        q=where( abs(dev) gt limit, count )
        weights=fltarr(n)
        weights(*)=1.
        if count gt 0 then weights(q)=0. 
     endif
     diff = 0. ; (skip rest of routine)
  endif

; Repeat:
  while( (diff gt close_enough) and (itnum lt maxit) )do begin
    itnum = itnum + 1
    uu = ( (y-y0)/(6.*sigma) )^2
    q=where(uu gt 1.,count) & if count gt 0 then uu(q)=1.
    weights=(1.-uu)^2       & weights=weights/total(weights)
    y0 = total( weights*y ) 
    dev = y-y0
    prev_sigma = sigma      & sigma = robust_sigma( dev,/zero )
    if sigma gt eps then diff=abs(prev_sigma-sigma)/prev_sigma else diff=0.
  endwhile

return,y0
end