Skip to content

Commit

Permalink
add a matrix-sorting function
Browse files Browse the repository at this point in the history
  • Loading branch information
AllinCottrell committed Mar 2, 2025
1 parent 3935107 commit 859a92a
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 1 deletion.
118 changes: 117 additions & 1 deletion lib/src/gretl_matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -15370,7 +15370,7 @@ gretl_matrix *gretl_matrix_sort_by_column (const gretl_matrix *m,
return NULL;
}

a = gretl_matrix_alloc(m->rows, m->cols);
a = gretl_matrix_copy(m);
if (a == NULL) {
free(rs);
*err = E_ALLOC;
Expand Down Expand Up @@ -15410,6 +15410,122 @@ gretl_matrix *gretl_matrix_sort_by_column (const gretl_matrix *m,
return a;
}

struct rsortx {
double *x;
int n;
int row;
};

static int compare_rsortx (const void *a, const void *b)
{
const struct rsortx *rsa = (const struct rsortx *) a;
const struct rsortx *rsb = (const struct rsortx *) b;
int i, ret = 0;

for (i=0; i<rsa->n; i++) {
ret = unstable_comp(rsa->x[i], rsb->x[i]);
if (ret != 0) {
break;
} else {
/* ensure stable sort and continue */
ret = a - b > 0 ? 1 : -1;
}
}

return ret;
}

gretl_matrix *gretl_matrix_sort_by_columns (const gretl_matrix *m,
int *cols, int *err)
{
struct rsortx *rsx = NULL;
gretl_matrix *a = NULL;
double *rvals = NULL;
double *rptr = NULL;
double x;
int ns, i, j;

if (gretl_is_null_matrix(m)) {
*err = E_DATA;
return NULL;
}

if (cols == NULL || cols[0] == 0) {
return gretl_matrix_copy(m);
}

/* check out the @cols argument */
ns = cols[0];
if (ns > m->cols) {
*err = E_INVARG;
} else {
for (i=1; i<=ns; i++) {
if (cols[i] < 0 || cols[i] >= m->cols) {
*err = E_INVARG;
break;
}
}
}
if (*err) {
return NULL;
}

rsx = malloc(m->rows * sizeof *rsx);
rvals = malloc(m->rows * ns * sizeof *rvals);
if (rsx == NULL || rvals == NULL) {
*err = E_ALLOC;
goto bailout;
}

a = gretl_matrix_copy(m);
if (a == NULL) {
*err = E_ALLOC;
goto bailout;
}

/* fill the rsortx structs */
rptr = rvals;
for (i=0; i<m->rows; i++) {
rsx[i].x = rptr;
for (j=0; j<ns; j++) {
rsx[i].x[j] = gretl_matrix_get(m, i, cols[j+1]);
}
rsx[i].n = ns;
rsx[i].row = i;
rptr += ns;
}

qsort(rsx, m->rows, sizeof *rsx, compare_rsortx);

for (j=0; j<m->cols; j++) {
for (i=0; i<m->rows; i++) {
x = gretl_matrix_get(m, rsx[i].row, j);
gretl_matrix_set(a, i, j, x);
}
}

if (a->info != NULL && a->info->rownames != NULL) {
char **S = malloc(a->rows * sizeof *S);

if (S != NULL) {
for (i=0; i<a->rows; i++) {
S[i] = a->info->rownames[i];
}
for (i=0; i<a->rows; i++) {
a->info->rownames[i] = S[rsx[i].row];
}
free(S);
}
}

bailout:

free(rsx);
free(rvals);

return a;
}

#define has_colnames(m) (m != NULL && !is_block_matrix(m) && \
m->info != NULL && m->info->colnames != NULL)

Expand Down
3 changes: 3 additions & 0 deletions lib/src/gretl_matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,9 @@ gretl_matrix *gretl_matrix_bool_sel(const gretl_matrix *A,
gretl_matrix *gretl_matrix_sort_by_column (const gretl_matrix *m,
int k, int *err);

gretl_matrix *gretl_matrix_sort_by_columns (const gretl_matrix *m,
int *cols, int *err);

gretl_matrix *gretl_vector_sort (const gretl_matrix *v,
int descending,
int *err);
Expand Down

0 comments on commit 859a92a

Please sign in to comment.