The R Project SVN R-packages

Rev

Rev 3284 | Rev 3308 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3255 mrmanese 1
#include "sqlite_dataframe.h"
3307 mrmanese 2
#include <math.h>
3
#include "Rmath.h"
3255 mrmanese 4
 
5
SEXP sdf_get_variable(SEXP sdf, SEXP name) {
6
    if (!IS_CHARACTER(name)) {
7
        Rprintf("ERROR: argument is not a string.\n");
8
        return R_NilValue;
9
    }
10
 
11
    char *iname = SDF_INAME(sdf);
12
    char *varname = CHAR_ELT(name, 0);
13
 
14
    /* check if sdf & varname w/in that sdf exists */
15
    sqlite3_stmt *stmt;
16
    sprintf(g_sql_buf[0], "select [%s] from [%s].sdf_data", varname, iname);
17
 
18
    int res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
19
 
3281 mrmanese 20
    if (_sqlite_error(res)) return R_NilValue;
3255 mrmanese 21
 
22
    const char *coltype = sqlite3_column_decltype(stmt, 0);
23
    sqlite3_finalize(stmt);
24
 
25
 
3281 mrmanese 26
    SEXP ret, value, class = R_NilValue; int nprotected = 0;
3255 mrmanese 27
    PROTECT(ret = NEW_LIST(2)); nprotected++;
28
 
29
    /* set list names */
30
    PROTECT(value = NEW_CHARACTER(2)); nprotected++;
31
    SET_STRING_ELT(value, 0, mkChar("iname"));
32
    SET_STRING_ELT(value, 1, mkChar("varname"));
33
    SET_NAMES(ret, value);
34
 
35
    /* set list values */
36
    SET_VECTOR_ELT(ret, 0, mkString(iname));
37
    SET_VECTOR_ELT(ret, 1, mkString(varname));
38
 
39
    /* set class */
40
    int type = -1;
41
    if (strcmp(coltype, "text") == 0) class = mkChar("character");
42
    else if (strcmp(coltype, "double") == 0) class = mkChar("numeric");
43
    else if (strcmp(coltype, "bit") == 0) class = mkChar("logical");
44
    else if (strcmp(coltype, "integer") == 0 || strcmp(coltype, "int") == 0) {
45
        /* determine if int, factor or ordered */
46
        type = _get_factor_levels1(iname, varname, ret);
47
        switch(type) {
3307 mrmanese 48
            case VAR_INTEGER: class = mkChar("integer"); break;
3255 mrmanese 49
            case VAR_FACTOR: class = mkChar("factor"); break;
50
            case VAR_ORDERED: class = mkChar("ordered");
51
        }
52
 
53
    }
54
 
55
    if (type != VAR_ORDERED) {
56
        PROTECT(value = NEW_CHARACTER(2)); nprotected++;
57
        SET_STRING_ELT(value, 0, mkChar("sqlite.vector"));
58
        SET_STRING_ELT(value, 1, class);
59
    } else {
60
        PROTECT(value = NEW_CHARACTER(3)); nprotected++;
61
        SET_STRING_ELT(value, 0, mkChar("sqlite.vector"));
62
        SET_STRING_ELT(value, 1, class);
63
        SET_STRING_ELT(value, 2, mkChar("factor"));
64
    }
65
    SET_CLASS(ret, value);
66
 
67
    UNPROTECT(nprotected);
68
    return ret;
69
 
70
}
71
 
