CR2RE Pipeline Reference Manual 1.6.10
hdrl_cat_utils_sort.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2017 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <string.h>
21
22#include "hdrl_cat_utils_sort.h"
23
24#include "hdrl_types.h"
25
26
27/*** Datatypes ***/
28
29typedef struct {
30 double data;
31 int index;
32} sort_index;
33
34
35/*** Prototypes ***/
36
37static int cmp_index_asc( const void *a, const void *b);
38static int cmp_int_asc( const void *a, const void *b);
39static int cmp_double_asc( const void *a, const void *b);
40static int cmp_cpl_size_asc( const void *a, const void *b);
41static int cmp_hdrl_value_asc(const void *a, const void *b);
42
43static int cmp_index_des( const void *a, const void *b);
44static int cmp_int_des( const void *a, const void *b);
45static int cmp_double_des( const void *a, const void *b);
46static int cmp_cpl_size_des( const void *a, const void *b);
47static int cmp_hdrl_value_des(const void *a, const void *b);
48
49static cpl_error_code sort_and_gen_index(double *a, cpl_size nE, sort_index *a_index, cpl_sort_direction dir);
50static cpl_error_code sort_array_using_index(sort_index *a_index, cpl_size nE, void *b, hdrl_sort_type type);
51
52
53/*----------------------------------------------------------------------------*/
61/*----------------------------------------------------------------------------*/
62
65/* ---------------------------------------------------------------------------*/
81/* ---------------------------------------------------------------------------*/
82cpl_error_code sort_array_f(void *a, cpl_size nE, cpl_size sE, f_compare f)
83{
84 /* Generic funtion in C99 STD standard.
85 * All the rest of the functions call, at the end, this function.
86 * If you need to change the method of sort and affect all of hdrl library,
87 * you need to change only that part. */
88 qsort(a, nE, sE, f);
89
90 return CPL_ERROR_NONE;
91}
92
93/* ---------------------------------------------------------------------------*/
106/* ---------------------------------------------------------------------------*/
107cpl_error_code sort_array(void *a, cpl_size nE, cpl_size sE, hdrl_sort_type type, cpl_sort_direction dir)
108{
109 f_compare f;
110
111 if (dir == CPL_SORT_ASCENDING) {
112
113 /* Ascending order hdrl_sort_type functions */
114 switch(type) {
115 case HDRL_SORT_INT : f = &cmp_int_asc; break;
116 case HDRL_SORT_DOUBLE : f = &cmp_double_asc; break;
117 case HDRL_SORT_CPL_SIZE : f = &cmp_cpl_size_asc; break;
118 case HDRL_SORT_HDRL_VALUE : f = &cmp_hdrl_value_asc; break;
119 default : return CPL_ERROR_ILLEGAL_INPUT;
120 }
121
122 } else {
123
124 /* Descending order hdrl_sort_type functions */
125 switch(type) {
126 case HDRL_SORT_INT : f = &cmp_int_des; break;
127 case HDRL_SORT_DOUBLE : f = &cmp_double_des; break;
128 case HDRL_SORT_CPL_SIZE : f = &cmp_cpl_size_des; break;
129 case HDRL_SORT_HDRL_VALUE : f = &cmp_hdrl_value_des; break;
130 default : return CPL_ERROR_ILLEGAL_INPUT;
131 }
132 }
133
134 /* Sort the generic vector */
135 return sort_array_f(a, nE, sE, f);
136}
137
138/* ---------------------------------------------------------------------------*/
152/* ---------------------------------------------------------------------------*/
153cpl_error_code sort_array_index(double *a, cpl_size nE, void *b, hdrl_sort_type type, cpl_sort_direction dir)
154{
155 /* Reserve memory for the index */
156 sort_index *a_index = cpl_malloc(nE * sizeof(sort_index));
157
158 /* Sort 'a' double array and generate the index sort */
159 cpl_error_code e = sort_and_gen_index(a, nE, a_index, dir);
160 if (e == CPL_ERROR_NONE) {
161
162 /* Sort the 'b' generic array with the index sort in 'a' */
163 e = sort_array_using_index(a_index, nE, b, type);
164 }
165
166 /* Cleanup */
167 cpl_free(a_index);
168
169 return e;
170}
171
172/* ---------------------------------------------------------------------------*/
187/* ---------------------------------------------------------------------------*/
188cpl_error_code sort_arrays_index(double *a, cpl_size nE, void **bs, cpl_size nA, hdrl_sort_type *types, cpl_sort_direction dir)
189{
190 /* Reserve memory for the index */
191 sort_index *a_index = cpl_malloc(nE * sizeof(sort_index));
192
193 /* Sort 'a' double array and generate the index sort */
194 cpl_error_code e = sort_and_gen_index(a, nE, a_index, dir);
195 for (cpl_size i = 0; i < nA && e == CPL_ERROR_NONE; i++) {
196
197 /* Sort the 'bs[i]' generic array with the index sort in 'a' */
198 e = sort_array_using_index(a_index, nE, bs[i], types[i]);
199 }
200
201 /* Cleanup */
202 cpl_free(a_index);
203
204 return e;
205}
206
209/* ---------------------------------------------------------------------------*/
221/* ---------------------------------------------------------------------------*/
222static int cmp_index_asc(const void *a, const void *b) {
223
224 const sort_index *a_d = (const sort_index*)a;
225 const sort_index *b_d = (const sort_index*)b;
226
227 return a_d->data < b_d->data ? -1 : (a_d->data > b_d->data ? 1 : 0);
228}
229
230/* ---------------------------------------------------------------------------*/
242/* ---------------------------------------------------------------------------*/
243static int cmp_int_asc(const void * a, const void * b)
244{
245 const int a_d = *(const int *)a;
246 const int b_d = *(const int *)b;
247
248 return a_d < b_d ? -1 : (a_d > b_d ? 1 : 0);
249}
250
251/* ---------------------------------------------------------------------------*/
263/* ---------------------------------------------------------------------------*/
264static int cmp_double_asc(const void * a, const void * b)
265{
266 const double a_d = *(const double *)a;
267 const double b_d = *(const double *)b;
268
269 return a_d < b_d ? -1 : (a_d > b_d ? 1 : 0);
270}
271
272/* ---------------------------------------------------------------------------*/
284/* ---------------------------------------------------------------------------*/
285static int cmp_cpl_size_asc(const void *a, const void *b)
286{
287 const cpl_size a_cs = *(const cpl_size *)a;
288 const cpl_size b_cs = *(const cpl_size *)b;
289
290 return a_cs < b_cs ? -1 : (a_cs > b_cs ? 1 : 0);
291}
292
293/* ---------------------------------------------------------------------------*/
305/* ---------------------------------------------------------------------------*/
306static int cmp_hdrl_value_asc(const void *a, const void *b)
307{
308 const hdrl_value *a_hv = (const hdrl_value*)a;
309 const hdrl_value *b_hv = (const hdrl_value*)b;
310
311 return a_hv->data < b_hv->data ? -1 : (a_hv->data > b_hv->data ? 1 : 0);
312}
313
314/* ---------------------------------------------------------------------------*/
326/* ---------------------------------------------------------------------------*/
327static int cmp_index_des(const void *a, const void *b) {
328
329 const sort_index *a_d = (const sort_index*)a;
330 const sort_index *b_d = (const sort_index*)b;
331
332 return a_d->data > b_d->data ? -1 : (a_d->data < b_d->data ? 1 : 0);
333}
334
335/* ---------------------------------------------------------------------------*/
347/* ---------------------------------------------------------------------------*/
348static int cmp_int_des(const void * a, const void * b)
349{
350 const int a_d = *(const int *)a;
351 const int b_d = *(const int *)b;
352
353 return a_d > b_d ? -1 : (a_d < b_d ? 1 : 0);
354}
355
356/* ---------------------------------------------------------------------------*/
368/* ---------------------------------------------------------------------------*/
369static int cmp_double_des(const void * a, const void * b)
370{
371 const double a_d = *(const double *)a;
372 const double b_d = *(const double *)b;
373
374 return a_d > b_d ? -1 : (a_d < b_d ? 1 : 0);
375}
376
377/* ---------------------------------------------------------------------------*/
389/* ---------------------------------------------------------------------------*/
390static int cmp_cpl_size_des(const void *a, const void *b)
391{
392 const cpl_size a_cs = *(const cpl_size *)a;
393 const cpl_size b_cs = *(const cpl_size *)b;
394
395 return a_cs > b_cs ? -1 : (a_cs < b_cs ? 1 : 0);
396}
397
398/* ---------------------------------------------------------------------------*/
410/* ---------------------------------------------------------------------------*/
411static int cmp_hdrl_value_des(const void *a, const void *b)
412{
413 const hdrl_value *a_hv = (const hdrl_value*)a;
414 const hdrl_value *b_hv = (const hdrl_value*)b;
415
416 return a_hv->data > b_hv->data ? -1 : (a_hv->data < b_hv->data ? 1 : 0);
417}
418
419/* ---------------------------------------------------------------------------*/
431/* ---------------------------------------------------------------------------*/
432static cpl_error_code sort_and_gen_index(double *a, cpl_size nE, sort_index *a_index, cpl_sort_direction dir){
433
434 /* Update the a_index vector with the values in 'a' array and your position
435 * in the array for sort with index */
436 for (cpl_size i = 0; i < nE; i++) {
437 a_index[i].data = a[i];
438 a_index[i].index = i;
439 }
440
441 /* Sort array in ascending/descending order the array with data and index */
442 cpl_error_code e;
443 if (dir == CPL_SORT_ASCENDING) {
444 e = sort_array_f(a_index, nE, sizeof(*a_index), &cmp_index_asc);
445 } else {
446 e = sort_array_f(a_index, nE, sizeof(*a_index), &cmp_index_des);
447 }
448
449 /* Update the original 'a' double array and keep the sort apply in a_index array */
450 if (e == CPL_ERROR_NONE ) {
451 for (cpl_size i = 0; i < nE; i++) {
452 a[i] = a_index[i].data;
453 }
454 }
455
456 return e;
457}
458
459/* ---------------------------------------------------------------------------*/
470/* ---------------------------------------------------------------------------*/
471static cpl_error_code sort_array_using_index(sort_index *a_index, cpl_size nE, void *b, hdrl_sort_type type)
472{
473 if (type == HDRL_SORT_INT) {
474
475 /* Cast generic 'b' array to int
476 * Copy the values in a auxiliary vector
477 * and apply the sort in the a_index array using the copy values */
478 int *b_cast = (int *)b;
479 int b_aux[nE];
480 for (cpl_size i = 0; i < nE; i++) {
481 b_aux[i] = b_cast[i];
482 }
483 for (cpl_size i = 0; i < nE; i++) {
484 b_cast[i] = b_aux[a_index[i].index];
485 }
486
487 } else if (type == HDRL_SORT_DOUBLE) {
488
489 /* Cast generic 'b' array to double
490 * Copy the values in a auxiliary vector
491 * and apply the sort in the a_index array using the copy values */
492 double *b_cast = (double *)b;
493 double b_aux[nE];
494 for (cpl_size i = 0; i < nE; i++) {
495 b_aux[i] = b_cast[i];
496 }
497 for (cpl_size i = 0; i < nE; i++) {
498 b_cast[i] = b_aux[a_index[i].index];
499 }
500
501 } else if (type == HDRL_SORT_CPL_SIZE) {
502
503 /* Cast generic 'b' array to cpl_size
504 * Copy the values in a auxiliary vector
505 * and apply the sort in the a_index array using the copy values */
506 cpl_size *b_cast = (cpl_size *)b;
507 cpl_size b_aux[nE];
508 for (cpl_size i = 0; i < nE; i++) {
509 b_aux[i] = b_cast[i];
510 }
511 for (cpl_size i = 0; i < nE; i++) {
512 b_cast[i] = b_aux[a_index[i].index];
513 }
514
515 } else if (type == HDRL_SORT_HDRL_VALUE) {
516
517 /* Cast generic 'b' array to hdrl_value
518 * Copy the values in a auxiliary vector
519 * and apply the sort in the a_index array using the copy values */
520 hdrl_value *b_cast = (hdrl_value *)b;
521 hdrl_value b_aux[nE];
522 for (cpl_size i = 0; i < nE; i++) {
523 b_aux[i] = b_cast[i];
524 }
525 for (cpl_size i = 0; i < nE; i++) {
526 b_cast[i] = b_aux[a_index[i].index];
527 }
528
529 } else {
530 return CPL_ERROR_ILLEGAL_INPUT;
531 }
532
533 return CPL_ERROR_NONE;
534}
cpl_error_code sort_array_f(void *a, cpl_size nE, cpl_size sE, f_compare f)
sort_array_f Core sort algorith that it's called with the other sort function. If you need to changed...
cpl_error_code sort_array(void *a, cpl_size nE, cpl_size sE, hdrl_sort_type type, cpl_sort_direction dir)
sort_array hdrl function for order arrays with know types. Using the type parameter for select the co...
cpl_error_code sort_arrays_index(double *a, cpl_size nE, void **bs, cpl_size nA, hdrl_sort_type *types, cpl_sort_direction dir)
sort_arrays_index hdrl function for sort several arrays The alghorithm sort 'a' and in the same way s...
cpl_error_code sort_array_index(double *a, cpl_size nE, void *b, hdrl_sort_type type, cpl_sort_direction dir)
sort_array_index hdrl function for sort two arrays The alghorithm sort 'a' and in the same way sort t...