Changeset: c35b4bedb174 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c35b4bedb174 Modified Files: sql/backends/monet5/UDF/udf.c sql/backends/monet5/UDF/udf.h sql/backends/monet5/UDF/udf.mal Branch: arrays Log Message:
qr c udf diffs (186 lines): diff --git a/sql/backends/monet5/UDF/udf.c b/sql/backends/monet5/UDF/udf.c --- a/sql/backends/monet5/UDF/udf.c +++ b/sql/backends/monet5/UDF/udf.c @@ -114,7 +114,7 @@ UDFBATreverse_(BAT **ret, BAT *src) assert(tr != NULL); /* append reversed tail in result BAT */ - BUNappend(bn, tr, FALSE); + BUNappend(bn, tr, FALSE); /* free memory allocated in UDFreverse_() */ GDKfree(tr); @@ -407,24 +407,133 @@ char* UDFqrq(bat *q, const bat *c, const return MAL_SUCCEED; } -char* fotini1UDF(double *ret1, double *in1, double *in2) { - if(*in1 > *in2) { - *ret1 = *in1; - } else { - *ret1=*in2; +static double computeR(BAT *col) { + BATiter col_iter = bat_iterator(col); + BUN start = BUNfirst(col); + BUN last = BUNlast(col); + BUN i; + double s = 0.0; + + for(i=start; i<last; i++) { + double val = *(double*)BUNtail(col_iter, i); + s += val*val; } - return MAL_SUCCEED; + return sqrt(s); } -char* fotini2UDF(double *ret1, double *ret2, double *in1, double *in2) { - if(*in1 > *in2) { - *ret1 = *in1; - *ret2 = *in2; - } else { - *ret1=*in2; - *ret2 = *in1; +static double computeR2(BAT *col, BAT *q) { + BATiter col_iter = bat_iterator(col); + BATiter q_iter = bat_iterator(q); + BUN start = BUNfirst(col); + BUN last = BUNlast(col); + BUN i; + double s = 0.0; + + for(i=start; i<last; i++) { + s += (*(double*)BUNtail(col_iter, i))*(*(double*)BUNtail(q_iter, i)); } - return MAL_SUCCEED; + return s; } + +static BAT* setQ(BAT *col, double r) { + BATiter col_iter = bat_iterator(col); + double *vals; + BUN i, start, end; + + BAT *q = BATnew(TYPE_void, TYPE_dbl, 0, TRANSIENT); + if(!q) + return NULL; + + start = BUNfirst(col); + end = BUNlast(col); + vals = (double*)Tloc(q, BUNfirst(q)); + + for(i=start; i<end; i++) { + double val = *(double*)BUNtail(col_iter, i); + *(vals++) = val/r; + } + + BATsetcount(q, BATcount(col)); + BATseqbase(q, col->hseqbase); + q->trevsorted = q->tsorted = 0; + q->tkey = 0; + q->T->nil = 1; + q->T->nonil = 0; + return q; +} + +static BAT* updateCol(BAT *col, double r, BAT* q) { + double *colVals, *qVals; + oid i; + + colVals = (double*)Tloc(col, BUNfirst(col)); + qVals = (double*)Tloc(q, BUNfirst(q)); + + for(i=0; i<BATcount(col); i++) { + colVals[i] -= r*qVals[i]; + } + + return col; +} + +char* qrUDF_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { + /* iterate over tha columns */ + int colNum =0; + int colsNum = pci->argc-pci->retc; + /* we need to update the column without destroying the original relation */ + BAT **cols_copy= (BAT**)malloc(sizeof(BAT*)*colsNum); + + (void)cntxt; + (void)mb; + + /* copy the columns */ + for(colNum=0; colNum<colsNum; colNum++) { + BAT *col = BATdescriptor(*getArgReference_bat(stk, pci, colNum+pci->retc)); + if (col == NULL) { + int i; + for(i=0; i<colNum; i++) + BBPunfix(cols_copy[colNum]->batCacheid); + return createException(MAL, "udf.qr", MAL_MALLOC_FAIL); + } + + cols_copy[colNum] = BATcopy(col, TYPE_void, BATttype(col), FALSE, TRANSIENT); + if (cols_copy[colNum] == NULL) { + int i; + for(i=0; i<=colNum; i++) + BBPunfix(cols_copy[colNum]->batCacheid); + return createException(MAL, "udf.qr", "BATcopy error"); + } + } + + /* process the columns */ + for(colNum=0 ; colNum<colsNum ; colNum++) { + int colNum2 =0 ; + BAT *col = cols_copy[colNum]; + double s = computeR(col); + bat *res = getArgReference_bat(stk, pci, colNum); + BAT *q = setQ(col,s); + + if(q == NULL) { + int i; + for(i=0; i<colsNum; i++) + BBPunfix(cols_copy[i]->batCacheid); + //TODO: clean res also + return createException(MAL, "udf.qr", "Problem in setQ"); + } + + /* update the other columns */ + for(colNum2 = colNum+1; colNum2<colsNum; colNum2++) { + s = computeR2(cols_copy[colNum2], q); + cols_copy[colNum2] = updateCol(cols_copy[colNum2], s, q); + } + + BBPkeepref(*res = q->batCacheid); + } + + for(colNum=0; colNum<colsNum; colNum++) + BBPunfix(cols_copy[colNum]->batCacheid); + + return MAL_SUCCEED; +} diff --git a/sql/backends/monet5/UDF/udf.h b/sql/backends/monet5/UDF/udf.h --- a/sql/backends/monet5/UDF/udf.h +++ b/sql/backends/monet5/UDF/udf.h @@ -46,6 +46,5 @@ udf_export char * UDFBATfuse(bat *ret, c udf_export char* UDFqrq(bat *q, const bat *c, const double *s); -udf_export char* fotini1UDF(double *ret1, double *in1, double *in2); -udf_export char* fotini2UDF(double *ret1, double *ret2, double *in1, double *in2); +udf_export char* qrUDF_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci); #endif /* _SQL_UDF_H_ */ diff --git a/sql/backends/monet5/UDF/udf.mal b/sql/backends/monet5/UDF/udf.mal --- a/sql/backends/monet5/UDF/udf.mal +++ b/sql/backends/monet5/UDF/udf.mal @@ -55,9 +55,7 @@ comment "fuse two (4-byte) int values in command batudf.qrq(c:bat[:oid,:dbl], s:dbl) :bat[:oid,:dbl] address UDFqrq; +pattern qr(c1:bat[:oid,:dbl]...) (:bat[:oid,:dbl]...) +address qrUDF_bulk; -command udf.fotini1(c1:dbl, c2:dbl) :dbl -address fotini1UDF; -command udf.fotinii2(c1:dbl, c2:dbl) (:dbl,:dbl) -address fotini2UDF; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list