The R Project SVN R-packages

Rev

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