Changeset: 3ccd6847f78f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3ccd6847f78f
Modified Files:
gdk/gdk_analytic.h
gdk/gdk_analytic_func.c
sql/backends/monet5/sql_rank.c
sql/backends/monet5/sql_rank.h
sql/backends/monet5/sql_rank.mal
sql/backends/monet5/sql_rank.mal.sh
sql/backends/monet5/sql_rank_hge.mal
sql/backends/monet5/sql_rank_hge.mal.sh
sql/backends/monet5/sql_upgrades.c
sql/scripts/39_analytics.sql
sql/scripts/39_analytics_hge.sql
sql/test/analytics/Tests/analytics14.sql
sql/test/analytics/Tests/analytics14.stable.out
Branch: statistics-analytics
Log Message:
Implemented quantile_avg as a window function
diffs (truncated from 1442 to 300 lines):
diff --git a/gdk/gdk_analytic.h b/gdk/gdk_analytic.h
--- a/gdk/gdk_analytic.h
+++ b/gdk/gdk_analytic.h
@@ -43,6 +43,6 @@ gdk_export gdk_return GDKanalytical_stdd
gdk_export gdk_return GDKanalytical_variance_samp(BAT *r, BAT *b, BAT *s, BAT
*e, int tpe);
gdk_export gdk_return GDKanalytical_variance_pop(BAT *r, BAT *b, BAT *s, BAT
*e, int tpe);
gdk_export gdk_return GDKanalytical_quantile(BAT *r, BAT *b, BAT *s, BAT *e,
BAT *q, const void *restrict quantile, int tp1, int tp2);
-gdk_export gdk_return GDKanalytical_median_avg(BAT *r, BAT *b, BAT *s, BAT *e,
int tpe);
+gdk_export gdk_return GDKanalytical_quantile_avg(BAT *r, BAT *b, BAT *s, BAT
*e, BAT *q, const void *restrict quantile, int tp1, int tp2);
#endif //_GDK_ANALYTIC_H_
diff --git a/gdk/gdk_analytic_func.c b/gdk/gdk_analytic_func.c
--- a/gdk/gdk_analytic_func.c
+++ b/gdk/gdk_analytic_func.c
@@ -2003,77 +2003,158 @@ nosupport:
return GDK_FAIL;
}
-#define ANALYTICAL_MEDIAN_AVG(TPE) \
- do { \
- TPE *restrict bp = (TPE*) Tloc(b, 0), ns, ne; \
- for (; i < cnt; i++, rb++) { \
- ss = (BUN) start[i]; \
- ee = (BUN) end[i]; \
- f = (ee - ss - 1) * 0.5f; \
- lo = floor(f); \
- hi = ceil(f); \
- ns = bp[ss + (BUN) hi]; \
- ne = bp[ss + (BUN) lo]; \
- if (is_##TPE##_nil(ns) || is_##TPE##_nil(ne)) { \
- v = dbl_nil; \
- has_nils = true; \
- } else \
- v = (f - lo) * ns + (lo + 1 - f) * ne; \
- *rb = v; \
+#define ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(TPE) \
+ do { \
+ TPE *bp = (TPE*)Tloc(b, 0), ns, ne; \
+ if (is_dbl_nil(qua)) { \
+ has_nils = true; \
+ for (; i < cnt; i++, rb++) \
+ *rb = dbl_nil; \
+ } else { \
+ for (; i < cnt; i++, rb++) { \
+ ss = (BUN) start[i]; \
+ ee = (BUN) end[i]; \
+ f = (ee - ss - 1) * qua; \
+ lo = floor(f); \
+ hi = ceil(f); \
+ ns = bp[ss + (BUN) hi]; \
+ ne = bp[ss + (BUN) lo]; \
+ if (is_##TPE##_nil(ns) || is_##TPE##_nil(ne)) {
\
+ v = dbl_nil; \
+ has_nils = true; \
+ } else \
+ v = (f - lo) * ns + (lo + 1 - f) * ne; \
+ *rb = v; \
+ } \
} \
} while (0)
+#define ANALYTICAL_QUANTILE_AVG_IMP_MULTI_FIXED(TPE1, TPE2) \
+ do { \
+ TPE2 *restrict qp = (TPE2*)Tloc(q, 0); \
+ for (; i < cnt; i++, rb++) { \
+ TPE2 qua = qp[i]; \
+ if (is_##TPE2##_nil(qua)) { \
+ *rb = dbl_nil; \
+ has_nils = true; \
+ } else { \
+ ss = (BUN) start[i]; \
+ ee = (BUN) end[i]; \
+ f = (ee - ss - 1) * qua; \
+ lo = floor(f); \
+ hi = ceil(f); \
+ ns = bp[ss + (BUN) hi]; \
+ ne = bp[ss + (BUN) lo]; \
+ if (is_##TPE1##_nil(ns) || is_##TPE1##_nil(ne))
{ \
+ v = dbl_nil; \
+ has_nils = true; \
+ } else \
+ v = (f - lo) * ns + (lo + 1 - f) * ne; \
+ *rb = v; \
+ } \
+ } \
+ } while (0)
+
+#define ANALYTICAL_QUANTILE_AVG_CALC_FIXED(TPE1) \
+ do { \
+ TPE1 *restrict bp = (TPE1*)Tloc(b, 0), ns, ne; \
+ switch (tp2) { \
+ case TYPE_flt: \
+ ANALYTICAL_QUANTILE_AVG_IMP_MULTI_FIXED(TPE1, flt); \
+ break; \
+ case TYPE_dbl: \
+ ANALYTICAL_QUANTILE_AVG_IMP_MULTI_FIXED(TPE1, dbl); \
+ break; \
+ default: \
+ goto nosupport; \
+ } \
+ } while (0)
+
gdk_return
-GDKanalytical_median_avg(BAT *r, BAT *b, BAT *s, BAT *e, int tpe)
+GDKanalytical_quantile_avg(BAT *r, BAT *b, BAT *s, BAT *e, BAT *q, const void
*restrict quantile, int tp1, int tp2)
{
- bool has_nils = false;
BUN i = 0, cnt = BATcount(b), ss, ee;
lng *restrict start, *restrict end;
- dbl f, lo, hi, v, *restrict rb = (dbl*) Tloc(r, 0);
+ dbl qua = 0, f, *restrict rb = (dbl*) Tloc(r, 0), v, lo, hi;
+ bool has_nils = false;
- assert(s && e);
+ assert(s && e && ((q && !quantile) || (!q && quantile)));
start = (lng *) Tloc(s, 0);
end = (lng *) Tloc(e, 0);
- if (!ATOMlinear(tpe)) {
- GDKerror("GDKanalytical_median_avg: cannot determine quantile
on "
- "non-linear type %s\n", ATOMname(tpe));
- return GDK_FAIL;
- }
-
- switch (tpe) {
- case TYPE_bte:
- ANALYTICAL_MEDIAN_AVG(bte);
- break;
- case TYPE_sht:
- ANALYTICAL_MEDIAN_AVG(sht);
- break;
- case TYPE_int:
- ANALYTICAL_MEDIAN_AVG(int);
- break;
- case TYPE_lng:
- ANALYTICAL_MEDIAN_AVG(lng);
- break;
+ if (quantile) {
+ switch (tp2) {
+ case TYPE_flt:{
+ flt val = *(flt *) quantile;
+ qua = !is_flt_nil(val) ? (dbl) val : dbl_nil;
+ } break;
+ case TYPE_dbl:{
+ qua = *(dbl *) quantile;
+ } break;
+ default:
+ goto nosupport;
+ }
+ switch (tp1) {
+ case TYPE_bte:
+ ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(bte);
+ break;
+ case TYPE_sht:
+ ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(sht);
+ break;
+ case TYPE_int:
+ ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(int);
+ break;
+ case TYPE_lng:
+ ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(lng);
+ break;
#ifdef HAVE_HGE
- case TYPE_hge:
- ANALYTICAL_MEDIAN_AVG(hge);
- break;
+ case TYPE_hge:
+ ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(hge);
+ break;
#endif
- case TYPE_flt:
- ANALYTICAL_MEDIAN_AVG(flt);
- break;
- case TYPE_dbl:
- ANALYTICAL_MEDIAN_AVG(dbl);
- break;
- default:
- GDKerror("GDKanalytical_median_avg: average of type %s
unsupported.\n", ATOMname(tpe));
- return GDK_FAIL;
+ case TYPE_flt:
+ ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(flt);
+ break;
+ case TYPE_dbl:
+ ANALYTICAL_QUANTILE_AVG_IMP_SINGLE_FIXED(dbl);
+ break;
+ default:
+ goto nosupport;
+ }
+ } else {
+ switch (tp1) {
+ case TYPE_bte:
+ ANALYTICAL_QUANTILE_AVG_CALC_FIXED(bte);
+ break;
+ case TYPE_sht:
+ ANALYTICAL_QUANTILE_AVG_CALC_FIXED(sht);
+ break;
+ case TYPE_int:
+ ANALYTICAL_QUANTILE_AVG_CALC_FIXED(int);
+ break;
+ case TYPE_lng:
+ ANALYTICAL_QUANTILE_AVG_CALC_FIXED(lng);
+ break;
+#ifdef HAVE_HGE
+ case TYPE_hge:
+ ANALYTICAL_QUANTILE_AVG_CALC_FIXED(hge);
+ break;
+#endif
+ case TYPE_flt:
+ ANALYTICAL_QUANTILE_AVG_CALC_FIXED(flt);
+ break;
+ case TYPE_dbl:
+ ANALYTICAL_QUANTILE_AVG_CALC_FIXED(dbl);
+ break;
+ default:
+ goto nosupport;
+ }
}
BATsetcount(r, cnt);
- r->tkey = BATcount(r) <= 1;
- r->tsorted = BATcount(r) <= 1;
- r->trevsorted = BATcount(r) <= 1;
r->tnonil = !has_nils;
r->tnil = has_nils;
return GDK_SUCCEED;
+nosupport:
+ GDKerror("%s: type %s not supported for the quantile.\n", __func__,
ATOMname(tp2));
+ return GDK_FAIL;
}
diff --git a/sql/backends/monet5/sql_rank.c b/sql/backends/monet5/sql_rank.c
--- a/sql/backends/monet5/sql_rank.c
+++ b/sql/backends/monet5/sql_rank.c
@@ -1514,12 +1514,11 @@ SQLprod(Client cntxt, MalBlkPtr mb, MalS
GDKanalyticalprod);
}
-static str
-do_fp_window(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, const
char *op, const char* err,
- gdk_return (*func)(BAT *, BAT *, BAT *, BAT *, int))
+str
+SQLavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
BAT *r, *b, *s, *e;
- str msg = SQLanalytics_args(&r, &b, &s, &e, cntxt, mb, stk, pci,
TYPE_dbl, op, err);
+ str msg = SQLanalytics_args(&r, &b, &s, &e, cntxt, mb, stk, pci,
TYPE_dbl, "sql.avg", SQLSTATE(42000) "avg(:any_1,:lng,:lng)");
int tpe = getArgType(mb, pci, 1);
gdk_return gdk_res;
@@ -1531,14 +1530,14 @@ do_fp_window(Client cntxt, MalBlkPtr mb,
if (b) {
bat *res = getArgReference_bat(stk, pci, 0);
- gdk_res = func(r, b, s, e, tpe);
+ gdk_res = GDKanalyticalavg(r, b, s, e, tpe);
BBPunfix(b->batCacheid);
if (s) BBPunfix(s->batCacheid);
if (e) BBPunfix(e->batCacheid);
if (gdk_res == GDK_SUCCEED)
BBPkeepref(*res = r->batCacheid);
else
- throw(SQL, op, GDK_EXCEPTION);
+ throw(SQL, "sql.avg", GDK_EXCEPTION);
} else {
ptr *res = getArgReference(stk, pci, 0);
ptr *in = getArgReference(stk, pci, 1);
@@ -1574,25 +1573,12 @@ do_fp_window(Client cntxt, MalBlkPtr mb,
*res = *in;
break;
default:
- throw(SQL, op, SQLSTATE(42000) "%s not
available for %s", op, ATOMname(tpe));
+ throw(SQL, "sql.avg", SQLSTATE(42000) "sql.avg
not available for %s", ATOMname(tpe));
}
}
return msg;
}
-str
-SQLavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
-{
- return do_fp_window(cntxt, mb, stk, pci, "sql.avg", SQLSTATE(42000)
"avg(:any_1,:lng,:lng)", GDKanalyticalavg);
-}
-
-str
-SQLmedian_avg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
-{
- return do_fp_window(cntxt, mb, stk, pci, "sql.median_avg",
SQLSTATE(42000) "median_avg(:any_1,:lng,:lng)",
- GDKanalytical_median_avg);
-}
-
static str
do_stddev_and_variance(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci, const char* op, const char* err,
gdk_return (*func)(BAT *, BAT *, BAT
*, BAT *, int))
@@ -1668,6 +1654,106 @@ SQLvar_pop(Client cntxt, MalBlkPtr mb, M
GDKanalytical_variance_pop);
}
+#define QUANTILE_SINGLE_IMP(TPE) \
+ do { \
+ TPE val = *(TPE*) VALget(qua), *toset; \
+ if (!VALisnil(qua) && (val > 1.0f || val < 0.0f)) \
+ throw(SQL, op, SQLSTATE(42000) "quantile value must be
in range [0,1]"); \
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list