introduce `cx_sortorder()' function

This commit is contained in:
dwarning 2013-08-20 21:39:20 +02:00 committed by rlar
parent e308f52e26
commit 075b620a86
4 changed files with 61 additions and 0 deletions

View File

@ -162,6 +162,7 @@ struct func ft_funcs[] = {
{ "cosh", cx_cosh },
{ "tanh", cx_tanh },
{ "atan", cx_atan },
{ "sortorder", cx_sortorder },
{ "norm", cx_norm },
{ "rnd", cx_rnd },
{ "sunif", cx_sunif },

View File

@ -74,6 +74,7 @@ extern void *cx_tanh(void *, short int , int , int *, short int *);
extern void *cx_atan(void *, short int , int , int *, short int *);
extern void *cx_floor(void *, short int , int , int *, short int *);
extern void *cx_ceil(void *, short int , int , int *, short int *);
extern void *cx_sortorder(void *, short int , int , int *, short int *);
/* cmath2.c */

View File

@ -709,3 +709,61 @@ cx_atan(void *data, short int type, int length, int *newlength, short int *newty
}
return ((void *) d);
}
/* Struct to store and order the values of the amplitudes preserving the index in the original array */
typedef struct {
double amplitude;
int index;
} amplitude_index_t;
static int compare_structs (const void *a, const void *b);
/*
* Returns the positions of the elements in a real vector
* after they have been sorted into increasing order using a stable method (qsort).
*/
void *
cx_sortorder(void *data, short int type, int length, int *newlength, short int *newtype)
{
double *d = alloc_d(length);
double *dd = (double *) data;
int i;
amplitude_index_t *array_amplitudes;
array_amplitudes = (amplitude_index_t *) malloc(sizeof(amplitude_index_t) * (size_t) length);
*newlength = length;
*newtype = VF_REAL;
if (type == VF_REAL) {
for(i = 0; i < length; i++){
array_amplitudes[i].amplitude = dd[i];
array_amplitudes[i].index = i;
}
qsort(array_amplitudes, (size_t) length, sizeof(array_amplitudes[0]), compare_structs);
for(i = 0; i < length; i++)
d[i] = array_amplitudes[i].index;
}
free(array_amplitudes);
/* Otherwise it is 0, but tmalloc zeros the stuff already. */
return ((void *) d);
}
static int
compare_structs(const void *a, const void *b)
{
amplitude_index_t *aa = (amplitude_index_t *) a;
amplitude_index_t *bb = (amplitude_index_t *) b;
if (aa->amplitude > bb->amplitude)
return 1;
else if (aa->amplitude == bb->amplitude)
return 0;
else
return -1;
}

View File

@ -27,6 +27,7 @@ void * cx_cosh(void *data, short int type, int length, int *newlength, short int
void * cx_tan(void *data, short int type, int length, int *newlength, short int *newtype);
void * cx_tanh(void *data, short int type, int length, int *newlength, short int *newtype);
void * cx_atan(void *data, short int type, int length, int *newlength, short int *newtype);
void * cx_sortorder(void *data, short int type, int length, int *newlength, short int *newtype);
#endif