72
int _get_vector_index_typed_result(sqlite3_stmt *stmt, SEXP *ret, int idx_or_len) {
73
    int added = 1;
74
    if (*ret == NULL || *ret == R_NilValue) {
75
        const char *coltype = sqlite3_column_decltype(stmt, 0);
76
        if (sqlite3_column_type(stmt, 0) == SQLITE_NULL) {
77
            added = 0;
78
        }
79
 
80
        if (strcmp(coltype, "text") == 0) {
81
            PROTECT(*ret = NEW_CHARACTER(idx_or_len));
82
            if (added) 
3284 mrmanese 83
                SET_STRING_ELT(*ret, 0, mkChar((char *)sqlite3_column_text(stmt, 0)));
3255 mrmanese 84
        } else if (strcmp(coltype, "double") == 0) {
85
            PROTECT(*ret = NEW_NUMERIC(idx_or_len));
86
            if (added) REAL(*ret)[0] = sqlite3_column_double(stmt, 0);
87
        } else if (strcmp(coltype, "bit") == 0) {
88
            PROTECT(*ret = NEW_LOGICAL(idx_or_len));
89
            if (added) INTEGER(*ret)[0] = sqlite3_column_int(stmt, 0);
90
        } else if (strcmp(coltype, "integer") == 0 || 
91
                   strcmp(coltype, "int") == 0) {
92
            /* caller should just copy off the vars level attr for factors */
93
            PROTECT(*ret = NEW_INTEGER(idx_or_len));
94
            if (added) INTEGER(*ret)[0] = sqlite3_column_int(stmt, 0);
95
        } else added = 0;
96
 
97
        UNPROTECT(1);
98
    } else {
99
        const char *coltype = sqlite3_column_decltype(stmt, 0);
100
        if (sqlite3_column_type(stmt, 0) == SQLITE_NULL) {
101
            added = 0;
102
        } else if (strcmp(coltype, "text") == 0) {
103
            SET_STRING_ELT(*ret, idx_or_len, 
3284 mrmanese 104
                    mkChar((char *)sqlite3_column_text(stmt, 0)));
3255 mrmanese 105
        } else if (strcmp(coltype, "double") == 0) {
106
            REAL(*ret)[idx_or_len] = sqlite3_column_double(stmt, 0);
107
        } else if (strcmp(coltype, "bit") == 0) {
108
            INTEGER(*ret)[idx_or_len] = sqlite3_column_int(stmt, 0);
109
        } else if (strcmp(coltype, "integer") == 0 ||
110
                   strcmp(coltype, "int") == 0) {
111
            /* caller should just copy off the vars level attr for factors */
112
            INTEGER(*ret)[idx_or_len] = sqlite3_column_int(stmt, 0);
113
        } else added = 0;
114
    }
115
 
116
    return added;
117
}
118
 
119
SEXP sdf_get_variable_length(SEXP svec) {
120
    char *iname = SDF_INAME(svec);
121
    sprintf(g_sql_buf[0], "[%s].sdf_data", iname);
122
 
123
    SEXP ret;
124
    PROTECT(ret = NEW_INTEGER(1));
125
    INTEGER(ret)[0] = _get_row_count2(g_sql_buf[0]);
126
    UNPROTECT(1);
127
    return ret;
128
}
129
 
130
 
