From 075b620a86b6a03af56f0cf2a694e843edd392b2 Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 20 Aug 2013 21:39:20 +0200 Subject: [PATCH] introduce `cx_sortorder()' function --- src/frontend/parse.c | 1 + src/include/ngspice/fteext.h | 1 + src/maths/cmaths/cmath1.c | 58 ++++++++++++++++++++++++++++++++++++ src/maths/cmaths/cmath1.h | 1 + 4 files changed, 61 insertions(+) diff --git a/src/frontend/parse.c b/src/frontend/parse.c index 29457a1de..ad3b7f1a5 100644 --- a/src/frontend/parse.c +++ b/src/frontend/parse.c @@ -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 }, diff --git a/src/include/ngspice/fteext.h b/src/include/ngspice/fteext.h index 9c70d15a4..5e98cfc5c 100644 --- a/src/include/ngspice/fteext.h +++ b/src/include/ngspice/fteext.h @@ -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 */ diff --git a/src/maths/cmaths/cmath1.c b/src/maths/cmaths/cmath1.c index b8427ec22..d96e16cb0 100644 --- a/src/maths/cmaths/cmath1.c +++ b/src/maths/cmaths/cmath1.c @@ -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; +} diff --git a/src/maths/cmaths/cmath1.h b/src/maths/cmaths/cmath1.h index 165738a9a..b6456f3d7 100644 --- a/src/maths/cmaths/cmath1.h +++ b/src/maths/cmaths/cmath1.h @@ -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