Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
qmed.c
Go to the documentation of this file.00001 #include "mrilib.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #undef MED3
00013 #define MED3(a,b,c) ( (a < b) ? ( (a > c) ? a : (b > c) ? c : b ) \
00014 : ( (b > c) ? b : (a > c) ? c : a ) )
00015
00016
00017
00018 #undef SWAP
00019 #define SWAP(x,y) (temp=(x),(x)=(y),(y)=temp)
00020
00021 float qmed_float( int n , float * ar )
00022 {
00023 register int i , j ;
00024 register float temp , pivot ;
00025 register float * a = ar ;
00026
00027 int left , right , mid , nodd ;
00028
00029 switch( n ){
00030 case 1: return ar[0] ;
00031 case 2: return 0.5*(ar[0]+ar[1]) ;
00032 case 3: return MED3( ar[0] , ar[1] , ar[2] ) ;
00033 }
00034
00035 left = 0 ; right = n-1 ; mid = n/2 ; nodd = ((n & 1) != 0) ;
00036
00037
00038
00039 while( right-left > 1 ){
00040
00041 i = ( left + right ) / 2 ;
00042
00043
00044
00045 if( a[left] > a[i] ) SWAP( a[left] , a[i] ) ;
00046 if( a[left] > a[right] ) SWAP( a[left] , a[right] ) ;
00047 if( a[i] > a[right] ) SWAP( a[right] , a[i] ) ;
00048
00049 pivot = a[i] ;
00050 a[i] = a[right] ;
00051
00052 i = left ;
00053 j = right ;
00054
00055
00056
00057
00058 do{
00059 for( ; a[++i] < pivot ; ) ;
00060 for( ; a[--j] > pivot ; ) ;
00061
00062 if( j <= i ) break ;
00063
00064 SWAP( a[i] , a[j] ) ;
00065 } while( 1 ) ;
00066
00067
00068
00069 a[right] = a[i] ;
00070 a[i] = pivot ;
00071
00072 if( i == mid ){
00073 if( nodd ) return pivot ;
00074
00075 temp = a[left] ;
00076 for( j=left+1 ; j < i ; j++ )
00077 if( a[j] > temp ) temp = a[j] ;
00078
00079 return 0.5*(pivot+temp) ;
00080 }
00081
00082 if( i < mid ) left = i ;
00083 else right = i ;
00084
00085 }
00086
00087 return (nodd) ? a[mid] : 0.5*(a[mid]+a[mid-1]) ;
00088 }
00089
00090 int main( int argc , char * argv[] )
00091 {
00092 int nn,ii , med , mrep=1 , jj ;
00093 float * ar , * br ;
00094 float mm ;
00095 double ct , ctsum=0.0 ;
00096
00097 if( argc < 2 ){printf("Usage: qmed N [m]\n");exit(0);}
00098 nn = strtol(argv[1],NULL,10) ; if( nn == 0 ) exit(1);
00099
00100 if( argc == 3 ){
00101 mrep = strtol(argv[2],NULL,10) ; if( mrep < 1 ) mrep = 1 ;
00102 }
00103
00104 med = ( nn > 0 ) ; if( !med ) nn = -nn ;
00105
00106 ar = (float *) malloc( sizeof(float)*nn ) ;
00107 br = (float *) malloc( sizeof(float)*nn ) ;
00108 srand48((long)(237+jj)) ;
00109 for( ii=0 ; ii < nn ; ii++ ) br[ii] = (float)(lrand48() % nn)*0.1 ;
00110
00111 ct = COX_cpu_time() ;
00112 for( jj=0 ; jj < mrep ; jj++ ){
00113
00114 memcpy( ar , br , sizeof(float)*nn ) ;
00115
00116 if( med ){
00117 mm = qmed_float( nn , ar ) ;
00118 } else {
00119 qsort_float( nn , ar ) ;
00120 if( nn%2 == 1 ) mm = ar[nn/2] ;
00121 else mm = 0.5*(ar[nn/2]+ar[nn/2-1]) ;
00122 }
00123 }
00124 ct = COX_cpu_time() - ct ;
00125 printf("Median = %g CPU = %g\n",mm,ct) ;
00126 exit(0) ;
00127 }