131
SEXP sdf_get_variable_index(SEXP svec, SEXP idx) {
132
    SEXP ret = R_NilValue, tmp;
133
    char *iname = SDF_INAME(svec), *varname = SVEC_VARNAME(svec);
3282 mrmanese 134
    int index, idxlen, i, retlen=0, res;
3255 mrmanese 135
 
136
    /* check if sdf exists */
137
    sqlite3_stmt *stmt;
138
    sprintf(g_sql_buf[0], "select [%s] from [%s].sdf_data", varname, iname);
139
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
140
    sqlite3_finalize(stmt);
141
    if (_sqlite_error(res)) { return ret; }
142
 
143
    idxlen = LENGTH(idx);
144
    if (idxlen < 1) return ret;
145
 
146
    sprintf(g_sql_buf[0], "select [%s] from [%s].sdf_data limit ?,1",
147
            varname, iname);
148
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
149
 
150
    /* get data based on index */
151
    if (IS_NUMERIC(idx)) {
152
        index = ((int) REAL(idx)[0]) - 1;
153
        if (index < 0 && idxlen == 1) return ret;
154
 
3281 mrmanese 155
        if (index >= 0) {
3255 mrmanese 156
            sqlite3_bind_int(stmt, 1, index);
157
            res = sqlite3_step(stmt);
158
            if (res == SQLITE_ROW) { 
159
                retlen = _get_vector_index_typed_result(stmt, &ret, idxlen);
160
            } 
161
        } 
162
 
3281 mrmanese 163
        if (index < 0 || res != SQLITE_ROW) {
3255 mrmanese 164
            /* something wrong w/ 1st idx, and it is quietly ignored. we make 
165
             * a "dummy" call to setup the SEXP */
166
            sqlite3_bind_int(stmt, 1, 0);
167
            _get_vector_index_typed_result(stmt, &ret, idxlen - 1);
168
            retlen = 0;
169
        }
170
 
171
        if (idxlen > 1) {
172
            for (i = 1; i < idxlen; i++) {
173
                index = ((int) REAL(idx)[i]) - 1;
174
                if (index < 0) continue;
175
                sqlite3_reset(stmt);
176
                sqlite3_bind_int(stmt, 1, index);
177
                res = sqlite3_step(stmt);
178
                if (res == SQLITE_ROW)
179
                    retlen += _get_vector_index_typed_result(stmt, &ret, retlen); 
180
            }
181
        }
182
    } else if (IS_INTEGER(idx)) {
183
        /* similar to REAL (IS_NUMERIC) above, except that we don't have
184
         * to cast idx to int. can't refactor this out, sucks. */
185
        index = INTEGER(idx)[0] - 1;
186
        if (index < 0 && idxlen == 1) return ret;
187
 
3281 mrmanese 188
        if (index >= 0) {
3255 mrmanese 189
            sqlite3_bind_int(stmt, 1, index);
3281 mrmanese 190
            res = sqlite3_step(stmt);
191
            if (res == SQLITE_ROW) { 
192
                retlen = _get_vector_index_typed_result(stmt, &ret, idxlen);
193
            } 
194
        } 
195
 
196
        if (index < 0 || res != SQLITE_ROW) {
197
            /* something wrong w/ 1st idx, and it is quietly ignored. we make 
198
             * a "dummy" call to setup the SEXP */
3255 mrmanese 199
            sqlite3_bind_int(stmt, 1, 0);
200
            _get_vector_index_typed_result(stmt, &ret, idxlen - 1);
201
            retlen = 0;
202
        }
203
 
204
        if (idxlen > 1) {
205
            for (i = 1; i < idxlen; i++) {
206
                index = INTEGER(idx)[i] - 1;
207
                if (index < 0) continue;
208
                sqlite3_reset(stmt);
209
                sqlite3_bind_int(stmt, 1, index);
210
                sqlite3_step(stmt);
211
                retlen += _get_vector_index_typed_result(stmt, &ret, retlen); 
212
            }
213
        }
214
 
215
    } else if (IS_LOGICAL(idx)) {
216
        /* have to deal with recycling */
217
        sprintf(g_sql_buf[0], "[%s].sdf_data", iname);
218
        int veclen = _get_row_count2(g_sql_buf[0]);
219
 
220
        /* find if there is any TRUE element in the vector */
3281 mrmanese 221
        for (i = 0; i < idxlen && i < veclen; i++) {
3255 mrmanese 222
            if (LOGICAL(idx)[i]) {
223
                sqlite3_bind_int(stmt, 1, i);
224
                sqlite3_step(stmt);
225
                /* there are at least (idxlen-i) TRUE per cycle of the LOGICAL
226
                 * index. there are at least (veclen/idxlen) cycles (int div).
227
                 * at the last cycle, if (veclen%idxlen > 0), there will be
228
                 * at least (veclen%idxlen - i) if veclen%idxlen > i */
229
                retlen = (idxlen-i) * (veclen/idxlen);
230
                if (veclen%idxlen > i) retlen += (veclen%idxlen - i);
231
 
232
                /* create the vector */
233
                retlen = _get_vector_index_typed_result(stmt, &ret, retlen);
234
                break;
235
            }
236
        }
237
 
3281 mrmanese 238
        if (i < idxlen && i < veclen) {
3255 mrmanese 239
            for (i++; i < veclen; i++) {
240
                if (LOGICAL(idx)[i%idxlen]) {
241
                    sqlite3_reset(stmt);
242
                    sqlite3_bind_int(stmt, 1, i);
243
                    sqlite3_step(stmt);
244
                    retlen += _get_vector_index_typed_result(stmt, &ret, retlen);
245
                }
246
            }
247
        }
248
    }
249
 
250
    sqlite3_finalize(stmt);
251
 
252
    if (ret != R_NilValue) {
253
        ret = _shrink_vector(ret, retlen);
254
        tmp = GET_LEVELS(svec);
255
        if (tmp != R_NilValue) {
256
            SET_LEVELS(ret, duplicate(tmp));
257
            if (LENGTH(GET_CLASS(svec)) == 2) {
258
                SET_CLASS(ret, mkString("factor"));
259
            } else {
260
                PROTECT(tmp = NEW_CHARACTER(2));
261
                SET_STRING_ELT(tmp, 0, mkChar("ordered"));
262
                SET_STRING_ELT(tmp, 1, mkChar("factor"));
263
                UNPROTECT(1);
264
            }
265
        }
266
    }
267
 
268
    return ret;
269
}
270
 
271
 
3307 mrmanese 272
SEXP sdf_do_variable_math(SEXP func, SEXP vector, SEXP extra_args, SEXP _nargs) {
273
    char *iname, *iname_src, *varname_src, *funcname;
274
    int namelen, res, nargs;
275
    sqlite3_stmt *stmt;
3255 mrmanese 276
 
3307 mrmanese 277
    /* get data from arguments (function name and sqlite.vector stuffs) */
278
    funcname = CHAR_ELT(func, 0);
279
    iname_src = SDF_INAME(vector);
280
    varname_src = SVEC_VARNAME(vector);
281
    nargs = INTEGER(_nargs)[0];
3255 mrmanese 282
 
3307 mrmanese 283
    /* check nargs */
284
    if (nargs > 2) {
285
        Rprintf("Error: Don't know how to handle Math functions w/ more than 2 args\n");
286
        return R_NilValue;
287
    }
288
 
289
    /* create a new sdf, with 1 column named V1 */
290
    iname = _create_sdf_skeleton2(R_NilValue, &namelen);
291
    if (iname == NULL) return R_NilValue;
292
 
293
    sprintf(g_sql_buf[0], "create table [%s].sdf_data ([row name] text, "
294
            "V1 double)", iname);
295
    res = _sqlite_exec(g_sql_buf[0]);
296
    _sqlite_error(res);
297
 
298
    /* insert into <newsdf>.col, row.names select func(col), rownames */
299
    sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
300
            "select [row name], %s([%s]) from [%s].sdf_data", iname, funcname,
301
            varname_src, iname_src);
302
 
303
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0); 
304
    if (_sqlite_error(res)) {
305
        sprintf(g_sql_buf[0], "detach %s", iname);
306
        _sqlite_exec(g_sql_buf[0]);
307
 
308
        /* we will return a string with the file name, and do file.remove
309
         * at R */
310
        iname[namelen] = '.';
311
        return mkString(iname);
312
    }
313
 
314
    sqlite3_step(stmt);
315
    sqlite3_finalize(stmt);
316
 
317
    /* add to workspace */
318
    strcpy(g_sql_buf[0], iname);
319
    iname[namelen] = '.';
320
    _add_sdf1(iname,  g_sql_buf[0]);
321
    iname[namelen] = 0;
322
 
323
    /* create sqlite.vector sexp */
324
    SEXP ret, value; int nprotected = 0;
325
    PROTECT(ret = NEW_LIST(2)); nprotected++;
326
 
327
    /* set list names */
328
    PROTECT(value = NEW_CHARACTER(2)); nprotected++;
329
    SET_STRING_ELT(value, 0, mkChar("iname"));
330
    SET_STRING_ELT(value, 1, mkChar("varname"));
331
    SET_NAMES(ret, value);
332
 
333
    /* set list values */
334
    SET_VECTOR_ELT(ret, 0, mkString(iname));
335
    SET_VECTOR_ELT(ret, 1, mkString("V1"));
336
 
337
    /* set sexp class */
338
    PROTECT(value = NEW_CHARACTER(2)); nprotected++;
339
    SET_VECTOR_ELT(value, 0, mkChar("sqlite.vector"));
340
    SET_VECTOR_ELT(value, 1, mkChar("numeric"));
341
    SET_CLASS(ret, value);
342
 
343
    UNPROTECT(nprotected);
344
 
345
    return ret;
346
 
347
}
348
 
349
 
350
 
351
/****************************************************************************
352
 * VECTOR MATH/OPS/GROUP OPERATIONS
353
 ****************************************************************************/
354
int __vecmath_checkarg(sqlite3_context *ctx, sqlite3_value *arg, double *value) {
355
    int ret = 1;
356
    if (sqlite3_value_type(arg) == SQLITE_NULL) { 
357
        sqlite3_result_null(ctx); 
358
        ret = 0;
359
    } else {
360
        if (sqlite3_value_type(arg) == SQLITE_INTEGER) 
361
            *value = sqlite3_value_int(arg); 
362
        else *value = sqlite3_value_double(arg); 
363
    }
364
    return ret;
365
}
366
 
367
#define SQLITE_MATH_FUNC1(name, func) static void __vecmath_ ## name(\
368
        sqlite3_context *ctx, int argc, sqlite3_value **argv) { \
369
    double value; \
370
    if (__vecmath_checkarg(ctx, argv[0], &value)) { \
371
        sqlite3_result_double(ctx, func(value)); \
372
    }  \
373
}
374
 
375
/* SQLITE_MATH_FUNC1(abs, abs)   in SQLite */
376
SQLITE_MATH_FUNC1(sign, sign)   /* in R */
377
SQLITE_MATH_FUNC1(sqrt, sqrt)
378
SQLITE_MATH_FUNC1(floor, floor)
379
SQLITE_MATH_FUNC1(ceiling, ceil)
380
SQLITE_MATH_FUNC1(trunc, ftrunc) /* in R */
381
/* SQLITE_MATH_FUNC1(round, )   in SQLite */
382
/* SQLITE_MATH_FUNC1(signif, ) 2 arg */
383
SQLITE_MATH_FUNC1(exp, exp)
384
/* SQLITE_MATH_FUNC1(log, ) 2 arg */
385
SQLITE_MATH_FUNC1(cos, cos)
386
SQLITE_MATH_FUNC1(sin, sin)
387
SQLITE_MATH_FUNC1(tan, tan)
388
SQLITE_MATH_FUNC1(acos, acos)
389
SQLITE_MATH_FUNC1(asin, asin)
390
SQLITE_MATH_FUNC1(atan, atan)
391
SQLITE_MATH_FUNC1(cosh, cosh)
392
SQLITE_MATH_FUNC1(sinh, sinh)
393
SQLITE_MATH_FUNC1(tanh, tanh)
394
SQLITE_MATH_FUNC1(acosh, acosh)  /* nowhere in include?? */
395
SQLITE_MATH_FUNC1(asinh, asinh)  /* nowhere in include?? */
396
SQLITE_MATH_FUNC1(atanh, atanh)  /* nowhere in include?? */
397
SQLITE_MATH_FUNC1(lgamma, lgammafn) /* in R */
398
SQLITE_MATH_FUNC1(gamma, gammafn) /* in R */
399
/* SQLITE_MATH_FUNC1(gammaCody, gammaCody)   * in R ?? */
400
SQLITE_MATH_FUNC1(digamma, digamma) /* in R */    
401
SQLITE_MATH_FUNC1(trigamma, trigamma) /* in R */
402
 
403
#define VMENTRY1(func)  {#func, __vecmath_ ## func}
404
void __register_vector_math() {
405
    int i, res;
406
    static const struct {
407
        char *name;
408
        void (*func)(sqlite3_context*, int, sqlite3_value**);
409
    } arr_func1[] = {
410
        VMENTRY1(sign),
411
        VMENTRY1(sqrt),
412
        VMENTRY1(floor),
413
        VMENTRY1(ceiling),
414
        VMENTRY1(trunc),
415
        VMENTRY1(exp),
416
        VMENTRY1(cos),
417
        VMENTRY1(sin),
418
        VMENTRY1(tan),
419
        VMENTRY1(acos),
420
        VMENTRY1(asin),
421
        VMENTRY1(atan),
422
        VMENTRY1(cosh),
423
        VMENTRY1(sinh),
424
        VMENTRY1(tanh),
425
        VMENTRY1(acosh),
426
        VMENTRY1(asinh),
427
        VMENTRY1(atanh),
428
        VMENTRY1(lgamma),
429
        VMENTRY1(gamma),
430
        VMENTRY1(digamma),
431
        VMENTRY1(trigamma)
432
    };
433
 
434
    int func1_len = sizeof(arr_func1) / sizeof(arr_func1[0]);
435
 
436
    for (i = 0; i < func1_len; i++) {
437
        res = sqlite3_create_function(g_workspace, arr_func1[i].name, 1, 
438
                SQLITE_ANY, NULL, arr_func1[i].func, NULL, NULL);
439
        _sqlite_error(res);
440
    }
441
}