diff --git a/src/z_spm.c b/src/z_spm.c index 34e59f5a9116e2ae6feabe883d5fd46a14ad7388..090e5bdf51a56a455342583880330c0932427736 100644 --- a/src/z_spm.c +++ b/src/z_spm.c @@ -65,7 +65,7 @@ z_spmSort( spmatrix_t *spm ) #else sortptr[0] = rowptr; sortptr[1] = values; - z_spmIntSortAsc( sortptr, size ); + z_spmIntFltSortAsc( sortptr, size ); #endif rowptr += size; values += size; @@ -81,7 +81,7 @@ z_spmSort( spmatrix_t *spm ) #else sortptr[0] = colptr; sortptr[1] = values; - z_spmIntSortAsc( sortptr, size ); + z_spmIntFltSortAsc( sortptr, size ); #endif colptr += size; values += size; diff --git a/src/z_spm.h b/src/z_spm.h index de270d3113d990ea12d39fb5f37d093def9e9ff2..27254c73f878723153392807c2053289aac3d90e 100644 --- a/src/z_spm.h +++ b/src/z_spm.h @@ -23,7 +23,8 @@ /** * Integer routines */ -void z_spmIntSortAsc(void ** const pbase, const spm_int_t n); +void z_spmIntFltSortAsc(void ** const pbase, const spm_int_t n); +void z_spmIntIntFltSortAsc(void ** const pbase, const spm_int_t n); /** * Conversion routines diff --git a/src/z_spm_integer.c b/src/z_spm_integer.c index cfe6513714f945e8ce1cc34ae247c22635bb06af..e3a863ceb7833a2c5df2d4615d2f438ad695d10f 100644 --- a/src/z_spm_integer.c +++ b/src/z_spm_integer.c @@ -22,7 +22,7 @@ /** ******************************************************************************* * - * @fn void z_spmIntSortAsc(void ** const pbase, const spm_int_t n) + * @fn void z_spmIntFltSortAsc(void ** const pbase, const spm_int_t n) * @ingroup spm_dev_integer * @brief Sort 2 arrays simultaneously, the first array is an array of * spm_int_t and used as key for sorting. The second array is an array of @@ -40,9 +40,9 @@ ******************************************************************************* */ #ifndef DOXYGEN_SHOULD_SKIP_THIS -static size_t intsortsize[2] = { sizeof(spm_int_t), sizeof(spm_complex64_t) }; -#define INTSORTNAME z_spmIntSortAsc -#define INTSORTSIZE(x) (intsortsize[x]) +static size_t intsortsize_if[2] = { sizeof(spm_int_t), sizeof(spm_complex64_t) }; +#define INTSORTNAME z_spmIntFltSortAsc +#define INTSORTSIZE(x) (intsortsize_if[x]) #define INTSORTNTAB 2 #define INTSORTSWAP(p,q) do { \ spm_int_t t; \ @@ -68,3 +68,64 @@ static size_t intsortsize[2] = { sizeof(spm_int_t), sizeof(spm_complex64_t) }; #undef INTSORTNTAB #endif /* DOXYGEN_SHOULD_SKIP_THIS */ +/** + ******************************************************************************* + * + * @fn void z_spmIntIntFltSortAsc(void ** const pbase, const spm_int_t n) + * @ingroup spm_dev_integer + * @brief Sort 2 arrays simultaneously, the first array is an array of + * spm_int_t and used as key for sorting. The second array is an array of + * spm_complex64_t. + * + ******************************************************************************* + * + * @param[inout] pbase + * Couple of pointers to an array of integers and to an array of + * spm_complex64_t to sort. + * + * @param[in] n + * The number of elements in the array. + * + ******************************************************************************* + */ +#ifndef DOXYGEN_SHOULD_SKIP_THIS +static size_t intsortsize_iif[3] = { sizeof(spm_int_t), sizeof(spm_int_t), sizeof(spm_complex64_t) }; +#define INTSORTNAME z_spmIntIntFltSortAsc +#define INTSORTSIZE(x) (intsortsize_iif[x]) +#define INTSORTNTAB 3 +#define INTSORTSWAP(p,q) do { \ + spm_int_t t; \ + long disp_p = (((spm_int_t*)p)-((spm_int_t*)base_ptr)); \ + long disp_q = (((spm_int_t*)q)-((spm_int_t*)base_ptr)); \ + spm_int_t * intptr = *(pbase+1); \ + spm_complex64_t * fltptr = *(pbase+2); \ + spm_complex64_t f; \ + /* swap integers */ \ + t = *((spm_int_t *) (p)); \ + *((spm_int_t *) (p)) = *((spm_int_t *) (q)); \ + *((spm_int_t *) (q)) = t; \ + /* swap on second integer array */ \ + t = intptr[disp_p]; \ + intptr[disp_p] = intptr[disp_q]; \ + intptr[disp_q] = t; \ + /* swap corresponding values */ \ + f = fltptr[disp_p]; \ + fltptr[disp_p] = fltptr[disp_q]; \ + fltptr[disp_q] = f; \ + } while (0) + +static inline int +intsortcmp_iif( void ** const pbase, spm_int_t *p, spm_int_t *q ) { + spm_int_t *int1ptr = pbase[0]; + spm_int_t *int2ptr = pbase[1]; + return ( ( *p < *q ) || (( *p == *q ) && ( int2ptr[ p - int1ptr ] < int2ptr[ q - int1ptr ] )) ); +} +#define INTSORTCMP(p,q) intsortcmp_iif( pbase, (spm_int_t*)p, (spm_int_t*)q ) +#include "integer_sort_mtypes.c" +#undef INTSORTNAME +#undef INTSORTSIZE +#undef INTSORTSWAP +#undef INTSORTCMP +#undef INTSORTNTAB +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ +