Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
SortTest.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20/*-----------------------------------------------------------------------
21 *
22 * File Name: SortTest.c
23 *
24 * Author: Creighton, T. D.
25 *
26 *
27 *-----------------------------------------------------------------------*/
28
29/**
30 * \file
31 * \ingroup Sort_h
32 *
33 * \brief A program to test sorting routines.
34 *
35 * ### Usage ###
36 *
37 * \code
38 * SortTest
39 * \endcode
40 *
41 * ### Description ###
42 *
43 * This test program creates rank and index arrays for an unordered list
44 * of numbers, and then sorts the list. The data for the list are
45 * generated randomly, and the output is to \c stdout if <tt>-v</tt> is
46 * specified (unless redirected). \c SortTest returns 0 if it executes
47 * successfully, and 1 if any of the subroutines fail.
48 *
49 * ### Exit codes ###
50 *
51 * <table><tr><th>Code</th><th>Explanation</th></tr>
52 * <tr><td>0</td><td>Success, normal exit.</td></tr>
53 * <tr><td>1</td><td>Subroutine failed.</td></tr>
54 * </table>
55 *
56 */
57
58/** \cond DONT_DOXYGEN */
59
60#include <stdlib.h>
61#include <string.h>
62#include <time.h>
63#include <lal/Sort.h>
64
65
66static void makedata( int nobj, int **data, int **sort, int **indx, int **rank )
67{
68 int i;
69
70 *data = malloc(nobj*sizeof(**data));
71 *sort = malloc(nobj*sizeof(**data));
72 *indx = malloc(nobj*sizeof(**indx));
73 *rank = malloc(nobj*sizeof(**rank));
74
75 for ( i = 0; i < nobj; ++i )
76 (*sort)[i] = (*data)[i] = rand() % 100;
77}
78
79
80static void freedata( int *data, int *sort, int *indx, int *rank)
81{
82 free( data );
83 free( sort );
84 free( indx );
85 free( rank );
86}
87
88
89static int compar( void *p, const void *a, const void *b )
90{
91 int x = *((const int *)a);
92 int y = *((const int *)b);
93 int ascend = *(int *)p;
94
95 if ( ascend )
96 {
97 if ( x < y )
98 return -1;
99 if ( x > y )
100 return 1;
101 return 0;
102 }
103
104 if ( x > y )
105 return -1;
106 if ( x < y )
107 return 1;
108 return 0;
109}
110
111
112static int lt( void *p, const void *a, const void *b )
113{
114 return compar( p, a, b ) < 0;
115}
116
117
118static int lte( void *p, const void *a, const void *b )
119{
120 return compar( p, a, b ) <= 0;
121}
122
123
124static int check( int *data, int *sort, int nobj, int ascend )
125{
126 int i, j;
127 /* make sure result is in correct order */
128 for ( i = 1; i < nobj; ++i )
129 if ( ascend )
130 {
131 if ( sort[i] < sort[i-1] ) {
132 LALPrintError( "ERROR: sort[i] < sort[i-1] at line %i\n", __LINE__ );
133 exit(1);
134 }
135 }
136 else
137 {
138 if ( sort[i] > sort[i-1] ) {
139 LALPrintError( "ERROR: sort[i] > sort[i-1] at line %i\n", __LINE__ );
140 exit(1);
141 }
142 }
143 /* make sure every element from the original data can be found somewhere
144 * in the result, and every element in the result can be found in the
145 * original data */
146 for ( i = 0; i < nobj; ++i )
147 {
148 for ( j = 0; j < nobj && sort[j] != data[i]; ++j );
149 if ( j == nobj ) {
150 LALPrintError( "ERROR: j == nobj at line %i\n", __LINE__ );
151 exit(1);
152 }
153 }
154 for ( i = 0; i < nobj; ++i )
155 {
156 for ( j = 0; j < nobj && data[j] != sort[i]; ++j );
157 if ( j == nobj ) {
158 LALPrintError( "ERROR: j == nobj at line %i\n", __LINE__ );
159 exit(1);
160 }
161 }
162 return 0;
163}
164
165
166int main(int argc, char **argv)
167{
168 int testnum;
169
170 if (argc!=1)
171 LALPrintError("%s: Incorrect arguments\n",argv[0]);
172
173 srand(time(NULL));
174
175 for ( testnum = 0; testnum < 200; testnum++ )
176 {
177 int nobj = rand() % 24;
178 int ascend = rand() & 1;
179 int *data;
180 int *sort;
181 int *indx;
182 int *rank;
183 int i;
184
185 makedata( nobj, &data, &sort, &indx, &rank );
186
187 if ( XLALHeapIndex( indx, data, nobj, sizeof(*data), &ascend, compar ) < 0 ) {
188 LALPrintError( "ERROR: XLALHeapIndex( indx, data, nobj, sizeof(*data), &ascend, compar ) < 0 at line %i\n", __LINE__ );
189 exit(1);
190 }
191 if ( XLALHeapRank( rank, data, nobj, sizeof(*data), &ascend, compar ) < 0 ) {
192 LALPrintError( "ERROR: XLALHeapRank( rank, data, nobj, sizeof(*data), &ascend, compar ) < 0 at line %i\n", __LINE__ );
193 exit(1);
194 }
195 if ( XLALHeapSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 ) {
196 LALPrintError( "ERROR: XLALHeapSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 at line %i\n", __LINE__ );
197 exit(1);
198 }
199
200 for ( i = 0; i < nobj; ++i )
201 if ( sort[i] != data[indx[i]] ) {
202 LALPrintError( "ERROR: sort[i] != data[indx[i]] at line %i\n", __LINE__ );
203 exit(1);
204 }
205
206 check( data, sort, nobj, ascend );
207
208 freedata( data, sort, indx, rank );
209 }
210 fprintf(stderr, "Passed XLALHeapSort\n");
211 fprintf(stderr, "Passed XLALHeapRank\n");
212 fprintf(stderr, "Passed XLALHeapIndex\n");
213
214 for ( testnum = 0; testnum < 200; testnum++ )
215 {
216 int nobj = rand() % 24;
217 int ascend = rand() & 1;
218 int *data;
219 int *sort;
220 int *indx; /* unused for these tests */
221 int *rank; /* unused for these tests */
222
223 makedata( nobj, &data, &sort, &indx, &rank );
224
225 if ( XLALInsertionSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 ) {
226 LALPrintError( "ERROR: XLALInsertionSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 at line %i\n", __LINE__ );
227 exit(1);
228 }
229
230 check( data, sort, nobj, ascend );
231
232 freedata( data, sort, indx, rank );
233 }
234 fprintf(stderr, "Passed XLALInsertionSort\n");
235
236 for ( testnum = 0; testnum < 200; testnum++ )
237 {
238 int nobj = rand() % 24;
239 int ascend = rand() & 1;
240 int *data;
241 int *sort;
242 int *indx; /* unused for these tests */
243 int *rank; /* unused for these tests */
244
245 makedata( nobj, &data, &sort, &indx, &rank );
246
247 if ( XLALMergeSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 ) {
248 LALPrintError( "ERROR: XLALMergeSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 at line %i\n", __LINE__ );
249 exit(1);
250 }
251
252 check( data, sort, nobj, ascend );
253
254 freedata( data, sort, indx, rank );
255 }
256 fprintf(stderr, "Passed XLALMergeSort\n");
257
258 for ( testnum = 0; testnum < 200; testnum++ )
259 {
260 int nobj = rand() % 24 + 1; /* these tests require at least one element */
261 int ascend = rand() & 1;
262 int *data;
263 int *sort;
264 int *indx; /* unused for these tests */
265 int *rank; /* unused for these tests */
266
267 makedata( nobj, &data, &sort, &indx, &rank );
268
269 if ( XLALMergeSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 ) {
270 LALPrintError( "ERROR: XLALMergeSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 at line %i\n", __LINE__ );
271 exit(1);
272 }
273
274 if ( !XLALIsSorted( sort, nobj, sizeof(*data), &ascend, compar ) ) {
275 LALPrintError( "ERROR: !XLALIsSorted( sort, nobj, sizeof(*data), &ascend, compar ) at line %i\n", __LINE__ );
276 exit(1);
277 }
278
279 freedata( data, sort, indx, rank );
280 }
281 fprintf(stderr, "Passed XLALIsSorted\n");
282
283 for ( testnum = 0; testnum < 200; testnum++ )
284 {
285 int nobj = rand() % 24;
286 int ascend = rand() & 1;
287 int *data;
288 int *sort;
289 int *indx; /* unused for these tests */
290 int *rank; /* unused for these tests */
291 int v;
292 int i;
293
294 makedata( nobj, &data, &sort, &indx, &rank );
295
296 if ( XLALMergeSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 ) {
297 LALPrintError( "ERROR: XLALMergeSort( sort, nobj, sizeof(*data), &ascend, compar ) < 0 at line %i\n", __LINE__ );
298 exit(1);
299 }
300
301 v = rand() % 100;
302 i = XLALSearchSorted( &v, sort, nobj, sizeof(*data), &ascend, compar, -1 );
303 if ( i < 0 || i > nobj ) {
304 LALPrintError( "ERROR: i=%d, nobj=%d, i < 0 || i > nobj at line %i\n", i, nobj, __LINE__ );
305 exit(1);
306 } else if ( nobj == 0 ) {
307 if ( i != 0 ) {
308 LALPrintError( "ERROR: i != 0 at line %i\n", __LINE__ );
309 exit(1);
310 }
311 } else if ( i == 0 ) {
312 // if ( !( v <= sort[i] ) )
313 if ( !( lte( &ascend, &v, &sort[i] ) ) ) {
314 LALPrintError( "ERROR: !( lte( &ascend, &v, &sort[i] ) ) at line %i\n", __LINE__ );
315 exit(1);
316 }
317 } else if ( i == nobj ) {
318 // if ( !( sort[i-1] < v) )
319 if ( !( lt( &ascend, &sort[i-1], &v ) ) ) {
320 LALPrintError( "ERROR: !( lt( &ascend, &sort[i-1], &v ) ) at line %i\n", __LINE__ );
321 exit(1);
322 }
323 // } else if ( !(sort[i-1] < v && v <= sort[i]) )
324 } else if ( !( lt( &ascend, &sort[i-1], &v ) && lte( &ascend, &v , &sort[i] ) ) ) {
325 LALPrintError( "ERROR: !( lt( &ascend, &sort[i-1], &v ) && lte( &ascend, &v , &sort[i] ) ) at line %i\n", __LINE__ );
326 exit(1);
327 }
328
329 v = rand() % 100;
330 i = XLALSearchSorted( &v, sort, nobj, sizeof(*data), &ascend, compar, +1 );
331 if ( i < 0 || i > nobj ) {
332 LALPrintError( "ERROR: i < 0 || i > nobj at line %i\n", __LINE__ );
333 exit(1);
334 }
335 else if ( nobj == 0 ) {
336 if ( i != 0 ) {
337 LALPrintError( "ERROR: i != 0 at line %i\n", __LINE__ );
338 exit(1);
339 }
340 } else if ( i == 0 ) {
341 // if ( !( v <= sort[i] ) )
342 if ( !( lte( &ascend, &v, &sort[i] ) ) ) {
343 LALPrintError( "ERROR: !( lte( &ascend, &v, &sort[i] ) ) at line %i\n", __LINE__ );
344 exit(1);
345 }
346 } else if ( i == nobj ) {
347 // if ( ! (sort[i-1] <= v) )
348 if ( ! ( lte( &ascend, &sort[i-1], &v ) ) ) {
349 LALPrintError( "ERROR: ! ( lte( &ascend, &sort[i-1], &v ) ) at line %i\n", __LINE__ );
350 exit(1);
351 }
352 // } else if ( !(sort[i-1] <= v && v < sort[i]) )
353 } else if ( !( lte( &ascend, &sort[i-1], &v ) && lt( &ascend, &v, &sort[i] ) ) ) {
354 LALPrintError( "ERROR: !( lte( &ascend, &sort[i-1], &v ) && lt( &ascend, &v, &sort[i] ) ) at line %i\n", __LINE__ );
355 exit(1);
356 }
357
358 if ( nobj > 0 ) {
359 /* select one of the data points */
360 int j = rand() % nobj;
361 v = data[j];
362 } else {
363 v = rand() % 100;
364 }
365 i = XLALSearchSorted( &v, sort, nobj, sizeof(*data), &ascend, compar, 0 );
366 if ( nobj == 0 ) {
367 if ( i != -1 ) {
368 LALPrintError( "ERROR: i != -1 at line %i\n", __LINE__ );
369 exit(1);
370 }
371 } else if ( i < 0 ) {
372 LALPrintError( "ERROR: i < 0 at line %i\n", __LINE__ );
373 exit(1);
374 } else if ( sort[i] != v ) {
375 LALPrintError( "ERROR: sort[i] != v at line %i\n", __LINE__ );
376 exit(1);
377 }
378
379 freedata( data, sort, indx, rank );
380 }
381 fprintf(stderr, "Passed XLALSearchSorted\n");
382
383 return 0;
384}
385
386/** \endcond */
static _LAL_INLINE_ int lt(void *params, const void *a, const void *b, int(*compar)(void *, const void *, const void *))
Definition: SearchSorted.c:7
static _LAL_INLINE_ int lte(void *params, const void *a, const void *b, int(*compar)(void *, const void *, const void *))
Definition: SearchSorted.c:12
#define fprintf
int main(int argc, char *argv[])
Definition: cache.c:25
int LALPrintError(const char *fmt,...)
Definition: LALError.c:46
static const INT4 a
Definition: Random.c:79
int XLALHeapSort(void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
Definition: HeapSort.c:44
int XLALMergeSort(void *base, size_t nobj, size_t size, void *params, int(*compar)(void *, const void *, const void *))
Definition: MergeSort.c:36
int XLALIsSorted(void *base, size_t nobj, size_t size, void *params, int(*compar)(void *, const void *, const void *))
Definition: SearchSorted.c:17
int XLALHeapRank(INT4 *rank, void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
Definition: HeapSort.c:152
ssize_t XLALSearchSorted(const void *key, const void *base, size_t nobj, size_t size, void *params, int(*compar)(void *, const void *, const void *), int side)
Definition: SearchSorted.c:31
int XLALInsertionSort(void *base, size_t nobj, size_t size, void *params, int(*compar)(void *, const void *, const void *))
Definition: InsertionSort.c:37
int XLALHeapIndex(INT4 *indx, void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
Definition: HeapSort.c:98