Changeset: 05b5736f9f89 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=05b5736f9f89
Removed Files:
sql/backends/monet5/sql_aggr_bte.mal
sql/backends/monet5/sql_aggr_dbl.mal
sql/backends/monet5/sql_aggr_flt.mal
sql/backends/monet5/sql_aggr_hge.mal
sql/backends/monet5/sql_aggr_int.mal
sql/backends/monet5/sql_aggr_lng.mal
sql/backends/monet5/sql_aggr_sht.mal
Modified Files:
gdk/gdk_aggr.c
gdk/gdk_calc.h
monetdb5/modules/kernel/00_aggr_hge.mal
monetdb5/modules/kernel/00_aggr_hge.mal.sh
monetdb5/modules/kernel/aggr.c
monetdb5/modules/kernel/aggr.mal
monetdb5/modules/kernel/aggr.mal.sh
monetdb5/modules/kernel/algebra.c
monetdb5/modules/kernel/algebra.h
monetdb5/modules/kernel/algebra.mal
sql/backends/monet5/Makefile.ag
sql/backends/monet5/sql.mal
sql/backends/monet5/sql_hge.mal
sql/test/BugTracker-2017/Tests/corr_coersion.Bug-6287.stable.out
sql/test/analytics/Tests/analytics16.sql
sql/test/analytics/Tests/analytics16.stable.out
Branch: statistics-analytics
Log Message:
Moved correlation aggregate definition into C. Now it outputs more accurate
results
diffs (truncated from 1672 to 300 lines):
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -3221,6 +3221,68 @@ BATcalccovariance_sample(BAT *b1, BAT *b
BATcount(b1), b1->ttype,
true, "BATcalccovariance_sample");
}
+#define AGGR_CORRELATION_SINGLE(TYPE) \
+ do { \
+ TYPE x, y; \
+ for (i = 0; i < cnt; i++) { \
+ x = ((const TYPE *) v1)[i]; \
+ y = ((const TYPE *) v2)[i]; \
+ if (is_##TYPE##_nil(x) || is_##TYPE##_nil(y)) \
+ continue; \
+ n++; \
+ delta1 = (dbl) x - mean1; \
+ mean1 += delta1 / n; \
+ delta2 = (dbl) y - mean2; \
+ mean2 += delta2 / n; \
+ aux = (dbl) y - mean2; \
+ up += delta1 * aux; \
+ down1 += delta1 * ((dbl) x - mean1); \
+ down2 += delta2 * aux; \
+ } \
+ } while (0)
+
+dbl
+BATcalccorrelation(BAT *b1, BAT *b2)
+{
+ BUN n = 0, i, cnt = BATcount(b1);
+ dbl mean1 = 0, mean2 = 0, up = 0, down1 = 0, down2 = 0, delta1, delta2,
aux;
+ const void *restrict v1 = (const void *) Tloc(b1, 0), *restrict v2 =
(const void *) Tloc(b2, 0);
+ int tp = b1->ttype;
+
+ switch (tp) {
+ case TYPE_bte:
+ AGGR_CORRELATION_SINGLE(bte);
+ break;
+ case TYPE_sht:
+ AGGR_CORRELATION_SINGLE(sht);
+ break;
+ case TYPE_int:
+ AGGR_CORRELATION_SINGLE(int);
+ break;
+ case TYPE_lng:
+ AGGR_CORRELATION_SINGLE(lng);
+ break;
+#ifdef HAVE_HGE
+ case TYPE_hge:
+ AGGR_CORRELATION_SINGLE(hge);
+ break;
+#endif
+ case TYPE_flt:
+ AGGR_CORRELATION_SINGLE(flt);
+ break;
+ case TYPE_dbl:
+ AGGR_CORRELATION_SINGLE(dbl);
+ break;
+ default:
+ GDKerror("%s: type (%s) not supported.\n", __func__,
ATOMname(tp));
+ return dbl_nil;
+ }
+ if (n > 0 && up > 0 && down1 > 0 && down2 > 0)
+ return (up / n) / (sqrt(down1 / n) * sqrt(down2 / n));
+ else
+ return dbl_nil;
+}
+
#define AGGR_STDEV(TYPE) \
do { \
const TYPE *restrict vals = (const TYPE *) Tloc(b, 0); \
@@ -3482,8 +3544,6 @@ BATgroupvariance_population(BAT *b, BAT
for (i = 0; i < ngrp; i++) { \
if (cnts[i] == 0 || cnts[i] == BUN_NONE) { \
dbls[i] = dbl_nil; \
- mean1[i] = dbl_nil; \
- mean2[i] = dbl_nil; \
nils++; \
} else if (cnts[i] == 1) { \
dbls[i] = issample ? dbl_nil : 0; \
@@ -3628,3 +3688,166 @@ BATgroupcovariance_population(BAT *b1, B
(void) abort_on_error;
return dogroupcovariance(b1, b2, g, e, s, tp, skip_nils, false,
"BATgroupcovariance_population");
}
+
+#define AGGR_CORRELATION(TYPE) \
+ do { \
+ const TYPE *restrict vals1 = (const TYPE *) Tloc(b1, 0);
\
+ const TYPE *restrict vals2 = (const TYPE *) Tloc(b2, 0);
\
+ while (ncand > 0) { \
+ ncand--; \
+ i = canditer_next(&ci) - b1->hseqbase; \
+ if (gids == NULL || \
+ (gids[i] >= min && gids[i] <= max)) { \
+ if (gids) \
+ gid = gids[i] - min; \
+ else \
+ gid = (oid) i; \
+ if (is_##TYPE##_nil(vals1[i]) ||
is_##TYPE##_nil(vals2[i])) { \
+ if (!skip_nils) \
+ cnts[gid] = BUN_NONE; \
+ } else if (cnts[gid] != BUN_NONE) { \
+ cnts[gid]++; \
+ delta1[gid] = (dbl) vals1[i] -
mean1[gid]; \
+ mean1[gid] += delta1[gid] / cnts[gid]; \
+ delta2[gid] = (dbl) vals2[i] -
mean2[gid]; \
+ mean2[gid] += delta2[gid] / cnts[gid]; \
+ aux = (dbl) vals2[i] - mean2[gid]; \
+ up[gid] += delta1[gid] * aux; \
+ down1[gid] += delta1[gid] * ((dbl)
vals1[i] - mean1[gid]); \
+ down2[gid] += delta2[gid] * aux; \
+ } \
+ } \
+ } \
+ for (i = 0; i < ngrp; i++) { \
+ if (cnts[i] <= 1 || cnts[i] == BUN_NONE || up[i] <= 0
|| down1[i] <= 0 || down2[i] <= 0) { \
+ dbls[i] = dbl_nil; \
+ nils++; \
+ } else { \
+ dbls[i] = (up[i] / cnts[i]) / (sqrt(down1[i] /
cnts[i]) * sqrt(down2[i] / cnts[i])); \
+ assert(!is_dbl_nil(dbls[i])); \
+ } \
+ } \
+ } while (0)
+
+BAT *
+BATgroupcorrelation(BAT *b1, BAT *b2, BAT *g, BAT *e, BAT *s, int tp, bool
skip_nils, bool abort_on_error)
+{
+ const oid *restrict gids;
+ oid gid, min, max;
+ BUN i, ngrp, nils = 0, ncand;
+ BUN *restrict cnts = NULL;
+ dbl *restrict dbls, *restrict mean1, *restrict mean2, *restrict delta1,
*restrict delta2, *restrict up, *restrict down1, *restrict down2, aux;
+ BAT *bn = NULL;
+ struct canditer ci;
+ const char *err;
+
+ assert(tp == TYPE_dbl && BATcount(b1) == BATcount(b2) && b1->ttype ==
b2->ttype && BATtdense(b1) == BATtdense(b2));
+ (void) tp;
+ (void) abort_on_error;
+
+ if ((err = BATgroupaggrinit(b1, g, e, s, &min, &max, &ngrp, &ci,
&ncand)) != NULL) {
+ GDKerror("%s: %s\n", __func__, err);
+ return NULL;
+ }
+ if (g == NULL) {
+ GDKerror("%s: b1, b2 and g must be aligned\n", __func__);
+ return NULL;
+ }
+
+ if (BATcount(b1) == 0 || ngrp == 0)
+ return BATconstant(ngrp == 0 ? 0 : min, TYPE_dbl, &dbl_nil,
ngrp, TRANSIENT);
+
+ if ((e == NULL ||
+ (BATcount(e) == BATcount(b1) && (e->hseqbase == b1->hseqbase ||
e->hseqbase == b2->hseqbase))) &&
+ (BATtdense(g) || (g->tkey && g->tnonil))) {
+ dbl v = dbl_nil;
+ return BATconstant(ngrp == 0 ? 0 : min, TYPE_dbl, &v, ngrp,
TRANSIENT);
+ }
+
+ delta1 = GDKmalloc(ngrp * sizeof(dbl));
+ delta2 = GDKmalloc(ngrp * sizeof(dbl));
+ up = GDKzalloc(ngrp * sizeof(dbl));
+ down1 = GDKzalloc(ngrp * sizeof(dbl));
+ down2 = GDKzalloc(ngrp * sizeof(dbl));
+ cnts = GDKzalloc(ngrp * sizeof(BUN));
+ mean1 = GDKzalloc(ngrp * sizeof(dbl));
+ mean2 = GDKzalloc(ngrp * sizeof(dbl));
+
+ if (mean1 == NULL || mean2 == NULL || delta1 == NULL || delta2 == NULL
|| up == NULL || down1 == NULL || down2 == NULL || cnts == NULL)
+ goto alloc_fail;
+
+ bn = COLnew(min, TYPE_dbl, ngrp, TRANSIENT);
+ if (bn == NULL)
+ goto alloc_fail;
+ dbls = (dbl *) Tloc(bn, 0);
+
+ if (!g || BATtdense(g))
+ gids = NULL;
+ else
+ gids = (const oid *) Tloc(g, 0);
+
+ switch (b1->ttype) {
+ case TYPE_bte:
+ AGGR_CORRELATION(bte);
+ break;
+ case TYPE_sht:
+ AGGR_CORRELATION(sht);
+ break;
+ case TYPE_int:
+ AGGR_CORRELATION(int);
+ break;
+ case TYPE_lng:
+ AGGR_CORRELATION(lng);
+ break;
+#ifdef HAVE_HGE
+ case TYPE_hge:
+ AGGR_CORRELATION(hge);
+ break;
+#endif
+ case TYPE_flt:
+ AGGR_CORRELATION(flt);
+ break;
+ case TYPE_dbl:
+ AGGR_CORRELATION(dbl);
+ break;
+ default:
+ BBPreclaim(bn);
+ GDKfree(mean1);
+ GDKfree(mean2);
+ GDKfree(delta1);
+ GDKfree(delta2);
+ GDKfree(up);
+ GDKfree(down1);
+ GDKfree(down2);
+ GDKfree(cnts);
+ GDKerror("%s: type (%s) not supported.\n", __func__,
ATOMname(b1->ttype));
+ return NULL;
+ }
+ GDKfree(mean1);
+ GDKfree(mean2);
+ GDKfree(delta1);
+ GDKfree(delta2);
+ GDKfree(up);
+ GDKfree(down1);
+ GDKfree(down2);
+ GDKfree(cnts);
+ BATsetcount(bn, ngrp);
+ bn->tkey = ngrp <= 1;
+ bn->tsorted = ngrp <= 1;
+ bn->trevsorted = ngrp <= 1;
+ bn->tnil = nils != 0;
+ bn->tnonil = nils == 0;
+ return bn;
+alloc_fail:
+ BBPreclaim(bn);
+ GDKfree(mean1);
+ GDKfree(mean2);
+ GDKfree(delta1);
+ GDKfree(delta2);
+ GDKfree(up);
+ GDKfree(down1);
+ GDKfree(down2);
+ GDKfree(cnts);
+ GDKerror("%s: cannot allocate enough memory.\n", __func__);
+ return NULL;
+}
diff --git a/gdk/gdk_calc.h b/gdk/gdk_calc.h
--- a/gdk/gdk_calc.h
+++ b/gdk/gdk_calc.h
@@ -156,8 +156,10 @@ gdk_export BAT *BATgroupvariance_sample(
gdk_export BAT *BATgroupvariance_population(BAT *b, BAT *g, BAT *e, BAT *s,
int tp, bool skip_nils, bool abort_on_error);
gdk_export dbl BATcalccovariance_sample(BAT *b1, BAT *b2);
gdk_export dbl BATcalccovariance_population(BAT *b1, BAT *b2);
+gdk_export dbl BATcalccorrelation(BAT *b1, BAT *b2);
gdk_export BAT *BATgroupcovariance_sample(BAT *b1, BAT *b2, BAT *g, BAT *e,
BAT *s, int tp, bool skip_nils, bool abort_on_error);
gdk_export BAT *BATgroupcovariance_population(BAT *b1, BAT *b2, BAT *g, BAT
*e, BAT *s, int tp, bool skip_nils, bool abort_on_error);
+gdk_export BAT *BATgroupcorrelation(BAT *b1, BAT *b2, BAT *g, BAT *e, BAT *s,
int tp, bool skip_nils, bool abort_on_error);
gdk_export BAT *BATgroupstr_group_concat(BAT *b, BAT *g, BAT *e, BAT *s, bool
skip_nils, bool abort_on_error, const char *separator);
gdk_export gdk_return BATstr_group_concat(ValPtr res, BAT *b, BAT *s, bool
skip_nils, bool abort_on_error, bool nil_if_empty, const char *separator);
diff --git a/monetdb5/modules/kernel/00_aggr_hge.mal
b/monetdb5/modules/kernel/00_aggr_hge.mal
--- a/monetdb5/modules/kernel/00_aggr_hge.mal
+++ b/monetdb5/modules/kernel/00_aggr_hge.mal
@@ -234,3 +234,15 @@ command subcovariancep(b1:bat[:hge],b2:b
address AGGRsubcovariancepcand
comment "Grouped covariance population aggregate with candidate list";
+command corr(b1:bat[:hge],b2:bat[:hge],g:bat[:oid],e:bat[:any_1]) :bat[:dbl]
+address AGGRcorr
+comment "Correlation aggregate";
+
+command
subcorr(b1:bat[:hge],b2:bat[:hge],g:bat[:oid],e:bat[:any_1],skip_nils:bit,abort_on_error:bit)
:bat[:dbl]
+address AGGRsubcorr
+comment "Grouped correlation aggregate";
+
+command
subcorr(b1:bat[:hge],b2:bat[:hge],g:bat[:oid],e:bat[:any_1],s:bat[:oid],skip_nils:bit,abort_on_error:bit)
:bat[:dbl]
+address AGGRsubcorrcand
+comment "Grouped correlation aggregate with candidate list";
+
diff --git a/monetdb5/modules/kernel/00_aggr_hge.mal.sh
b/monetdb5/modules/kernel/00_aggr_hge.mal.sh
--- a/monetdb5/modules/kernel/00_aggr_hge.mal.sh
+++ b/monetdb5/modules/kernel/00_aggr_hge.mal.sh
@@ -182,5 +182,17 @@ command subcovariancep(b1:bat[:${tp}],b2
address AGGRsubcovariancepcand
comment "Grouped covariance population aggregate with candidate list";
+command corr(b1:bat[:${tp}],b2:bat[:${tp}],g:bat[:oid],e:bat[:any_1])
:bat[:dbl]
+address AGGRcorr
+comment "Correlation aggregate";
+
+command
subcorr(b1:bat[:${tp}],b2:bat[:${tp}],g:bat[:oid],e:bat[:any_1],skip_nils:bit,abort_on_error:bit)
:bat[:dbl]
+address AGGRsubcorr
+comment "Grouped correlation aggregate";
+
+command
subcorr(b1:bat[:${tp}],b2:bat[:${tp}],g:bat[:oid],e:bat[:any_1],s:bat[:oid],skip_nils:bit,abort_on_error:bit)
:bat[:dbl]
+address AGGRsubcorrcand
+comment "Grouped correlation aggregate with candidate list";
+
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list