@@ -15370,7 +15370,7 @@ gretl_matrix *gretl_matrix_sort_by_column (const gretl_matrix *m,
1537015370 return NULL ;
1537115371 }
1537215372
15373- a = gretl_matrix_alloc ( m -> rows , m -> cols );
15373+ a = gretl_matrix_copy ( m );
1537415374 if (a == NULL ) {
1537515375 free (rs );
1537615376 * err = E_ALLOC ;
@@ -15410,6 +15410,122 @@ gretl_matrix *gretl_matrix_sort_by_column (const gretl_matrix *m,
1541015410 return a ;
1541115411}
1541215412
15413+ struct rsortx {
15414+ double * x ;
15415+ int n ;
15416+ int row ;
15417+ };
15418+
15419+ static int compare_rsortx (const void * a , const void * b )
15420+ {
15421+ const struct rsortx * rsa = (const struct rsortx * ) a ;
15422+ const struct rsortx * rsb = (const struct rsortx * ) b ;
15423+ int i , ret = 0 ;
15424+
15425+ for (i = 0 ; i < rsa -> n ; i ++ ) {
15426+ ret = unstable_comp (rsa -> x [i ], rsb -> x [i ]);
15427+ if (ret != 0 ) {
15428+ break ;
15429+ } else {
15430+ /* ensure stable sort and continue */
15431+ ret = a - b > 0 ? 1 : -1 ;
15432+ }
15433+ }
15434+
15435+ return ret ;
15436+ }
15437+
15438+ gretl_matrix * gretl_matrix_sort_by_columns (const gretl_matrix * m ,
15439+ int * cols , int * err )
15440+ {
15441+ struct rsortx * rsx = NULL ;
15442+ gretl_matrix * a = NULL ;
15443+ double * rvals = NULL ;
15444+ double * rptr = NULL ;
15445+ double x ;
15446+ int ns , i , j ;
15447+
15448+ if (gretl_is_null_matrix (m )) {
15449+ * err = E_DATA ;
15450+ return NULL ;
15451+ }
15452+
15453+ if (cols == NULL || cols [0 ] == 0 ) {
15454+ return gretl_matrix_copy (m );
15455+ }
15456+
15457+ /* check out the @cols argument */
15458+ ns = cols [0 ];
15459+ if (ns > m -> cols ) {
15460+ * err = E_INVARG ;
15461+ } else {
15462+ for (i = 1 ; i <=ns ; i ++ ) {
15463+ if (cols [i ] < 0 || cols [i ] >= m -> cols ) {
15464+ * err = E_INVARG ;
15465+ break ;
15466+ }
15467+ }
15468+ }
15469+ if (* err ) {
15470+ return NULL ;
15471+ }
15472+
15473+ rsx = malloc (m -> rows * sizeof * rsx );
15474+ rvals = malloc (m -> rows * ns * sizeof * rvals );
15475+ if (rsx == NULL || rvals == NULL ) {
15476+ * err = E_ALLOC ;
15477+ goto bailout ;
15478+ }
15479+
15480+ a = gretl_matrix_copy (m );
15481+ if (a == NULL ) {
15482+ * err = E_ALLOC ;
15483+ goto bailout ;
15484+ }
15485+
15486+ /* fill the rsortx structs */
15487+ rptr = rvals ;
15488+ for (i = 0 ; i < m -> rows ; i ++ ) {
15489+ rsx [i ].x = rptr ;
15490+ for (j = 0 ; j < ns ; j ++ ) {
15491+ rsx [i ].x [j ] = gretl_matrix_get (m , i , cols [j + 1 ]);
15492+ }
15493+ rsx [i ].n = ns ;
15494+ rsx [i ].row = i ;
15495+ rptr += ns ;
15496+ }
15497+
15498+ qsort (rsx , m -> rows , sizeof * rsx , compare_rsortx );
15499+
15500+ for (j = 0 ; j < m -> cols ; j ++ ) {
15501+ for (i = 0 ; i < m -> rows ; i ++ ) {
15502+ x = gretl_matrix_get (m , rsx [i ].row , j );
15503+ gretl_matrix_set (a , i , j , x );
15504+ }
15505+ }
15506+
15507+ if (a -> info != NULL && a -> info -> rownames != NULL ) {
15508+ char * * S = malloc (a -> rows * sizeof * S );
15509+
15510+ if (S != NULL ) {
15511+ for (i = 0 ; i < a -> rows ; i ++ ) {
15512+ S [i ] = a -> info -> rownames [i ];
15513+ }
15514+ for (i = 0 ; i < a -> rows ; i ++ ) {
15515+ a -> info -> rownames [i ] = S [rsx [i ].row ];
15516+ }
15517+ free (S );
15518+ }
15519+ }
15520+
15521+ bailout :
15522+
15523+ free (rsx );
15524+ free (rvals );
15525+
15526+ return a ;
15527+ }
15528+
1541315529#define has_colnames (m ) (m != NULL && !is_block_matrix(m) && \
1541415530 m->info != NULL && m->info->colnames != NULL)
1541515531
0 commit comments