Skip to content

Commit 3935107

Browse files
committed
streamline matrix_aggregate
1 parent fac3281 commit 3935107

File tree

1 file changed

+43
-47
lines changed

1 file changed

+43
-47
lines changed

lib/src/genfuncs.c

+43-47
Original file line numberDiff line numberDiff line change
@@ -7597,6 +7597,12 @@ static gretl_matrix *series_aggregate (const gretl_matrix *X,
75977597

75987598
#if AGGR_SORT_ALL
75997599

7600+
/* Design: start by forming (y ~ X), where y is a vector, and sorting
7601+
this matrix by its first column. This is an expensive operation,
7602+
but once it's done the rest of the calculation is very
7603+
straightforward.
7604+
*/
7605+
76007606
gretl_matrix *matrix_aggregate (const gretl_matrix *X,
76017607
const gretl_matrix *y,
76027608
const char *func,
@@ -7608,13 +7614,11 @@ gretl_matrix *matrix_aggregate (const gretl_matrix *X,
76087614
gretl_matrix *M;
76097615
gretl_matrix *ret;
76107616
double *z, *zsave;
7611-
double by = 0;
76127617
double rkj;
7618+
int *counts = NULL;
76137619
int nx = X->cols;
76147620
int nby = 0;
7615-
int do_final = 0;
7616-
int t1, t2, count;
7617-
int i, j, k;
7621+
int i, j, k, nk;
76187622

76197623
if (X == NULL || y == NULL || X->rows != y->rows) {
76207624
*err = E_NONCONF;
@@ -7646,72 +7650,64 @@ gretl_matrix *matrix_aggregate (const gretl_matrix *X,
76467650
/* determine the number of 'by' values */
76477651
nby = 0;
76487652
for (i=0; i<M->rows; i++) {
7649-
by = M->val[i];
7650-
if (i == 0 || by != M->val[i-1]) {
7653+
if (i == 0 || M->val[i] > M->val[i-1]) {
76517654
nby++;
76527655
}
76537656
}
76547657

76557658
/* allocate the return matrix */
76567659
ret = gretl_zero_matrix_new(nby, 2 + nx);
7660+
if (ret == NULL) {
7661+
*err = E_ALLOC;
7662+
gretl_matrix_free(M);
7663+
return NULL;
7664+
}
76577665

7658-
z = M->val + M->rows;
7659-
by = M->val[0];
7660-
t2 = t1 = 0;
7661-
k = 0;
7662-
7663-
for (i=1; i<M->rows; i++) {
7664-
by = M->val[i];
7665-
if (by > M->val[i-1] && i == M->rows - 1) {
7666-
do_final = 1;
7667-
}
7668-
if (by > M->val[i-1] || i == M->rows - 1) {
7669-
if (i == M->rows - 1 && by == M->val[i-1]) {
7670-
t2++;
7671-
}
7672-
/* calculate */
7666+
/* get the per-value counts, filling the first two columns
7667+
of @ret as we go
7668+
*/
7669+
counts = calloc(nby, sizeof *counts);
7670+
counts[0] = 1;
7671+
for (i=1, k=0; i<M->rows; i++) {
7672+
if (M->val[i] > M->val[i-1]) {
76737673
gretl_matrix_set(ret, k, 0, M->val[i-1]);
7674-
count = t2 - t1 + 1;
7675-
gretl_matrix_set(ret, k, 1, (double) count);
7676-
zsave = z;
7677-
for (j=0; j<nx; j++) {
7678-
if (dbuiltin) {
7679-
rkj = (*dbuiltin)(t1, t2, z);
7680-
} else {
7681-
rkj = (double) (*ibuiltin)(t1, t2, z);
7682-
}
7683-
gretl_matrix_set(ret, k, j+2, rkj);
7684-
z += M->rows;
7674+
gretl_matrix_set(ret, k, 1, (double) counts[k]);
7675+
counts[++k] = 1;
7676+
if (i == M->rows - 1) {
7677+
gretl_matrix_set(ret, k, 0, M->val[i]);
7678+
gretl_matrix_set(ret, k, 1, 1.0);
76857679
}
7686-
z = zsave + count;
7687-
k++;
7688-
t1 = t2 = 0;
76897680
} else {
7690-
/* increment sample range */
7691-
t2++;
7681+
counts[k] += 1;
7682+
if (i == M->rows - 1) {
7683+
gretl_matrix_set(ret, k, 0, M->val[i]);
7684+
gretl_matrix_set(ret, k, 1, (double) counts[k]);
7685+
}
76927686
}
76937687
}
76947688

7695-
if (do_final) {
7696-
/* handle singleton final row */
7697-
by = M->val[M->rows - 1];
7698-
t1 = t2 = 0;
7699-
count = 1;
7700-
gretl_matrix_set(ret, k, 0, by);
7701-
gretl_matrix_set(ret, k, 1, (double) count);
7689+
z = M->val + M->rows; /* the @X portion of @M */
7690+
7691+
/* do the actual aggregation */
7692+
for (k=0; k<nby; k++) {
77027693
zsave = z;
7694+
nk = counts[k] - 1;
77037695
for (j=0; j<nx; j++) {
7704-
if (dbuiltin) {
7705-
rkj = (*dbuiltin)(t1, t2, z);
7696+
if (dbuiltin) {
7697+
rkj = (*dbuiltin)(0, nk, z);
77067698
} else {
7707-
rkj = (double) (*ibuiltin)(t1, t2, z);
7699+
rkj = (double) (*ibuiltin)(0, nk, z);
77087700
}
77097701
gretl_matrix_set(ret, k, j+2, rkj);
7702+
/* skip to the next column */
77107703
z += M->rows;
77117704
}
7705+
/* move to the next block of rows */
7706+
z = zsave + counts[k];
77127707
}
77137708

77147709
gretl_matrix_free(M);
7710+
free(counts);
77157711

77167712
return ret;
77177713
}

0 commit comments

Comments
 (0)