⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 robust_linefit.pro

📁 basic median filter simulation
💻 PRO
字号:
FUNCTION  ROBUST_LINEFIT,XIN,YIN,YFIT,SIG,SS, NUMIT=THIS_MANY, BISECT=TYPE, $                         Bisquare_Limit=Bisquare_Limit, $                         Close_Factor=Close_Factor;+; NAME:;       ROBUST_LINEFIT;; PURPOSE:;       An outlier-resistant two-variable linear regression. ; EXPLANATION:;       Either Y on X or, for the case in which there is no true independent ;       variable, the bisecting line of Y vs X and X vs Y is calculated. No ;       knowledge of the errors of the input points is assumed.;; CALLING SEQUENCE:;       COEFF = ROBUST_LINEFIT( X, Y, YFIT, SIG, COEF_SIG, [ /BISECT,;                       BiSquare_Limit = , Close_factor = , NumIT = ] );; INPUTS:;       X = Independent variable vector, floating-point or double-precision;       Y = Dependent variable vector;; OUTPUTS:;       Function result = coefficient vector. ;       If = 0.0 (scalar), no fit was possible.;       If vector has more than 2 elements (the last=0) then the fit is dubious.;; OPTIONAL OUTPUT PARAMETERS:;       YFIT = Vector of calculated y's;       SIG  = The "standard deviation" of the fit's residuals. If BISECTOR ;               is set, this will be smaller by ~ sqrt(2).;       COEF_SIG  = The estimated standard deviations of the coefficients. If ;               BISECTOR is set, however, this becomes the vector of fit ;               residuals measured orthogonal to the line.;; OPTIONAL INPUT KEYWORDS:;       NUMIT = the number of iterations allowed. Default = 25;       BISECT  if set, the bisector of the "Y vs X" and "X vs Y" fits is ;               determined.  The distance PERPENDICULAR to this line is used ;               in calculating weights. This is better when the uncertainties ;               in X and Y are comparable, so there is no true independent ;               variable.  Bisquare_Limit  Limit used for calculation of ;               bisquare weights. In units of outlier-resistant standard ;               deviations. Default: 6.;               Smaller limit ==>more resistant, less efficient; Close_Factor  - Factor used to determine when the calculation has converged.;               Convergence if the computed standard deviation changes by less ;               than Close_Factor * ( uncertainty of the std dev of a normal;               distribution ). Default: 0.03.; SUBROUTINE CALLS:;       ROB_CHECKFIT;       ROBUST_SIGMA, to calculate a robust analog to the std. deviation;; PROCEDURE:;       For the initial estimate, the data is sorted by X and broken into 2;       groups. A line is fitted to the x and y medians of each group.;       Bisquare ("Tukey's Biweight") weights are then calculated, using the ;       a limit of 6 outlier-resistant standard deviations.;       This is done iteratively until the standard deviation changes by less ;       than CLOSE_ENOUGH = CLOSE_FACTOR * {uncertainty of the standard ;               deviation of a normal distribution};; REVISION HISTORY:;       Written, H. Freudenreich, STX, 4/91.;       4/13/93 to return more realistic SS's HF;       2/94 --more error-checking, changed convergence criterion HF;       5/94 --added BISECT option. HF.;       8/94 --added Close_Factor and Bisquare_Limit options  Jack Saba.;       4/02 --V5.0 version, use MEDIAN(/EVEN)  W. Landsman;-ON_ERROR,2IF N_ELEMENTS(THIS_MANY) GT 0 THEN ITMAX=THIS_MANY ELSE ITMAX=25IF ( NOT KEYWORD_SET ( Close_Factor   ) ) THEN Close_Factor = 0.03DEL = 5.0E-07EPS = 1.0E-20N = N_ELEMENTS(XIN); First, shift X and Y to their centers of gravity: X0 = TOTAL(XIN)/N  &  Y0=TOTAL(YIN)/N X = XIN-X0       &  Y = YIN-Y0  CC=FLTARR(2) SS=FLTARR(2) SIG=0. YFIT=YIN BADFIT=0 NGOOD=N; Make sure the independent variables are not all the same. XRANGE=MAX(X)-MIN(X) AVEX= (TOTAL(ABS(X))/N) > EPS IF (XRANGE LT EPS) OR (XRANGE/AVEX LT DEL) THEN BEGIN   message,'Independent variables the same. No fit possible.',/CON   RETURN,0.ENDIF ; First guess: LSQ=0YP=YIF N GT 5 THEN BEGIN;  We divide the data into 2 groups and fit a line to their X and Y medians.   S=SORT(X) &  U=X[S]  &  V=Y[S]   NHALF=N/2-1   X1=MEDIAN(U[0:NHALF],/EVEN) & X2=MEDIAN(U[NHALF+1:N-1],/EVEN)   Y1=MEDIAN(V[0:NHALF],/EVEN) & Y2=MEDIAN(V[NHALF+1:N-1],/EVEN)   IF ABS(X2-X1) LT EPS THEN BEGIN;     The X medians are too close. Select the end-points instead.      X1=U[0]  &  X2=U[N-1]      Y1=V[0]  &  Y2=V[N-1]   ENDIF   CC[1]=(Y2-Y1)/(X2-X1)  & CC[0]=Y1-CC[1]*X1   YFIT = CC[0]+CC[1]*X   ISTAT = ROB_CHECKFIT(YP,YFIT,EPS,DEL,  SIG,FRACDEV,NGOOD,W,S)   IF NGOOD LT 2 THEN LSQ=1ENDIF IF (LSQ EQ 1) OR (N LT 6) THEN BEGIN  ; Try a least-squares fit   SX=TOTAL(X) & SY=TOTAL(Y) & SXY=TOTAL(X*Y) & SXX=TOTAL(X*X)    D=SXX-SX*SX   IF ABS(D) LT EPS THEN BEGIN      PRINT,'ROBUST_LINEFIT: No fit possible.'      RETURN,0.   ENDIF    YSLOP=(SXY-SX*SY)/D      &   YYINT=(SXX*SY-SX*SXY)/D    IF KEYWORD_SET(TYPE) THEN BEGIN    ;     Get the X vs Y line.      SYY=TOTAL(Y*Y)      D=SYY-SY*SY      IF ABS(D) LT EPS THEN BEGIN         PRINT,'ROBUST_LINEFIT: No fit possible.'         RETURN,0.      ENDIF      TSLOP=(SXY-SY*SX)/D   &   TYINT=(SYY*SX-SY*SXY)/D ;     Now invert it to get the form Y=a+bX:      IF ABS(TSLOP) LT EPS THEN BEGIN         message,'No fit possible.',/CON         RETURN,0.      ENDIF      XSLOP = 1./TSLOP       &   XYINT=-TYINT/TSLOP;     Now calculate the equation of the bisector of the 2 lines:      IF YSLOP GT XSLOP THEN BEGIN         A1=YYINT  &  B1=YSLOP  &  R1=SQRT(1.+YSLOP^2)         A2=XYINT  &  B2=XSLOP  &  R2=SQRT(1.+XSLOP^2)      ENDIF ELSE BEGIN         A2=YYINT  &  B2=YSLOP  &  R2=SQRT(1.+YSLOP^2)         A1=XYINT  &  B1=XSLOP  &  R1=SQRT(1.+XSLOP^2)      ENDELSE      YINT = (R1*A2+R2*A1)/(R1+R2)       SLOP = (R1*B2+R2*B1)/(R1+R2);     Now find the orthogonal distance to the line. Convert to normal;     coordinates.      R = SQRT(1.+SLOP^2)  & IF YINT GT 0. THEN R=-R      U1 = SLOP/R  & U2=-1./R  &  U3=YINT/R       YP = U1*X+U2*Y+U3  ; = orthog. distance to line      YFIT = FLTARR(N)   ; to fool ROB_CHECKFIT      SS=YP   ENDIF ELSE BEGIN      SLOP=YSLOP               &   YINT=YYINT      YFIT = YINT+SLOP*X   ENDELSE   CC = [YINT,SLOP]   ISTAT = ROB_CHECKFIT(YP,YFIT,EPS,DEL,  SIG,FRACDEV,NGOOD,W,S)ENDIF IF ISTAT EQ 0 THEN GOTO,AFTERFIT IF NGOOD LT 2 THEN BEGIN   message,'Data Dangerously Weird. Fit Questionable.',/CON   BADFIT=1   GOTO,AFTERFITENDIF; Now iterate until the solution converges: SIG_1= (100.*SIG) < 1.0E20 CLOSE_ENOUGH = Close_Factor * SQRT(.5/(N-1)) > DEL DIFF= 1.0E20 NIT = 0 WHILE( (DIFF GT CLOSE_ENOUGH) AND (NIT LT ITMAX) ) DO BEGIN  NIT=NIT+1  SIG_2=SIG_1  SIG_1=SIG  SX=TOTAL(W*X) & SY=TOTAL(W*Y) & SXY=TOTAL(W*X*Y) & SXX=TOTAL(W*X*X)   D=SXX-SX*SX  IF ABS(D) LT EPS THEN BEGIN     message,'No fit possible.',/CON     RETURN,0.  ENDIF   YSLOP = (SXY-SX*SY)/D      &   YYINT = (SXX*SY-SX*SXY)/D   SLOP = YSLOP               &   YINT = YYINT  IF KEYWORD_SET(TYPE) THEN BEGIN    ;    Get the X vs Y line.     SYY=TOTAL(W*Y*Y)      D=SYY-SY*SY     IF ABS(D) LT EPS THEN BEGIN        PRINT,'ROBUST_LINEFIT: No fit possible.'        RETURN,0.     ENDIF     TSLOP=(SXY-SY*SX)/D   &   TYINT=(SYY*SX-SY*SXY)/D ;    Now invert it to get the form Y=a+bX:     IF ABS(TSLOP) LT EPS THEN BEGIN        PRINT,'ROBUST_LINEFIT: No fit possible.'        RETURN,0.     ENDIF     XSLOP=1./TSLOP       &   XYINT=-TYINT/TSLOP;    Now calculate the equation of the bisector of the 2 lines:     IF YSLOP GT XSLOP THEN BEGIN        A1=YYINT  &  B1=YSLOP  &  R1=SQRT(1.+YSLOP^2)        A2=XYINT  &  B2=XSLOP  &  R2=SQRT(1.+XSLOP^2)     ENDIF ELSE BEGIN        A2=YYINT  &  B2=YSLOP  &  R2=SQRT(1.+YSLOP^2)        A1=XYINT  &  B1=XSLOP  &  R1=SQRT(1.+XSLOP^2)     ENDELSE     YINT=(R1*A2+R2*A1)/(R1+R2)     SLOP=(R1*B2+R2*B1)/(R1+R2)     R=SQRT(1.+SLOP^2)  & IF YINT GT 0. THEN R=-R     U1=SLOP/R  & U2=-1./R  &  U3=YINT/R      YP=U1*X+U2*Y+U3  ; = orthog distance to line     YFIT=FLTARR(N) & YFIT[*]=0.     SS=YP  ENDIF ELSE BEGIN     YFIT = YINT+SLOP*X  ENDELSE  CC=[YINT,SLOP]   ISTAT=ROB_CHECKFIT(YP,YFIT,EPS,DEL,  SIG,FRACDEV,NGOOD,W,S, $                     Bisquare_Limit=Bisquare_Limit )  IF ISTAT EQ 0 THEN GOTO,AFTERFIT  IF NGOOD LT 2 THEN BEGIN     PRINT,'ROBUST_LINEFIT: Data Dangerously Weird. Fit Questionable.'     BADFIT=1     GOTO,AFTERFIT  ENDIF  DIFF = (ABS(SIG_1-SIG)/SIG) < (ABS(SIG_2-SIG)/SIG)ENDWHILEAFTERFIT:; Untranslate the coefficients CC[0] = CC[0]+Y0-CC[1]*X0IF N_PARAMS(0) GT 2 THEN YFIT = CC[0] + CC[1]*XIN IF KEYWORD_SET(BISECT) THEN RETURN,CC IF (N_PARAMS(0) GT 3) AND (SIG GT EPS) AND (NGOOD GT 2) THEN BEGIN   ; Here we use an empirical formula to approximate the standard deviations   ; of the coefficients. They are usually accurate to ~ 25%.   SX2 = TOTAL(W*X*X)    UU = S*S   DEV = YIN-YFIT   Y0 = TOTAL( W*DEV )   Q = WHERE(UU LE 1.0,COUNT)   DEN1 = ABS(TOTAL( (1.-UU[Q])*(1.-5.*UU[Q]) ))   SIG = ROBUST_SIGMA(DEV,/ZERO)   ; Now empirically derived estimates of the uncertainties:   SS[0] = SIG/SQRT(DEN1)/1.105    SS[1] = SS[0]/SQRT(SX2)   ; Take the X shift into account:   SS[0] = SQRT(SS[0]^2+X0*SS[1]^2) ENDIF IF BADFIT EQ 1 THEN CC=[CC,0.] RETURN,CC END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -