@@ -7597,6 +7597,12 @@ static gretl_matrix *series_aggregate (const gretl_matrix *X,
7597
7597
7598
7598
#if AGGR_SORT_ALL
7599
7599
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
+
7600
7606
gretl_matrix * matrix_aggregate (const gretl_matrix * X ,
7601
7607
const gretl_matrix * y ,
7602
7608
const char * func ,
@@ -7608,13 +7614,11 @@ gretl_matrix *matrix_aggregate (const gretl_matrix *X,
7608
7614
gretl_matrix * M ;
7609
7615
gretl_matrix * ret ;
7610
7616
double * z , * zsave ;
7611
- double by = 0 ;
7612
7617
double rkj ;
7618
+ int * counts = NULL ;
7613
7619
int nx = X -> cols ;
7614
7620
int nby = 0 ;
7615
- int do_final = 0 ;
7616
- int t1 , t2 , count ;
7617
- int i , j , k ;
7621
+ int i , j , k , nk ;
7618
7622
7619
7623
if (X == NULL || y == NULL || X -> rows != y -> rows ) {
7620
7624
* err = E_NONCONF ;
@@ -7646,72 +7650,64 @@ gretl_matrix *matrix_aggregate (const gretl_matrix *X,
7646
7650
/* determine the number of 'by' values */
7647
7651
nby = 0 ;
7648
7652
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 ]) {
7651
7654
nby ++ ;
7652
7655
}
7653
7656
}
7654
7657
7655
7658
/* allocate the return matrix */
7656
7659
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
+ }
7657
7665
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 ]) {
7673
7673
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 );
7685
7679
}
7686
- z = zsave + count ;
7687
- k ++ ;
7688
- t1 = t2 = 0 ;
7689
7680
} 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
+ }
7692
7686
}
7693
7687
}
7694
7688
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 ++ ) {
7702
7693
zsave = z ;
7694
+ nk = counts [k ] - 1 ;
7703
7695
for (j = 0 ; j < nx ; j ++ ) {
7704
- if (dbuiltin ) {
7705
- rkj = (* dbuiltin )(t1 , t2 , z );
7696
+ if (dbuiltin ) {
7697
+ rkj = (* dbuiltin )(0 , nk , z );
7706
7698
} else {
7707
- rkj = (double ) (* ibuiltin )(t1 , t2 , z );
7699
+ rkj = (double ) (* ibuiltin )(0 , nk , z );
7708
7700
}
7709
7701
gretl_matrix_set (ret , k , j + 2 , rkj );
7702
+ /* skip to the next column */
7710
7703
z += M -> rows ;
7711
7704
}
7705
+ /* move to the next block of rows */
7706
+ z = zsave + counts [k ];
7712
7707
}
7713
7708
7714
7709
gretl_matrix_free (M );
7710
+ free (counts );
7715
7711
7716
7712
return ret ;
7717
7713
}
0 commit comments