Skip to content

Commit 859a92a

Browse files
committed
add a matrix-sorting function
1 parent 3935107 commit 859a92a

File tree

2 files changed

+120
-1
lines changed

2 files changed

+120
-1
lines changed

lib/src/gretl_matrix.c

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

lib/src/gretl_matrix.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,9 @@ gretl_matrix *gretl_matrix_bool_sel(const gretl_matrix *A,
906906
gretl_matrix *gretl_matrix_sort_by_column (const gretl_matrix *m,
907907
int k, int *err);
908908

909+
gretl_matrix *gretl_matrix_sort_by_columns (const gretl_matrix *m,
910+
int *cols, int *err);
911+
909912
gretl_matrix *gretl_vector_sort (const gretl_matrix *v,
910913
int descending,
911914
int *err);

0 commit comments

Comments
 (0)