| Line 429... |
Line 429... |
| 429 |
* from sdf_data". */
|
429 |
* from sdf_data". */
|
| 430 |
static long double g_accumulator = 0.0; /* accumulator var for cumsum, cumprod, etc. */
|
430 |
static long double g_accumulator = 0.0; /* accumulator var for cumsum, cumprod, etc. */
|
| 431 |
static int g_start = 0; /* flag for start of cummulation */
|
431 |
static int g_start = 0; /* flag for start of cummulation */
|
| 432 |
static int g_narm = 0; /* for Summary group */
|
432 |
static int g_narm = 0; /* for Summary group */
|
| 433 |
|
433 |
|
| 434 |
SEXP sdf_do_variable_math(SEXP func, SEXP vector, SEXP extra_args, SEXP _nargs) {
|
434 |
SEXP sdf_do_variable_math(SEXP func, SEXP vector, SEXP other_args) {
|
| 435 |
char *iname, *iname_src, *varname_src, *funcname;
|
435 |
char *iname, *iname_src, *varname_src, *funcname;
|
| 436 |
int namelen, res, nargs;
|
436 |
int namelen, res;
|
| 437 |
sqlite3_stmt *stmt;
|
437 |
sqlite3_stmt *stmt;
|
| 438 |
|
438 |
|
| 439 |
/* get data from arguments (function name and sqlite.vector stuffs) */
|
439 |
/* get data from arguments (function name and sqlite.vector stuffs) */
|
| 440 |
funcname = CHAR_ELT(func, 0);
|
440 |
funcname = CHAR_ELT(func, 0);
|
| 441 |
iname_src = SDF_INAME(vector);
|
441 |
iname_src = SDF_INAME(vector);
|
| 442 |
varname_src = SVEC_VARNAME(vector);
|
442 |
varname_src = SVEC_VARNAME(vector);
|
| 443 |
nargs = INTEGER(_nargs)[0];
|
- |
|
| 444 |
|
443 |
|
| 445 |
if (!USE_SDF1(iname_src, TRUE, TRUE)) return R_NilValue;
|
444 |
if (!USE_SDF1(iname_src, TRUE, TRUE)) return R_NilValue;
|
| 446 |
|
445 |
|
| 447 |
/* check nargs */
|
- |
|
| 448 |
if (nargs > 2) {
|
- |
|
| 449 |
Rprintf("Error: Don't know how to handle Math functions w/ more than 2 args\n");
|
- |
|
| 450 |
return R_NilValue;
|
- |
|
| 451 |
}
|
- |
|
| 452 |
|
- |
|
| 453 |
/* create a new sdf, with 1 column named V1 */
|
446 |
/* create a new sdf, with 1 column named V1 */
|
| 454 |
iname = _create_svector1(R_NilValue, "double", &namelen, TRUE);
|
447 |
iname = _create_svector1(R_NilValue, "double", &namelen, TRUE);
|
| 455 |
|
448 |
|
| 456 |
/* insert into <newsdf>.col, row.names select func(col), rownames */
|
449 |
/* insert into <newsdf>.col, row.names select func(col), rownames */
|
| - |
|
450 |
if (strcmp(funcname, "round") == 0 || strcmp(funcname, "signif") == 0) {
|
| - |
|
451 |
double digits = REAL(_getListElement(other_args, "digits"))[0];
|
| - |
|
452 |
sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
|
| - |
|
453 |
"select [row name], %s([%s],?) from [%s].sdf_data", iname, funcname,
|
| - |
|
454 |
varname_src, iname_src);
|
| - |
|
455 |
res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
|
| - |
|
456 |
if (_sqlite_error(res)) goto vecmath_prepare_error;
|
| - |
|
457 |
res = sqlite3_bind_double(stmt, 1, digits);
|
| - |
|
458 |
} else if (strcmp(funcname, "log") == 0) {
|
| - |
|
459 |
double base = REAL(_getListElement(other_args, "base"))[0];
|
| - |
|
460 |
sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
|
| - |
|
461 |
"select [row name], %s([%s],?) from [%s].sdf_data", iname, funcname,
|
| - |
|
462 |
varname_src, iname_src);
|
| - |
|
463 |
res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
|
| - |
|
464 |
if (_sqlite_error(res)) goto vecmath_prepare_error;
|
| - |
|
465 |
res = sqlite3_bind_double(stmt, 1, base);
|
| - |
|
466 |
} else {
|
| 457 |
sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
|
467 |
sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
|
| 458 |
"select [row name], %s([%s]) from [%s].sdf_data", iname, funcname,
|
468 |
"select [row name], %s([%s]) from [%s].sdf_data", iname, funcname,
|
| 459 |
varname_src, iname_src);
|
469 |
varname_src, iname_src);
|
| 460 |
|
- |
|
| 461 |
res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
|
470 |
res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
|
| - |
|
471 |
}
|
| - |
|
472 |
|
| 462 |
if (_sqlite_error(res)) {
|
473 |
if (_sqlite_error(res)) {
|
| - |
|
474 |
vecmath_prepare_error:
|
| 463 |
sprintf(g_sql_buf[0], "detach %s", iname);
|
475 |
sprintf(g_sql_buf[0], "detach %s", iname);
|
| 464 |
_sqlite_exec(g_sql_buf[0]);
|
476 |
_sqlite_exec(g_sql_buf[0]);
|
| 465 |
|
477 |
|
| 466 |
/* we will return a string with the file name, and do file.remove
|
478 |
/* we will return a string with the file name, and do file.remove
|
| 467 |
* at R */
|
479 |
* at R */
|
| Line 478... |
Line 490... |
| 478 |
UNUSE_SDF2(iname_src);
|
490 |
UNUSE_SDF2(iname_src);
|
| 479 |
|
491 |
|
| 480 |
return _create_svector_sexp(iname, "V1", "numeric");
|
492 |
return _create_svector_sexp(iname, "V1", "numeric");
|
| 481 |
}
|
493 |
}
|
| 482 |
|
494 |
|
| 483 |
SEXP sdf_do_variable_op(SEXP func, SEXP vector, SEXP op2) {
|
495 |
SEXP sdf_do_variable_op(SEXP func, SEXP vector, SEXP op2, SEXP arg_reversed) {
|
| 484 |
char *iname = NULL, *iname_src, *varname_src, *funcname;
|
496 |
char *iname = NULL, *iname_src, *varname_src, *funcname;
|
| 485 |
int res, functype = -1, op2_len, svec_len, i;
|
497 |
int res, functype = -1, op2_len, svec_len, i, reversed;
|
| 486 |
sqlite3_stmt *stmt, *stmt2;
|
498 |
sqlite3_stmt *stmt, *stmt2;
|
| 487 |
|
499 |
|
| 488 |
/* get data from arguments (function name and sqlite.vector stuffs) */
|
500 |
/* get data from arguments (function name and sqlite.vector stuffs) */
|
| 489 |
funcname = CHAR_ELT(func, 0);
|
501 |
funcname = CHAR_ELT(func, 0);
|
| 490 |
iname_src = SDF_INAME(vector);
|
502 |
iname_src = SDF_INAME(vector);
|
| 491 |
varname_src = SVEC_VARNAME(vector);
|
503 |
varname_src = SVEC_VARNAME(vector);
|
| - |
|
504 |
reversed = LOGICAL(arg_reversed)[0];
|
| 492 |
|
505 |
|
| 493 |
if (!USE_SDF1(iname_src, TRUE, TRUE)) return R_NilValue;
|
506 |
if (!USE_SDF1(iname_src, TRUE, TRUE)) return R_NilValue;
|
| 494 |
switch(funcname[0]) {
|
507 |
switch(funcname[0]) {
|
| 495 |
case '+' :
|
508 |
case '+' :
|
| 496 |
case '-' :
|
509 |
case '-' :
|
| Line 511... |
Line 524... |
| 511 |
|
524 |
|
| 512 |
svec_len = _get_row_count2(iname_src, 1);
|
525 |
svec_len = _get_row_count2(iname_src, 1);
|
| 513 |
if (functype == 0 || functype == 2 || (functype == 1 && funcname[0] != '!')) {
|
526 |
if (functype == 0 || functype == 2 || (functype == 1 && funcname[0] != '!')) {
|
| 514 |
char *insert_fmt_string1c, *insert_fmt_string1s;
|
527 |
char *insert_fmt_string1c, *insert_fmt_string1s;
|
| 515 |
char *insert_fmt_string2c, *insert_fmt_string2s;
|
528 |
char *insert_fmt_string2c, *insert_fmt_string2s;
|
| - |
|
529 |
int vec_idx, sdf_idx;
|
| - |
|
530 |
|
| 516 |
iname = _create_svector1(R_NilValue, (functype == 0) ? "double" : "bit", NULL, TRUE);
|
531 |
iname = _create_svector1(R_NilValue, (functype == 0) ? "double" : "bit", NULL, TRUE);
|
| 517 |
|
532 |
|
| - |
|
533 |
/* insert_fmt_string prefixes:
|
| - |
|
534 |
* 1 - op2 is an ordinary vector, op2_len = 1, straightforward insert-select
|
| - |
|
535 |
* 2 - op2 is an ordinary vector, op2_len > 1, may need recycling, loop both sides
|
| - |
|
536 |
* s - operator will be printed as string
|
| - |
|
537 |
* c - operator is either INTDIV or RMOD (int division, R modulo). initially, I
|
| - |
|
538 |
* thought I could cast both op to int then use / and % of sqlite, which is just
|
| - |
|
539 |
* the 2nd character of the funcname. however, R's INTDIV and casts to int
|
| - |
|
540 |
* after division (e.g. 3.5 %/% 1.5 == 2). RMOD operates on doubles too,
|
| - |
|
541 |
* which is the remainder of the largest int multiple of "divisor"
|
| - |
|
542 |
* (e.g. 3.5 %% 1.5 = 0.5)
|
| - |
|
543 |
*/
|
| 518 |
if (functype == 1) { /* boolean binary operators */
|
544 |
if (functype == 1) { /* boolean binary operators */
|
| - |
|
545 |
if (!reversed) {
|
| 519 |
insert_fmt_string1s = "insert into [%s].sdf_data "
|
546 |
insert_fmt_string1s = "insert into [%s].sdf_data "
|
| 520 |
"select [row name], ([%s] != 0) %s (? != 0) from [%s].sdf_data";
|
547 |
"select [row name], ([%s] != 0) %s (? != 0) from [%s].sdf_data";
|
| - |
|
548 |
} else {
|
| - |
|
549 |
insert_fmt_string1s = "insert into [%s].sdf_data "
|
| - |
|
550 |
"select [row name], (? != 0) %s ([%s] != 0) from [%s].sdf_data";
|
| - |
|
551 |
}
|
| 521 |
insert_fmt_string2s = "insert into [%s].sdf_data values(?, (? != 0) %s (? != 0))";
|
552 |
insert_fmt_string2s = "insert into [%s].sdf_data values(?, (? != 0) %s (? != 0))";
|
| 522 |
/* no need for char version of fmt_string2, since %% only occurs for functype==0 */
|
553 |
/* no need for char version of fmt_string2, since %% only occurs for functype==0 */
|
| 523 |
insert_fmt_string1c = insert_fmt_string1s;
|
554 |
insert_fmt_string1c = insert_fmt_string1s;
|
| 524 |
insert_fmt_string2c = insert_fmt_string2s;
|
555 |
insert_fmt_string2c = insert_fmt_string2s;
|
| 525 |
} else {
|
556 |
} else {
|
| - |
|
557 |
if (!reversed) {
|
| 526 |
insert_fmt_string1s = "insert into [%s].sdf_data "
|
558 |
insert_fmt_string1s = "insert into [%s].sdf_data "
|
| 527 |
"select [row name], [%s] %s ? from [%s].sdf_data";
|
559 |
"select [row name], [%s] %s ? from [%s].sdf_data";
|
| 528 |
insert_fmt_string1c = "insert into [%s].sdf_data "
|
560 |
insert_fmt_string1c = "insert into [%s].sdf_data "
|
| 529 |
"select [row name], [%s] %c ? from [%s].sdf_data";
|
561 |
"select [row name], %s([%s],?) from [%s].sdf_data";
|
| - |
|
562 |
} else {
|
| - |
|
563 |
insert_fmt_string1s = "insert into [%s].sdf_data "
|
| - |
|
564 |
"select [row name], ? %s [%s] from [%s].sdf_data";
|
| - |
|
565 |
insert_fmt_string1c = "insert into [%s].sdf_data "
|
| - |
|
566 |
"select [row name], %s(?,[%s]) from [%s].sdf_data";
|
| - |
|
567 |
}
|
| 530 |
/* fmt_string2c format operator from a char, used for %% and %/% */
|
568 |
/* fmt_string2c format operator from a char, used for %% and %/% */
|
| 531 |
/* BUG: i'm casting to int before applying / & %, w/c is different
|
- |
|
| 532 |
* from R. added trunc to pass package test */
|
- |
|
| 533 |
insert_fmt_string2c = "insert into [%s].sdf_data values(?, trunc(? %c ?))";
|
569 |
insert_fmt_string2c = "insert into [%s].sdf_data values(?, %s(?,?))";
|
| 534 |
insert_fmt_string2s = "insert into [%s].sdf_data values(?, ? %s ?)";
|
570 |
insert_fmt_string2s = "insert into [%s].sdf_data values(?, ? %s ?)";
|
| 535 |
}
|
571 |
}
|
| 536 |
|
572 |
|
| - |
|
573 |
/* for 2* insert statements, the values below specifies the index of bind().
|
| - |
|
574 |
* if !reversed, then e1 is svec, e2 is anything. otherwise, e2 is the svec */
|
| - |
|
575 |
if (reversed) { sdf_idx = 3; vec_idx = 2; }
|
| - |
|
576 |
else { sdf_idx = 2; vec_idx = 3; }
|
| 537 |
|
577 |
|
| 538 |
if (IS_NUMERIC(op2)) {
|
578 |
if (IS_NUMERIC(op2)) {
|
| 539 |
op2_len = LENGTH(op2);
|
579 |
op2_len = LENGTH(op2);
|
| 540 |
|
580 |
|
| 541 |
if (op2_len == 1) {
|
581 |
if (op2_len == 1) {
|
| 542 |
if (funcname[0] == '%') {
|
582 |
if (funcname[0] == '%') {
|
| 543 |
sprintf(g_sql_buf[2], insert_fmt_string1c, iname,
|
583 |
sprintf(g_sql_buf[2], insert_fmt_string1c, iname,
|
| 544 |
varname_src, funcname[1], iname_src);
|
584 |
(funcname[1] == '%') ? "r_mod" : "r_intdiv", varname_src, iname_src);
|
| 545 |
} else {
|
585 |
} else {
|
| 546 |
sprintf(g_sql_buf[2], insert_fmt_string1s, iname,
|
586 |
sprintf(g_sql_buf[2], insert_fmt_string1s, iname,
|
| 547 |
varname_src, funcname, iname_src);
|
587 |
varname_src, funcname, iname_src);
|
| 548 |
}
|
588 |
}
|
| 549 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
589 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| Line 556... |
Line 596... |
| 556 |
varname_src, iname_src);
|
596 |
varname_src, iname_src);
|
| 557 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
|
597 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt2, 0);
|
| 558 |
_sqlite_error(res);
|
598 |
_sqlite_error(res);
|
| 559 |
|
599 |
|
| 560 |
if (funcname[0] == '%') {
|
600 |
if (funcname[0] == '%') {
|
| 561 |
/* sqlite does int div with "/" if both args are int. mod is % also.
|
601 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname,
|
| 562 |
* fortunately, in both cases the sqlite op is 2nd char of funcname */
|
- |
|
| 563 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname, funcname[1]);
|
602 |
(funcname[1] == '%') ? "r_mod" : "r_intdiv");
|
| 564 |
_sqlite_begin;
|
603 |
_sqlite_begin;
|
| 565 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
604 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| 566 |
_sqlite_error(res);
|
605 |
_sqlite_error(res);
|
| 567 |
|
606 |
|
| 568 |
for (i = 0; i < svec_len; i++) {
|
607 |
for (i = 0; i < svec_len; i++) {
|
| 569 |
sqlite3_step(stmt2);
|
608 |
sqlite3_step(stmt2);
|
| 570 |
|
609 |
|
| 571 |
sqlite3_reset(stmt);
|
610 |
sqlite3_reset(stmt);
|
| 572 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
611 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
| 573 |
sqlite3_bind_int(stmt, 2, (int)sqlite3_column_double(stmt2, 1));
|
612 |
sqlite3_bind_int(stmt, sdf_idx, (int)sqlite3_column_double(stmt2, 1));
|
| 574 |
sqlite3_bind_int(stmt, 3, (int)REAL(op2)[i % op2_len]);
|
613 |
sqlite3_bind_int(stmt, vec_idx, (int)REAL(op2)[i % op2_len]);
|
| 575 |
sqlite3_step(stmt);
|
614 |
sqlite3_step(stmt);
|
| 576 |
}
|
615 |
}
|
| 577 |
sqlite3_finalize(stmt);
|
616 |
sqlite3_finalize(stmt);
|
| 578 |
sqlite3_finalize(stmt2);
|
617 |
sqlite3_finalize(stmt2);
|
| 579 |
_sqlite_commit;
|
618 |
_sqlite_commit;
|
| Line 586... |
Line 625... |
| 586 |
for (i = 0; i < svec_len; i++) {
|
625 |
for (i = 0; i < svec_len; i++) {
|
| 587 |
sqlite3_step(stmt2);
|
626 |
sqlite3_step(stmt2);
|
| 588 |
|
627 |
|
| 589 |
sqlite3_reset(stmt);
|
628 |
sqlite3_reset(stmt);
|
| 590 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
629 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
| 591 |
sqlite3_bind_double(stmt, 2, sqlite3_column_double(stmt2, 1));
|
630 |
sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
|
| 592 |
sqlite3_bind_double(stmt, 3, REAL(op2)[i % op2_len]);
|
631 |
sqlite3_bind_double(stmt, vec_idx, REAL(op2)[i % op2_len]);
|
| 593 |
sqlite3_step(stmt);
|
632 |
sqlite3_step(stmt);
|
| 594 |
}
|
633 |
}
|
| 595 |
sqlite3_finalize(stmt);
|
634 |
sqlite3_finalize(stmt);
|
| 596 |
sqlite3_finalize(stmt2);
|
635 |
sqlite3_finalize(stmt2);
|
| 597 |
_sqlite_commit;
|
636 |
_sqlite_commit;
|
| Line 599... |
Line 638... |
| 599 |
} else { /* op2_len > svec_len, recycle svec */
|
638 |
} else { /* op2_len > svec_len, recycle svec */
|
| 600 |
sprintf(g_sql_buf[1], "select [%s] from [%s].sdf_data",
|
639 |
sprintf(g_sql_buf[1], "select [%s] from [%s].sdf_data",
|
| 601 |
varname_src, iname_src);
|
640 |
varname_src, iname_src);
|
| 602 |
|
641 |
|
| 603 |
if (funcname[0] == '%') {
|
642 |
if (funcname[0] == '%') {
|
| 604 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname, funcname[1]);
|
643 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname,
|
| - |
|
644 |
(funcname[1] == '%') ? "r_mod" : "r_intdiv");
|
| 605 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
645 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| 606 |
_sqlite_error(res);
|
646 |
_sqlite_error(res);
|
| 607 |
} else {
|
647 |
} else {
|
| 608 |
sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
|
648 |
sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
|
| 609 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
649 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| Line 621... |
Line 661... |
| 621 |
|
661 |
|
| 622 |
sqlite3_reset(stmt);
|
662 |
sqlite3_reset(stmt);
|
| 623 |
/* simplify my life, just use ints for row names so that we
|
663 |
/* simplify my life, just use ints for row names so that we
|
| 624 |
* don't have to worry about duplicates */
|
664 |
* don't have to worry about duplicates */
|
| 625 |
sqlite3_bind_int(stmt, 1, i);
|
665 |
sqlite3_bind_int(stmt, 1, i);
|
| 626 |
sqlite3_bind_int(stmt, 2, sqlite3_column_int(stmt2, 1));
|
666 |
sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 1));
|
| 627 |
sqlite3_bind_int(stmt, 3, (int)REAL(op2)[i % op2_len]);
|
667 |
sqlite3_bind_int(stmt, vec_idx, (int)REAL(op2)[i % op2_len]);
|
| 628 |
sqlite3_step(stmt);
|
668 |
sqlite3_step(stmt);
|
| 629 |
}
|
669 |
}
|
| 630 |
} else {
|
670 |
} else {
|
| 631 |
for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
|
671 |
for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
|
| 632 |
sqlite3_step(stmt2);
|
672 |
sqlite3_step(stmt2);
|
| 633 |
|
673 |
|
| 634 |
sqlite3_reset(stmt);
|
674 |
sqlite3_reset(stmt);
|
| 635 |
sqlite3_bind_int(stmt, 1, i);
|
675 |
sqlite3_bind_int(stmt, 1, i);
|
| 636 |
sqlite3_bind_double(stmt, 2, sqlite3_column_double(stmt2, 1));
|
676 |
sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
|
| 637 |
sqlite3_bind_double(stmt, 3, REAL(op2)[i % op2_len]);
|
677 |
sqlite3_bind_double(stmt, vec_idx, REAL(op2)[i % op2_len]);
|
| 638 |
sqlite3_step(stmt);
|
678 |
sqlite3_step(stmt);
|
| 639 |
}
|
679 |
}
|
| 640 |
}
|
680 |
}
|
| 641 |
|
681 |
|
| 642 |
/* recycle on svec if we loop again */
|
682 |
/* recycle on svec if we loop again */
|
| Line 653... |
Line 693... |
| 653 |
op2_len = LENGTH(op2);
|
693 |
op2_len = LENGTH(op2);
|
| 654 |
|
694 |
|
| 655 |
if (op2_len == 1) {
|
695 |
if (op2_len == 1) {
|
| 656 |
if (funcname[0] == '%') {
|
696 |
if (funcname[0] == '%') {
|
| 657 |
sprintf(g_sql_buf[2], insert_fmt_string1c, iname,
|
697 |
sprintf(g_sql_buf[2], insert_fmt_string1c, iname,
|
| 658 |
varname_src, funcname[1], iname_src);
|
698 |
varname_src, (funcname[1] == '%') ? "r_mod" : "r_intdiv", iname_src);
|
| 659 |
} else {
|
699 |
} else {
|
| 660 |
sprintf(g_sql_buf[2], insert_fmt_string1s, iname,
|
700 |
sprintf(g_sql_buf[2], insert_fmt_string1s, iname,
|
| 661 |
varname_src, funcname, iname_src);
|
701 |
varname_src, funcname, iname_src);
|
| 662 |
}
|
702 |
}
|
| 663 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
703 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| Line 671... |
Line 711... |
| 671 |
_sqlite_error(res);
|
711 |
_sqlite_error(res);
|
| 672 |
|
712 |
|
| 673 |
if (funcname[0] == '%') {
|
713 |
if (funcname[0] == '%') {
|
| 674 |
/* sqlite does int div with "/" if both args are int. mod is % also.
|
714 |
/* sqlite does int div with "/" if both args are int. mod is % also.
|
| 675 |
* fortunately, in both cases the sqlite op is 2nd char of funcname */
|
715 |
* fortunately, in both cases the sqlite op is 2nd char of funcname */
|
| 676 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname, funcname[1]);
|
716 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname,
|
| - |
|
717 |
(funcname[1] == '%') ? "r_mod" : "r_intdiv");
|
| 677 |
_sqlite_begin;
|
718 |
_sqlite_begin;
|
| 678 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
719 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| 679 |
_sqlite_error(res);
|
720 |
_sqlite_error(res);
|
| 680 |
|
721 |
|
| 681 |
for (i = 0; i < svec_len; i++) {
|
722 |
for (i = 0; i < svec_len; i++) {
|
| 682 |
sqlite3_step(stmt2);
|
723 |
sqlite3_step(stmt2);
|
| 683 |
|
724 |
|
| 684 |
sqlite3_reset(stmt);
|
725 |
sqlite3_reset(stmt);
|
| 685 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
726 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
| 686 |
sqlite3_bind_int(stmt, 2, sqlite3_column_int(stmt2, 1));
|
727 |
sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 1));
|
| 687 |
sqlite3_bind_int(stmt, 3, INTEGER(op2)[i % op2_len]);
|
728 |
sqlite3_bind_int(stmt, vec_idx, INTEGER(op2)[i % op2_len]);
|
| 688 |
sqlite3_step(stmt);
|
729 |
sqlite3_step(stmt);
|
| 689 |
}
|
730 |
}
|
| 690 |
_sqlite_commit;
|
731 |
_sqlite_commit;
|
| 691 |
} else {
|
732 |
} else {
|
| 692 |
sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
|
733 |
sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
|
| Line 697... |
Line 738... |
| 697 |
for (i = 0; i < svec_len; i++) {
|
738 |
for (i = 0; i < svec_len; i++) {
|
| 698 |
sqlite3_step(stmt2);
|
739 |
sqlite3_step(stmt2);
|
| 699 |
|
740 |
|
| 700 |
sqlite3_reset(stmt);
|
741 |
sqlite3_reset(stmt);
|
| 701 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
742 |
sqlite3_bind_text(stmt, 1, (char *)sqlite3_column_text(stmt2, 0), -1, SQLITE_STATIC);
|
| 702 |
sqlite3_bind_double(stmt, 2, sqlite3_column_double(stmt2, 1));
|
743 |
sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
|
| 703 |
sqlite3_bind_double(stmt, 3, (double)INTEGER(op2)[i % op2_len]);
|
744 |
sqlite3_bind_double(stmt, vec_idx, (double)INTEGER(op2)[i % op2_len]);
|
| 704 |
sqlite3_step(stmt);
|
745 |
sqlite3_step(stmt);
|
| 705 |
}
|
746 |
}
|
| 706 |
_sqlite_commit;
|
747 |
_sqlite_commit;
|
| 707 |
}
|
748 |
}
|
| 708 |
sqlite3_finalize(stmt2);
|
749 |
sqlite3_finalize(stmt2);
|
| 709 |
} else {
|
750 |
} else {
|
| 710 |
sprintf(g_sql_buf[1], "select [%s] from [%s].sdf_data",
|
751 |
sprintf(g_sql_buf[1], "select [%s] from [%s].sdf_data",
|
| 711 |
varname_src, iname_src);
|
752 |
varname_src, iname_src);
|
| 712 |
|
753 |
|
| 713 |
if (funcname[0] == '%') {
|
754 |
if (funcname[0] == '%') {
|
| 714 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname, funcname[1]);
|
755 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname,
|
| - |
|
756 |
(funcname[1] == '%') ? "r_mod" : "r_intdiv");
|
| 715 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
757 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| 716 |
_sqlite_error(res);
|
758 |
_sqlite_error(res);
|
| 717 |
} else {
|
759 |
} else {
|
| 718 |
sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
|
760 |
sprintf(g_sql_buf[2], insert_fmt_string2s, iname, funcname);
|
| 719 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
761 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| Line 731... |
Line 773... |
| 731 |
|
773 |
|
| 732 |
sqlite3_reset(stmt);
|
774 |
sqlite3_reset(stmt);
|
| 733 |
/* simplify my life, just use ints for row names so that we
|
775 |
/* simplify my life, just use ints for row names so that we
|
| 734 |
* don't have to worry about duplicates */
|
776 |
* don't have to worry about duplicates */
|
| 735 |
sqlite3_bind_int(stmt, 1, i);
|
777 |
sqlite3_bind_int(stmt, 1, i);
|
| 736 |
sqlite3_bind_int(stmt, 2, sqlite3_column_int(stmt2, 1));
|
778 |
sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 1));
|
| 737 |
sqlite3_bind_int(stmt, 3, INTEGER(op2)[i % op2_len]);
|
779 |
sqlite3_bind_int(stmt, vec_idx, INTEGER(op2)[i % op2_len]);
|
| 738 |
sqlite3_step(stmt);
|
780 |
sqlite3_step(stmt);
|
| 739 |
}
|
781 |
}
|
| 740 |
} else {
|
782 |
} else {
|
| 741 |
for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
|
783 |
for ( ; i < op2_len && sqlite3_step(stmt) == SQLITE_ROW ; i++) {
|
| 742 |
sqlite3_step(stmt2);
|
784 |
sqlite3_step(stmt2);
|
| 743 |
|
785 |
|
| 744 |
sqlite3_reset(stmt);
|
786 |
sqlite3_reset(stmt);
|
| 745 |
sqlite3_bind_int(stmt, 1, i);
|
787 |
sqlite3_bind_int(stmt, 1, i);
|
| 746 |
sqlite3_bind_double(stmt, 2, sqlite3_column_double(stmt2, 1));
|
788 |
sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 1));
|
| 747 |
sqlite3_bind_double(stmt, 3, (double)INTEGER(op2)[i % op2_len]);
|
789 |
sqlite3_bind_double(stmt, vec_idx, (double)INTEGER(op2)[i % op2_len]);
|
| 748 |
sqlite3_step(stmt);
|
790 |
sqlite3_step(stmt);
|
| 749 |
}
|
791 |
}
|
| 750 |
}
|
792 |
}
|
| 751 |
|
793 |
|
| 752 |
/* recycle on svec if we loop again */
|
794 |
/* recycle on svec if we loop again */
|
| Line 756... |
Line 798... |
| 756 |
}
|
798 |
}
|
| 757 |
|
799 |
|
| 758 |
sqlite3_finalize(stmt);
|
800 |
sqlite3_finalize(stmt);
|
| 759 |
} else if (inherits(op2, "sqlite.vector")) {
|
801 |
} else if (inherits(op2, "sqlite.vector")) {
|
| 760 |
/* op2 is surely not a factor, as handled by the R wrapper */
|
802 |
/* op2 is surely not a factor, as handled by the R wrapper */
|
| - |
|
803 |
/* even though it is impossible for reversed to be FALSE, still use
|
| - |
|
804 |
* sdf_idx and vec_idx so that code would be less confusing */
|
| 761 |
char *iname_op2, *varname_op2;
|
805 |
char *iname_op2, *varname_op2;
|
| 762 |
sqlite3_stmt *stmt3;
|
806 |
sqlite3_stmt *stmt3;
|
| 763 |
iname_op2 = SDF_INAME(op2);
|
807 |
iname_op2 = SDF_INAME(op2);
|
| 764 |
varname_op2 = SVEC_VARNAME(op2);
|
808 |
varname_op2 = SVEC_VARNAME(op2);
|
| 765 |
|
809 |
|
| Line 780... |
Line 824... |
| 780 |
sprintf(g_sql_buf[2], "select [%s] from [%s].sdf_data", varname_op2, iname_op2);
|
824 |
sprintf(g_sql_buf[2], "select [%s] from [%s].sdf_data", varname_op2, iname_op2);
|
| 781 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt3, 0);
|
825 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt3, 0);
|
| 782 |
_sqlite_error(res);
|
826 |
_sqlite_error(res);
|
| 783 |
|
827 |
|
| 784 |
if (funcname[0] == '%') {
|
828 |
if (funcname[0] == '%') {
|
| 785 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname, funcname[1]);
|
829 |
sprintf(g_sql_buf[2], insert_fmt_string2c, iname,
|
| - |
|
830 |
(funcname[1] == '%') ? "r_mod" : "r_intdiv");
|
| 786 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
831 |
res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
|
| 787 |
_sqlite_error(res);
|
832 |
_sqlite_error(res);
|
| 788 |
|
833 |
|
| 789 |
if (svec_len == op2_len) {
|
834 |
if (svec_len == op2_len) {
|
| 790 |
for (i = 0; i < svec_len; i++) {
|
835 |
for (i = 0; i < svec_len; i++) {
|
| 791 |
sqlite3_step(stmt2); sqlite3_step(stmt3);
|
836 |
sqlite3_step(stmt2); sqlite3_step(stmt3);
|
| 792 |
|
837 |
|
| 793 |
sqlite3_reset(stmt);
|
838 |
sqlite3_reset(stmt);
|
| 794 |
sqlite3_bind_int(stmt, 1, i);
|
839 |
sqlite3_bind_int(stmt, 1, i);
|
| 795 |
sqlite3_bind_int(stmt, 2, sqlite3_column_int(stmt2, 0));
|
840 |
sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 0));
|
| 796 |
sqlite3_bind_int(stmt, 3, sqlite3_column_int(stmt3, 0));
|
841 |
sqlite3_bind_int(stmt, vec_idx, sqlite3_column_int(stmt3, 0));
|
| 797 |
sqlite3_step(stmt);
|
842 |
sqlite3_step(stmt);
|
| 798 |
}
|
843 |
}
|
| 799 |
} else if (svec_len < op2_len) {
|
844 |
} else if (svec_len < op2_len) {
|
| 800 |
i = 0;
|
845 |
i = 0;
|
| 801 |
while (i < op2_len) {
|
846 |
while (i < op2_len) {
|
| 802 |
for ( ; sqlite3_step(stmt2) == SQLITE_ROW && i < op2_len; i++) {
|
847 |
for ( ; sqlite3_step(stmt2) == SQLITE_ROW && i < op2_len; i++) {
|
| 803 |
sqlite3_step(stmt3);
|
848 |
sqlite3_step(stmt3);
|
| 804 |
|
849 |
|
| 805 |
sqlite3_reset(stmt);
|
850 |
sqlite3_reset(stmt);
|
| 806 |
sqlite3_bind_int(stmt, 1, i);
|
851 |
sqlite3_bind_int(stmt, 1, i);
|
| 807 |
sqlite3_bind_int(stmt, 2, sqlite3_column_int(stmt2, 0));
|
852 |
sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 0));
|
| 808 |
sqlite3_bind_int(stmt, 3, sqlite3_column_int(stmt3, 0));
|
853 |
sqlite3_bind_int(stmt, vec_idx, sqlite3_column_int(stmt3, 0));
|
| 809 |
sqlite3_step(stmt);
|
854 |
sqlite3_step(stmt);
|
| 810 |
}
|
855 |
}
|
| 811 |
sqlite3_reset(stmt2);
|
856 |
sqlite3_reset(stmt2);
|
| 812 |
}
|
857 |
}
|
| 813 |
} else {
|
858 |
} else {
|
| Line 816... |
Line 861... |
| 816 |
for ( ; sqlite3_step(stmt3) == SQLITE_ROW && i < svec_len; i++) {
|
861 |
for ( ; sqlite3_step(stmt3) == SQLITE_ROW && i < svec_len; i++) {
|
| 817 |
sqlite3_step(stmt2);
|
862 |
sqlite3_step(stmt2);
|
| 818 |
|
863 |
|
| 819 |
sqlite3_reset(stmt);
|
864 |
sqlite3_reset(stmt);
|
| 820 |
sqlite3_bind_int(stmt, 1, i);
|
865 |
sqlite3_bind_int(stmt, 1, i);
|
| 821 |
sqlite3_bind_int(stmt, 2, sqlite3_column_int(stmt2, 0));
|
866 |
sqlite3_bind_int(stmt, sdf_idx, sqlite3_column_int(stmt2, 0));
|
| 822 |
sqlite3_bind_int(stmt, 3, sqlite3_column_int(stmt3, 0));
|
867 |
sqlite3_bind_int(stmt, vec_idx, sqlite3_column_int(stmt3, 0));
|
| 823 |
sqlite3_step(stmt);
|
868 |
sqlite3_step(stmt);
|
| 824 |
}
|
869 |
}
|
| 825 |
sqlite3_reset(stmt3);
|
870 |
sqlite3_reset(stmt3);
|
| 826 |
}
|
871 |
}
|
| 827 |
}
|
872 |
}
|
| Line 835... |
Line 880... |
| 835 |
for (i = 0; i < svec_len; i++) {
|
880 |
for (i = 0; i < svec_len; i++) {
|
| 836 |
sqlite3_step(stmt2); sqlite3_step(stmt3);
|
881 |
sqlite3_step(stmt2); sqlite3_step(stmt3);
|
| 837 |
|
882 |
|
| 838 |
sqlite3_reset(stmt);
|
883 |
sqlite3_reset(stmt);
|
| 839 |
sqlite3_bind_int(stmt, 1, i);
|
884 |
sqlite3_bind_int(stmt, 1, i);
|
| 840 |
sqlite3_bind_double(stmt, 2, sqlite3_column_double(stmt2, 0));
|
885 |
sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 0));
|
| 841 |
sqlite3_bind_double(stmt, 3, sqlite3_column_double(stmt3, 0));
|
886 |
sqlite3_bind_double(stmt, vec_idx, sqlite3_column_double(stmt3, 0));
|
| 842 |
sqlite3_step(stmt);
|
887 |
sqlite3_step(stmt);
|
| 843 |
}
|
888 |
}
|
| 844 |
} else if (svec_len < op2_len) { /* recycle svec */
|
889 |
} else if (svec_len < op2_len) { /* recycle svec */
|
| 845 |
i = 0;
|
890 |
i = 0;
|
| 846 |
while (i < op2_len) {
|
891 |
while (i < op2_len) {
|
| 847 |
for ( ; sqlite3_step(stmt2) == SQLITE_ROW && i < op2_len; i++) {
|
892 |
for ( ; sqlite3_step(stmt2) == SQLITE_ROW && i < op2_len; i++) {
|
| 848 |
sqlite3_step(stmt3);
|
893 |
sqlite3_step(stmt3);
|
| 849 |
|
894 |
|
| 850 |
sqlite3_reset(stmt);
|
895 |
sqlite3_reset(stmt);
|
| 851 |
sqlite3_bind_int(stmt, 1, i);
|
896 |
sqlite3_bind_int(stmt, 1, i);
|
| 852 |
sqlite3_bind_double(stmt, 2, sqlite3_column_double(stmt2, 0));
|
897 |
sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 0));
|
| 853 |
sqlite3_bind_double(stmt, 3, sqlite3_column_double(stmt3, 0));
|
898 |
sqlite3_bind_double(stmt, vec_idx, sqlite3_column_double(stmt3, 0));
|
| 854 |
sqlite3_step(stmt);
|
899 |
sqlite3_step(stmt);
|
| 855 |
}
|
900 |
}
|
| 856 |
sqlite3_reset(stmt2);
|
901 |
sqlite3_reset(stmt2);
|
| 857 |
}
|
902 |
}
|
| 858 |
} else { /* svec_len > op2_len, recycle op2 */
|
903 |
} else { /* svec_len > op2_len, recycle op2 */
|
| Line 861... |
Line 906... |
| 861 |
for ( ; sqlite3_step(stmt3) == SQLITE_ROW && i < svec_len; i++) {
|
906 |
for ( ; sqlite3_step(stmt3) == SQLITE_ROW && i < svec_len; i++) {
|
| 862 |
sqlite3_step(stmt2);
|
907 |
sqlite3_step(stmt2);
|
| 863 |
|
908 |
|
| 864 |
sqlite3_reset(stmt);
|
909 |
sqlite3_reset(stmt);
|
| 865 |
sqlite3_bind_int(stmt, 1, i);
|
910 |
sqlite3_bind_int(stmt, 1, i);
|
| 866 |
sqlite3_bind_double(stmt, 2, sqlite3_column_double(stmt2, 0));
|
911 |
sqlite3_bind_double(stmt, sdf_idx, sqlite3_column_double(stmt2, 0));
|
| 867 |
sqlite3_bind_double(stmt, 3, sqlite3_column_double(stmt3, 0));
|
912 |
sqlite3_bind_double(stmt, vec_idx, sqlite3_column_double(stmt3, 0));
|
| 868 |
sqlite3_step(stmt);
|
913 |
sqlite3_step(stmt);
|
| 869 |
}
|
914 |
}
|
| 870 |
sqlite3_reset(stmt3);
|
915 |
sqlite3_reset(stmt3);
|
| 871 |
}
|
916 |
}
|
| 872 |
}
|
917 |
}
|
| Line 1010... |
Line 1055... |
| 1010 |
|
1055 |
|
| 1011 |
/****************************************************************************
|
1056 |
/****************************************************************************
|
| 1012 |
* VECTOR MATH/OPS/GROUP OPERATIONS
|
1057 |
* VECTOR MATH/OPS/GROUP OPERATIONS
|
| 1013 |
****************************************************************************/
|
1058 |
****************************************************************************/
|
| 1014 |
|
1059 |
|
| 1015 |
int __vecmath_checkarg(sqlite3_context *ctx, sqlite3_value *arg, double *value) {
|
1060 |
R_INLINE int __vecmath_checkarg(sqlite3_context *ctx, sqlite3_value *arg, double *value) {
|
| 1016 |
int ret = 1;
|
1061 |
int ret = 1;
|
| 1017 |
if (sqlite3_value_type(arg) == SQLITE_NULL) {
|
1062 |
if (sqlite3_value_type(arg) == SQLITE_NULL) {
|
| 1018 |
sqlite3_result_null(ctx);
|
1063 |
sqlite3_result_null(ctx);
|
| 1019 |
ret = 0;
|
1064 |
ret = 0;
|
| 1020 |
} else {
|
1065 |
} else {
|
| Line 1031... |
Line 1076... |
| 1031 |
if (__vecmath_checkarg(ctx, argv[0], &value)) { \
|
1076 |
if (__vecmath_checkarg(ctx, argv[0], &value)) { \
|
| 1032 |
sqlite3_result_double(ctx, func(value)); \
|
1077 |
sqlite3_result_double(ctx, func(value)); \
|
| 1033 |
} \
|
1078 |
} \
|
| 1034 |
}
|
1079 |
}
|
| 1035 |
|
1080 |
|
| - |
|
1081 |
#define SQLITE_MATH_FUNC2(name, func) static void __vecmath_ ## name(\
|
| - |
|
1082 |
sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
|
| - |
|
1083 |
double value1, value2; \
|
| - |
|
1084 |
if (__vecmath_checkarg(ctx, argv[0], &value1) && \
|
| - |
|
1085 |
__vecmath_checkarg(ctx, argv[1], &value2)) { \
|
| - |
|
1086 |
sqlite3_result_double(ctx, func((long double)value1, (long double)value2)); \
|
| - |
|
1087 |
} \
|
| - |
|
1088 |
}
|
| - |
|
1089 |
|
| 1036 |
#define SQLITE_MATH_FUNC_CUM(name, func) static void __vecmath_ ## name(\
|
1090 |
#define SQLITE_MATH_FUNC_CUM(name, func) static void __vecmath_ ## name(\
|
| 1037 |
sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
|
1091 |
sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
|
| 1038 |
double value; \
|
1092 |
double value; \
|
| 1039 |
if (__vecmath_checkarg(ctx, argv[0], &value)) { \
|
1093 |
if (__vecmath_checkarg(ctx, argv[0], &value)) { \
|
| 1040 |
if (g_start) { g_start = 0; g_accumulator = value; } \
|
1094 |
if (g_start) { g_start = 0; g_accumulator = value; } \
|
| 1041 |
else g_accumulator = func(g_accumulator, value); \
|
1095 |
else g_accumulator = func(g_accumulator, value); \
|
| 1042 |
sqlite3_result_double(ctx, g_accumulator); \
|
1096 |
sqlite3_result_double(ctx, g_accumulator); \
|
| 1043 |
} \
|
1097 |
} \
|
| 1044 |
}
|
1098 |
}
|
| 1045 |
|
1099 |
|
| - |
|
1100 |
#define LOGBASE(a, b) log(a)/log(b)
|
| - |
|
1101 |
|
| 1046 |
/* SQLITE_MATH_FUNC1(abs, abs) in SQLite */
|
1102 |
/* SQLITE_MATH_FUNC1(abs, abs) in SQLite */
|
| 1047 |
SQLITE_MATH_FUNC1(sign, sign) /* in R */
|
1103 |
SQLITE_MATH_FUNC1(sign, sign) /* in R */
|
| 1048 |
SQLITE_MATH_FUNC1(sqrt, sqrt)
|
1104 |
SQLITE_MATH_FUNC1(sqrt, sqrt)
|
| 1049 |
SQLITE_MATH_FUNC1(floor, floor)
|
1105 |
SQLITE_MATH_FUNC1(floor, floor)
|
| 1050 |
SQLITE_MATH_FUNC1(ceiling, ceil)
|
1106 |
SQLITE_MATH_FUNC1(ceiling, ceil)
|
| 1051 |
SQLITE_MATH_FUNC1(trunc, ftrunc) /* in R */
|
1107 |
SQLITE_MATH_FUNC1(trunc, ftrunc) /* in R */
|
| 1052 |
/* SQLITE_MATH_FUNC1(round, ) in SQLite */
|
1108 |
/*SQLITE_MATH_FUNC2(round, fprec) 2 arg, in SQLite, but override with R's version */
|
| 1053 |
/* SQLITE_MATH_FUNC1(signif, ) 2 arg */
|
1109 |
SQLITE_MATH_FUNC2(signif, fround) /* 2 arg, in R */
|
| 1054 |
SQLITE_MATH_FUNC1(exp, exp)
|
1110 |
SQLITE_MATH_FUNC1(exp, exp)
|
| 1055 |
/* SQLITE_MATH_FUNC1(log, ) 2 arg */
|
1111 |
SQLITE_MATH_FUNC2(log, LOGBASE) /* 2 arg */
|
| 1056 |
SQLITE_MATH_FUNC1(cos, cos)
|
1112 |
SQLITE_MATH_FUNC1(cos, cos)
|
| 1057 |
SQLITE_MATH_FUNC1(sin, sin)
|
1113 |
SQLITE_MATH_FUNC1(sin, sin)
|
| 1058 |
SQLITE_MATH_FUNC1(tan, tan)
|
1114 |
SQLITE_MATH_FUNC1(tan, tan)
|
| 1059 |
SQLITE_MATH_FUNC1(acos, acos)
|
1115 |
SQLITE_MATH_FUNC1(acos, acos)
|
| 1060 |
SQLITE_MATH_FUNC1(asin, asin)
|
1116 |
SQLITE_MATH_FUNC1(asin, asin)
|
| Line 1109... |
Line 1165... |
| 1109 |
static void __vecsummary_finalize(sqlite3_context *ctx) {
|
1165 |
static void __vecsummary_finalize(sqlite3_context *ctx) {
|
| 1110 |
/* g_accumulator already summarizes it. just return that */
|
1166 |
/* g_accumulator already summarizes it. just return that */
|
| 1111 |
sqlite3_result_double(ctx, g_accumulator);
|
1167 |
sqlite3_result_double(ctx, g_accumulator);
|
| 1112 |
}
|
1168 |
}
|
| 1113 |
|
1169 |
|
| - |
|
1170 |
static void __r_modulo(sqlite3_context *ctx, int argc, sqlite3_value **argv) {
|
| - |
|
1171 |
if (sqlite3_value_type(argv[0]) == SQLITE_NULL ||
|
| - |
|
1172 |
sqlite3_value_type(argv[1]) == SQLITE_NULL) {
|
| - |
|
1173 |
sqlite3_result_null(ctx);
|
| - |
|
1174 |
} else {
|
| - |
|
1175 |
double v1, v2, q, tmp;
|
| - |
|
1176 |
if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER &&
|
| - |
|
1177 |
sqlite3_value_type(argv[1]) == SQLITE_INTEGER) {
|
| - |
|
1178 |
int i1, i2;
|
| - |
|
1179 |
i1 = sqlite3_value_int(argv[0]);
|
| - |
|
1180 |
i2 = sqlite3_value_int(argv[1]);
|
| - |
|
1181 |
if (i1 > 0 && i2 > 0) {
|
| - |
|
1182 |
sqlite3_result_int(ctx, i1 % i2); return;
|
| - |
|
1183 |
}
|
| - |
|
1184 |
v1 = i1; v2 = i2;
|
| - |
|
1185 |
} else {
|
| - |
|
1186 |
v1 = sqlite3_value_double(argv[0]);
|
| - |
|
1187 |
v2 = sqlite3_value_double(argv[1]);
|
| - |
|
1188 |
}
|
| - |
|
1189 |
/* copied from myfmod() in src/main/arithmetic.c */
|
| - |
|
1190 |
q = v1 / v2;
|
| - |
|
1191 |
if (v2 == 0) sqlite3_result_double(ctx, R_NaN);
|
| - |
|
1192 |
tmp = v1 - floor(q) * v2;
|
| - |
|
1193 |
/* checking omitted */
|
| - |
|
1194 |
q = floor(tmp/v2);
|
| - |
|
1195 |
sqlite3_result_double(ctx, tmp - q*v2);
|
| - |
|
1196 |
|
| - |
|
1197 |
}
|
| - |
|
1198 |
}
|
| - |
|
1199 |
|
| - |
|
1200 |
static void __r_intdiv(sqlite3_context *ctx, int argc, sqlite3_value **argv) {
|
| - |
|
1201 |
if (sqlite3_value_type(argv[0]) == SQLITE_NULL ||
|
| - |
|
1202 |
sqlite3_value_type(argv[1]) == SQLITE_NULL) {
|
| - |
|
1203 |
sqlite3_result_null(ctx);
|
| - |
|
1204 |
} else {
|
| - |
|
1205 |
double v1, v2;
|
| - |
|
1206 |
if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER &&
|
| - |
|
1207 |
sqlite3_value_type(argv[1]) == SQLITE_INTEGER) {
|
| - |
|
1208 |
int i1, i2;
|
| - |
|
1209 |
i1 = sqlite3_value_int(argv[0]);
|
| - |
|
1210 |
i2 = sqlite3_value_int(argv[1]);
|
| - |
|
1211 |
if (i1 == NA_INTEGER || i2 == NA_INTEGER) {
|
| - |
|
1212 |
sqlite3_result_int(ctx, NA_INTEGER); return;
|
| - |
|
1213 |
} else if (i2 == 0) {
|
| - |
|
1214 |
sqlite3_result_int(ctx, 0); return;
|
| - |
|
1215 |
}
|
| - |
|
1216 |
v1 = i1; v2 = i2;
|
| - |
|
1217 |
} else {
|
| - |
|
1218 |
v1 = sqlite3_value_double(argv[0]);
|
| - |
|
1219 |
v2 = sqlite3_value_double(argv[1]);
|
| - |
|
1220 |
}
|
| - |
|
1221 |
/* copied from IDIVOP cases in src/main/arithmetic.c */
|
| - |
|
1222 |
sqlite3_result_double(ctx, floor(v1/v2));
|
| - |
|
1223 |
}
|
| - |
|
1224 |
}
|
| 1114 |
#define VMENTRY1(func) {#func, __vecmath_ ## func}
|
1225 |
#define VMENTRY1(func) {#func, __vecmath_ ## func}
|
| 1115 |
#define VSENTRY1(func) {#func, __vecsummary_ ## func}
|
1226 |
#define VSENTRY1(func) {#func, __vecsummary_ ## func}
|
| 1116 |
void __register_vector_math() {
|
1227 |
void __register_vector_math() {
|
| 1117 |
int i, res;
|
1228 |
int i, res;
|
| 1118 |
static const struct {
|
1229 |
static const struct {
|
| Line 1143... |
Line 1254... |
| 1143 |
VMENTRY1(trigamma),
|
1254 |
VMENTRY1(trigamma),
|
| 1144 |
VMENTRY1(cumsum),
|
1255 |
VMENTRY1(cumsum),
|
| 1145 |
VMENTRY1(cumprod),
|
1256 |
VMENTRY1(cumprod),
|
| 1146 |
VMENTRY1(cummin),
|
1257 |
VMENTRY1(cummin),
|
| 1147 |
VMENTRY1(cummax)
|
1258 |
VMENTRY1(cummax)
|
| - |
|
1259 |
}, arr_func2[] = {
|
| - |
|
1260 |
{"r_mod", __r_modulo},
|
| - |
|
1261 |
{"r_intdiv", __r_intdiv},
|
| - |
|
1262 |
/*VMENTRY1(round),*/
|
| - |
|
1263 |
VMENTRY1(signif),
|
| - |
|
1264 |
VMENTRY1(log)
|
| 1148 |
}, arr_sum1[] = {
|
1265 |
}, arr_sum1[] = {
|
| 1149 |
VSENTRY1(all_df), /* can't override sum, min, max */
|
1266 |
VSENTRY1(all_df), /* can't override sum, min, max */
|
| 1150 |
VSENTRY1(any_df),
|
1267 |
VSENTRY1(any_df),
|
| 1151 |
VSENTRY1(sum_df),
|
1268 |
VSENTRY1(sum_df),
|
| 1152 |
VSENTRY1(prod_df),
|
1269 |
VSENTRY1(prod_df),
|
| Line 1160... |
Line 1277... |
| 1160 |
res = sqlite3_create_function(g_workspace, arr_func1[i].name, 1,
|
1277 |
res = sqlite3_create_function(g_workspace, arr_func1[i].name, 1,
|
| 1161 |
SQLITE_ANY, NULL, arr_func1[i].func, NULL, NULL);
|
1278 |
SQLITE_ANY, NULL, arr_func1[i].func, NULL, NULL);
|
| 1162 |
_sqlite_error(res);
|
1279 |
_sqlite_error(res);
|
| 1163 |
}
|
1280 |
}
|
| 1164 |
|
1281 |
|
| - |
|
1282 |
len = sizeof(arr_func2) / sizeof(arr_func2[0]);
|
| - |
|
1283 |
for (i = 0; i < len; i++) {
|
| - |
|
1284 |
res = sqlite3_create_function(g_workspace, arr_func2[i].name, 2,
|
| - |
|
1285 |
SQLITE_ANY, NULL, arr_func2[i].func, NULL, NULL);
|
| - |
|
1286 |
_sqlite_error(res);
|
| - |
|
1287 |
}
|
| - |
|
1288 |
|
| 1165 |
len = sizeof(arr_sum1) / sizeof(arr_sum1[0]);
|
1289 |
len = sizeof(arr_sum1) / sizeof(arr_sum1[0]);
|
| 1166 |
for (i = 0; i < len; i++) {
|
1290 |
for (i = 0; i < len; i++) {
|
| 1167 |
res = sqlite3_create_function(g_workspace, arr_sum1[i].name, 1,
|
1291 |
res = sqlite3_create_function(g_workspace, arr_sum1[i].name, 1,
|
| 1168 |
SQLITE_ANY, NULL, NULL, arr_sum1[i].func, __vecsummary_finalize);
|
1292 |
SQLITE_ANY, NULL, NULL, arr_sum1[i].func, __vecsummary_finalize);
|
| 1169 |
_sqlite_error(res);
|
1293 |
_sqlite_error(res);
|