Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
cs_qmed.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "mrilib.h"
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 static float median_float4(float,float,float,float) ;
00017 static float median_float5(float *) ;  
00018 static float median_float7(float *) ;
00019 static float median_float9(float *) ;
00020 
00021 
00022 
00023 #undef  MED3
00024 #define MED3(a,b,c) ( (a < b) ? ( (a > c) ? a : (b > c) ? c : b )  \
00025                               : ( (b > c) ? b : (a > c) ? c : a ) )
00026 
00027 
00028 
00029 #undef  SWAP
00030 #define SWAP(x,y) (temp=x,x=y,y=temp)
00031 
00032 float qmed_float( int n , float * ar )
00033 {
00034    register int i , j ;           
00035    register float temp , pivot ;  
00036    register float * a = ar ;
00037 
00038    int left , right , mid , nodd ;
00039 
00040    switch( n ){
00041       case 1: return ar[0] ;
00042       case 2: return 0.5*(ar[0]+ar[1]) ;
00043       case 3: return MED3( ar[0] , ar[1] , ar[2] ) ;
00044       case 4: return median_float4( ar[0],ar[1],ar[2],ar[3] ) ;
00045       case 5: return median_float5( ar ) ;
00046       case 7: return median_float7( ar ) ;
00047       case 9: return median_float9( ar ) ;
00048    }
00049 
00050    left = 0 ; right = n-1 ; mid = n/2 ; nodd = ((n & 1) != 0) ;
00051 
00052    
00053 
00054    while( right-left > 1  ){  
00055 
00056       i = ( left + right ) / 2 ;   
00057 
00058       
00059 
00060       if( a[left] > a[i]     ) SWAP( a[left]  , a[i]     ) ;
00061       if( a[left] > a[right] ) SWAP( a[left]  , a[right] ) ;
00062       if( a[i] > a[right]    ) SWAP( a[right] , a[i]     ) ;
00063 
00064       pivot = a[i] ;                 
00065       a[i]  = a[right] ;
00066 
00067       i = left ;                     
00068       j = right ;
00069 
00070       
00071 
00072 
00073       do{
00074         for( ; a[++i] < pivot ; ) ;  
00075         for( ; a[--j] > pivot ; ) ;  
00076 
00077         if( j <= i ) break ;         
00078 
00079         SWAP( a[i] , a[j] ) ;
00080       } while( 1 ) ;
00081 
00082       
00083 
00084       a[right] = a[i] ;           
00085       a[i]     = pivot ;
00086 
00087       if( i == mid ){             
00088          if( nodd ) return pivot ;   
00089 
00090          temp = a[left] ;            
00091          for( j=left+1 ; j < i ; j++ )
00092             if( a[j] > temp ) temp = a[j] ;
00093 
00094          return 0.5*(pivot+temp) ;   
00095       }
00096 
00097       if( i <  mid ) left  = i ; 
00098       else           right = i ; 
00099 
00100    }  
00101 
00102    return (nodd) ? a[mid] : 0.5*(a[mid]+a[mid-1]) ;
00103 }
00104 
00105 
00106 
00107 
00108 
00109 void qmedmad_float( int n, float *ar, float *med, float *mad )
00110 {
00111    float * q = (float *) malloc(sizeof(float)*n) ;
00112    float me,ma ;
00113    register int ii ;
00114 
00115    memcpy(q,ar,sizeof(float)*n) ;  
00116    me = qmed_float( n , q ) ;      
00117 
00118    for( ii=0 ; ii < n ; ii++ )     
00119       q[ii] = fabs(q[ii]-me) ;     
00120 
00121    ma = qmed_float( n , q ) ;      
00122 
00123    free(q) ;                       
00124 
00125    *med = me ; *mad = ma ; return ;
00126 }
00127 
00128 
00129 
00130 static float median_float4(float a, float b, float c, float d)
00131 {
00132   register float t1,t2,t3;
00133 
00134   if (a > b){t1 = a; a = b;} else t1 = b;  
00135   if (c > d){t2 = d; d = c;} else t2 = c;  
00136 
00137   
00138 
00139   t3 = (a > t2) ? a : t2 ;
00140   t2 = (d < t1) ? d : t1 ;
00141 
00142   return 0.5*(t2+t3) ;
00143 }
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 #undef  SORT2
00172 #define SORT2(a,b) if(a>b) SWAP(a,b);
00173 
00174 static float median_float5(float *p)
00175 {
00176     register float temp ;
00177     SORT2(p[0],p[1]) ; SORT2(p[3],p[4]) ; SORT2(p[0],p[3]) ;
00178     SORT2(p[1],p[4]) ; SORT2(p[1],p[2]) ; SORT2(p[2],p[3]) ;
00179     SORT2(p[1],p[2]) ; return(p[2]) ;
00180 }
00181 
00182 static float median_float7(float *p)
00183 {
00184     register float temp ;
00185     SORT2(p[0],p[1]) ; SORT2(p[4],p[5]) ; SORT2(p[1],p[2]) ;
00186     SORT2(p[5],p[6]) ; SORT2(p[0],p[1]) ; SORT2(p[4],p[5]) ;
00187     SORT2(p[0],p[4]) ; SORT2(p[2],p[6]) ; SORT2(p[1],p[3]) ;
00188     SORT2(p[3],p[5]) ; SORT2(p[1],p[3]) ; SORT2(p[2],p[3]) ;
00189     SORT2(p[3],p[4]) ; SORT2(p[2],p[3]) ; return(p[3]) ;
00190 }
00191 
00192 static float median_float9(float *p)
00193 {
00194     register float temp ;
00195     SORT2(p[1],p[2]) ; SORT2(p[4],p[5]) ; SORT2(p[7],p[8]) ;
00196     SORT2(p[0],p[1]) ; SORT2(p[3],p[4]) ; SORT2(p[6],p[7]) ;
00197     SORT2(p[1],p[2]) ; SORT2(p[4],p[5]) ; SORT2(p[7],p[8]) ;
00198     SORT2(p[0],p[3]) ; SORT2(p[5],p[8]) ; SORT2(p[4],p[7]) ;
00199     SORT2(p[3],p[6]) ; SORT2(p[1],p[4]) ; SORT2(p[2],p[5]) ;
00200     SORT2(p[4],p[7]) ; SORT2(p[4],p[2]) ; SORT2(p[6],p[4]) ;
00201     SORT2(p[4],p[2]) ; return(p[4]) ;
00202 }