#include "medians_1D.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include <float.h>
Include dependency graph for demo.c:

Go to the source code of this file.
Defines | |
| #define | BIG_NUM (1024*1024) |
| Number of elements in the target array. | |
| #define | MAX_ARRAY_VALUE 1024 |
| Random test data; generated values are in [0...MAX_ARRAY_VALUE-1]. | |
| #define | N_METHODS 5 |
| Number of search methods tested. | |
| #define | odd(x) ((x)&1) |
| Macro to determine an integer's oddness. | |
| #define | PIX_SWAP(a, b) { pixelvalue temp=(a);(a)=(b);(b)=temp; } |
| #define | PIX_STACK_SIZE 50 |
Functions | |
| void | bench (int, size_t) |
| int | compare (const void *f1, const void *f2) |
| This function is only useful to the qsort() routine. | |
| void | pixel_qsort (pixelvalue *, int) |
| Old and supposedly optimized quicksort algorithm. | |
| pixelvalue | median_AHU (pixelvalue *list, int n) |
| This function uses select_k to find the median. | |
| pixelvalue | select_k (int, pixelvalue *, int) |
| Called by median_AHU(). | |
| int | main (int argc, char *argv[]) |
| Main driver demo for median search routines. | |
Variables | |
| static const char | rcsid [] |
Comparison of qsort-based and optimized median search methods for a 1-D data array. The data type is flexible.
Original code by Nicolas Devillard <ndevilla@free.fr> August 1998. Modified by Stephen Arnold <stephen.arnold@acm.org> August 2005. This code in public domain.
A note about this benchmarking method:
The reported times indicate the actual time spent on CPU, they are quite dependent on CPU load. However, the test is quite fast and it is reasonable to assume a constant machine load throughout the test.
Definition in file demo.c.
| #define BIG_NUM (1024*1024) |
| #define MAX_ARRAY_VALUE 1024 |
| #define N_METHODS 5 |
| #define odd | ( | x | ) | ((x)&1) |
Macro to determine an integer's oddness.
Definition at line 41 of file demo.c.
Referenced by bench(), and median_AHU().
| #define PIX_STACK_SIZE 50 |
| #define PIX_SWAP | ( | a, | |||
| b | ) | { pixelvalue temp=(a);(a)=(b);(b)=temp; } |
| void bench | ( | int | , | |
| size_t | ||||
| ) |
Definition at line 50 of file demo.c.
References BIG_NUM, MAX_ARRAY_VALUE, median_AHU(), N_METHODS, odd, pixel_qsort(), quick_select(), torben(), and wirth().
Referenced by main().
00051 { 00052 int i ; 00053 int mednum ; 00054 pixelvalue med[N_METHODS] ; 00055 00056 clock_t chrono ; 00057 double elapsed ; 00058 00059 pixelvalue * array_init, 00060 * array ; 00061 00063 00067 srand48(getpid()) ; 00068 00069 if (verbose) { 00070 printf("generating element values...\n") ; 00071 fflush(stdout) ; 00072 } 00073 if (array_size<1) array_size = BIG_NUM ; 00074 00075 if (verbose) { 00076 printf("array size: %ld\n", (long)array_size) ; 00077 } else { 00078 printf("%ld\t", (long)array_size) ; 00079 } 00080 00081 array_init = malloc(array_size * sizeof(pixelvalue)) ; 00082 array = malloc(array_size * sizeof(pixelvalue)) ; 00083 00084 if (array_init==NULL || array==NULL) { 00085 printf("memory allocation failure: aborting\n") ; 00086 return ; 00087 } 00088 00089 for (i=0 ; i<array_size; i++) { 00090 array_init[i] = (pixelvalue)(lrand48() % MAX_ARRAY_VALUE) ; 00091 } 00092 mednum = 0 ; 00093 00095 memcpy(array, array_init, array_size * sizeof(pixelvalue)) ; 00096 if (verbose) { 00097 printf("quick select :\t") ; 00098 fflush(stdout) ; 00099 } 00100 chrono = clock() ; 00101 med[mednum] = quick_select(array, array_size) ; 00102 elapsed = (double)(clock() - chrono) / (double)CLOCKS_PER_SEC ; 00103 if (verbose) { 00104 printf("%5.3f sec\t", elapsed) ; 00105 fflush(stdout) ; 00106 printf("med %g\n", (double)med[mednum]) ; 00107 fflush(stdout) ; 00108 } else { 00109 printf("%5.3f\t", elapsed) ; 00110 fflush(stdout) ; 00111 } 00112 mednum++ ; 00113 00115 memcpy(array, array_init, array_size * sizeof(pixelvalue)) ; 00116 if (verbose) { 00117 printf("Wirth median :\t") ; 00118 fflush(stdout) ; 00119 } 00120 chrono = clock() ; 00121 med[mednum] = wirth(array, array_size) ; 00122 elapsed = (double)(clock() - chrono) / (double)CLOCKS_PER_SEC ; 00123 if (verbose) { 00124 printf("%5.3f sec\t", elapsed) ; 00125 fflush(stdout) ; 00126 printf("med %g\n", (double)med[mednum]) ; 00127 fflush(stdout) ; 00128 } else { 00129 printf("%5.3f\t", elapsed) ; 00130 fflush(stdout) ; 00131 } 00132 mednum++ ; 00133 00135 memcpy(array, array_init, array_size * sizeof(pixelvalue)) ; 00136 if (verbose) { 00137 printf("AHU median :\t") ; 00138 fflush(stdout) ; 00139 } 00140 chrono = clock() ; 00141 med[mednum] = median_AHU(array, array_size) ; 00142 elapsed = (double)(clock() - chrono) / (double)CLOCKS_PER_SEC ; 00143 if (verbose) { 00144 printf("%5.3f sec\t", elapsed) ; 00145 fflush(stdout) ; 00146 printf("med %g\n", (double)med[mednum]) ; 00147 fflush(stdout) ; 00148 } else { 00149 printf("%5.3f\t", elapsed) ; 00150 fflush(stdout) ; 00151 } 00152 mednum++ ; 00153 00155 memcpy(array, array_init, array_size * sizeof(pixelvalue)) ; 00156 if (verbose) { 00157 printf("torben :\t") ; 00158 fflush(stdout) ; 00159 } 00160 chrono = clock() ; 00161 med[mednum] = torben(array, array_size) ; 00162 elapsed = (double)(clock() - chrono) / (double)CLOCKS_PER_SEC ; 00163 if (verbose) { 00164 printf("%5.3f sec\t", elapsed) ; 00165 fflush(stdout) ; 00166 printf("med %g\n", (double)med[mednum]) ; 00167 fflush(stdout) ; 00168 } else { 00169 printf("%5.3f\t", elapsed) ; 00170 fflush(stdout) ; 00171 } 00172 mednum++ ; 00173 00175 memcpy(array, array_init, array_size * sizeof(pixelvalue)) ; 00176 if (verbose) { 00177 printf("fast pixel sort :\t") ; 00178 fflush(stdout) ; 00179 } 00180 chrono = clock() ; 00181 pixel_qsort(array, array_size) ; 00182 elapsed = (double)(clock() - chrono) / (double)CLOCKS_PER_SEC ; 00183 00184 if (odd(array_size)) { 00185 med[mednum] = array[array_size/2] ; 00186 } else { 00187 med[mednum] = array[(array_size/2) -1] ; 00188 } 00189 00190 if (verbose) { 00191 printf("%5.3f sec\t", elapsed) ; 00192 fflush(stdout) ; 00193 printf("med %g\n", (double)med[mednum]) ; 00194 fflush(stdout) ; 00195 } else { 00196 printf("%5.3f\t", elapsed) ; 00197 fflush(stdout) ; 00198 } 00199 mednum++ ; 00200 00201 free(array) ; 00202 free(array_init) ; 00203 00204 for (i=1 ; i<N_METHODS ; i++) { 00205 if (fabs(med[i-1] - med[i]) > 10 * FLT_EPSILON) { 00206 printf("diverging median values!\n") ; 00207 fflush(stdout) ; 00208 } 00209 } 00210 printf("\n") ; 00211 fflush(stdout) ; 00212 return ; 00213 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int compare | ( | const void * | , | |
| const void * | ||||
| ) |
This function is only useful to the qsort() routine.
Definition at line 216 of file demo.c.
00217 { return ( *(pixelvalue*)f1 > *(pixelvalue*)f2) ? 1 : -1 ; }
| int main | ( | int | argc, | |
| char * | argv[] | |||
| ) |
Main driver demo for median search routines.
Definition at line 370 of file demo.c.
References bench(), and BIG_NUM.
00371 { 00372 int i ; 00373 int from, to, step ; 00374 int count ; 00375 00376 if (argc<2) { 00377 printf("usage:\n") ; 00378 printf("%s <n>\n", argv[0]) ; 00379 printf("\tif n=1 the output is verbose for one attempt\n") ; 00380 printf("\tif n>1 the output reads:\n") ; 00381 printf("\t# of elements | method1 | method2 | ...\n") ; 00382 printf("\n") ; 00383 printf("%s <from> <to> <step>\n", argv[0]) ; 00384 printf("\twill loop over the number of elements in input\n") ; 00385 printf("\n") ; 00386 return 0 ; 00387 } 00388 00389 if (argc==2) { 00390 count = atoi(argv[1]) ; 00391 if (count==1) { 00392 bench(1, BIG_NUM) ; 00393 } else { 00394 printf("Size\tQS\tWirth\tAHU\tTorben\tpixel sort\n") ; 00395 for (i=0 ; i<atoi(argv[1]) ; i++) { 00396 bench(0, BIG_NUM) ; 00397 } 00398 } 00399 } else if (argc==4) { 00400 from = atoi(argv[1]) ; 00401 to = atoi(argv[2]) ; 00402 step = atoi(argv[3]) ; 00403 for (count=from ; count<=to ; count+=step) { 00404 bench(0, count) ; 00405 } 00406 return 0 ; 00407 } 00408 00409 }
Here is the call graph for this function:

| pixelvalue median_AHU | ( | pixelvalue * | , | |
| int | ||||
| ) |
This function uses select_k to find the median.
Definition at line 359 of file demo.c.
References odd, and select_k().
Referenced by bench().
00360 { 00361 if (odd(n)) { 00362 return select_k((n/2)+1, list, n) ; 00363 } else { 00364 return select_k((n/2), list, n) ; 00365 } 00366 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void pixel_qsort | ( | pixelvalue * | pix_arr, | |
| int | npix | |||
| ) |
Old and supposedly optimized quicksort algorithm.
Function : pixel_qsort()
Definition at line 233 of file demo.c.
References PIX_STACK_SIZE, and PIX_SWAP.
Referenced by bench().
00234 { 00235 int i, 00236 ir, 00237 j, 00238 k, 00239 l; 00240 int * i_stack ; 00241 int j_stack ; 00242 pixelvalue a ; 00243 00244 ir = npix ; 00245 l = 1 ; 00246 j_stack = 0 ; 00247 i_stack = malloc(PIX_STACK_SIZE * sizeof(pixelvalue)) ; 00248 for (;;) { 00249 if (ir-l < 7) { 00250 for (j=l+1 ; j<=ir ; j++) { 00251 a = pix_arr[j-1]; 00252 for (i=j-1 ; i>=1 ; i--) { 00253 if (pix_arr[i-1] <= a) break; 00254 pix_arr[i] = pix_arr[i-1]; 00255 } 00256 pix_arr[i] = a; 00257 } 00258 if (j_stack == 0) break; 00259 ir = i_stack[j_stack-- -1]; 00260 l = i_stack[j_stack-- -1]; 00261 } else { 00262 k = (l+ir) >> 1; 00263 PIX_SWAP(pix_arr[k-1], pix_arr[l]) 00264 if (pix_arr[l] > pix_arr[ir-1]) { 00265 PIX_SWAP(pix_arr[l], pix_arr[ir-1]) 00266 } 00267 if (pix_arr[l-1] > pix_arr[ir-1]) { 00268 PIX_SWAP(pix_arr[l-1], pix_arr[ir-1]) 00269 } 00270 if (pix_arr[l] > pix_arr[l-1]) { 00271 PIX_SWAP(pix_arr[l], pix_arr[l-1]) 00272 } 00273 i = l+1; 00274 j = ir; 00275 a = pix_arr[l-1]; 00276 for (;;) { 00277 do i++; while (pix_arr[i-1] < a); 00278 do j--; while (pix_arr[j-1] > a); 00279 if (j < i) break; 00280 PIX_SWAP(pix_arr[i-1], pix_arr[j-1]); 00281 } 00282 pix_arr[l-1] = pix_arr[j-1]; 00283 pix_arr[j-1] = a; 00284 j_stack += 2; 00285 if (j_stack > PIX_STACK_SIZE) { 00286 printf("stack too small in pixel_qsort: aborting"); 00287 exit(-2001) ; 00288 } 00289 if (ir-i+1 >= j-l) { 00290 i_stack[j_stack-1] = ir; 00291 i_stack[j_stack-2] = i; 00292 ir = j-1; 00293 } else { 00294 i_stack[j_stack-1] = j-1; 00295 i_stack[j_stack-2] = l; 00296 l = i; 00297 } 00298 } 00299 } 00300 free(i_stack) ; 00301 }
Here is the caller graph for this function:

| pixelvalue select_k | ( | int | k, | |
| pixelvalue * | list, | |||
| int | n | |||
| ) |
Called by median_AHU().
Function : select_k()
Definition at line 315 of file demo.c.
Referenced by median_AHU().
00316 { 00317 int n1 = 0, 00318 n2 = 0, 00319 n3 = 0 ; 00320 pixelvalue * S ; 00321 int i, j ; 00322 pixelvalue p ; 00323 00324 if (n==1) return list[0] ; 00325 p = list[(n>>1)] ; 00326 for (i=0 ; i<n ; i++) { 00327 if (list[i]<p) { 00328 n1++ ; 00329 } else if (fabs(list[i] - p) < 10 * FLT_EPSILON) { 00330 n2++ ; 00331 } else { 00332 n3++ ; 00333 } 00334 } 00335 if (n1>=k) { 00336 S = malloc(n1*sizeof(pixelvalue)) ; 00337 j = 0 ; 00338 for (i=0 ; i<n ; i++) { 00339 if (list[i]<p) S[j++] = list[i] ; 00340 } 00341 p = select_k(k, S, n1) ; 00342 free(S) ; 00343 } else { 00344 if ((n1+n2)<k) { 00345 S = malloc(n3 * sizeof(pixelvalue)) ; 00346 j = 0 ; 00347 for (i=0 ; i<n ; i++) { 00348 if (list[i]>p) S[j++] = list[i] ; 00349 } 00350 p = select_k(k-n1-n2, S, n3) ; 00351 free(S) ; 00352 } 00353 } 00354 return p ; 00355 }
Here is the caller graph for this function:

1.5.1