pomp
Inference for partially observed Markov processes
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pomp_fun.c
Go to the documentation of this file.
1// dear emacs, please treat this as -*- C++ -*-
2
3#include <R.h>
4#include <Rdefines.h>
5
6#include <R_ext/Rdynload.h>
7
8#include "internal.h"
9
10static R_INLINE SEXP name_index (SEXP provided, SEXP object, const char *slot, const char *humanreadable) {
11 SEXP slotnames, index;
12 PROTECT(slotnames = GET_SLOT(object,install(slot)));
13 if (LENGTH(slotnames) > 0) {
14 PROTECT(index = matchnames(provided,slotnames,humanreadable));
15 } else {
16 PROTECT(index = NEW_INTEGER(0));
17 }
18 UNPROTECT(2);
19 return index;
20}
21
22// Returns either the R function or the address of the native routine.
23// On return, mode indicates the mode of the 'pomp_fun'
24// (i.e., R function, external function, or C snippet).
25// If 'gnsi' is set to TRUE, we look up the native symbol information in the DLL,
26// storing it in the 'address' slot.
27// If 'gsni' is TRUE, and there are names in one or more of the S,P,O,C arguments, we look up the
28// names in the corresponding 'pomp_fun' slots and storing the corresponding index
29// inside the 'pomp_fun'.
30SEXP pomp_fun_handler (SEXP pfun, SEXP gnsi, pompfunmode *mode,
31 SEXP S, SEXP P, SEXP O, SEXP C)
32{
33 int nprotect = 0;
34 SEXP f = R_NilValue;
35 SEXP sidx, pidx, oidx, cidx;
36
37 *mode = *(INTEGER(GET_SLOT(pfun,install("mode"))));
38
39 switch (*mode) {
40
41 case Rfun: // R function
42
43 PROTECT(f = GET_SLOT(pfun,install("R.fun"))); nprotect++;
44
45 break;
46
47 case native: case regNative: // native code
48
49 if (*(LOGICAL(gnsi))) { // get native symbol information?
50
51 SEXP nf, pack;
52 PROTECT(nf = GET_SLOT(pfun,install("native.fun")));
53 PROTECT(pack = GET_SLOT(pfun,install("PACKAGE")));
54 nprotect += 2;
55
56 if (LENGTH(pack) < 1) {
57 PROTECT(pack = mkString("")); nprotect++; // #nocov
58 }
59
60 if (*mode == native) {
61
62 SEXP nsi;
63 PROTECT(nsi = eval(PROTECT(lang3(install("getNativeSymbolInfo"),nf,pack)),R_BaseEnv));
64 PROTECT(f = getListElement(nsi,"address"));
65 nprotect += 3;
66
67 } else if (*mode == regNative) {
68
69 const char *fname, *pkg;
70 fname = (const char *) CHAR(STRING_ELT(nf,0));
71 pkg = (const char *) CHAR(STRING_ELT(pack,0));
72 DL_FUNC fn;
73 fn = R_GetCCallable(pkg,fname);
74 PROTECT(f = R_MakeExternalPtrFn(fn,R_NilValue,R_NilValue)); nprotect++;
75
76 }
77
78 SET_SLOT(pfun,install("address"),f);
79
80 if (S != NA_STRING) {
81 PROTECT(sidx = name_index(S,pfun,"statenames","state variables")); nprotect++;
82 SET_SLOT(pfun,install("stateindex"),sidx);
83 }
84
85 if (P != NA_STRING) {
86 PROTECT(pidx = name_index(P,pfun,"paramnames","parameters")); nprotect++;
87 SET_SLOT(pfun,install("paramindex"),pidx);
88 }
89
90 if (O != NA_STRING) {
91 PROTECT(oidx = name_index(O,pfun,"obsnames","observables")); nprotect++;
92 SET_SLOT(pfun,install("obsindex"),oidx);
93 }
94
95 if (C != NA_STRING) {
96 PROTECT(cidx = name_index(C,pfun,"covarnames","covariates")); nprotect++;
97 SET_SLOT(pfun,install("covarindex"),cidx);
98 }
99
100 } else { // native symbol info is stored
101
102 PROTECT(f = GET_SLOT(pfun,install("address"))); nprotect++;
103
104 }
105
106 break;
107
108 case undef: default:
109
110 PROTECT(f = R_NilValue); nprotect++;
111 *mode = undef;
112
113 break;
114
115 }
116
117 UNPROTECT(nprotect);
118 return f;
119}
120
121SEXP load_stack_incr (SEXP pack) {
122 const char *pkg;
123 void (*ff)(void);
124 pkg = (const char *) CHAR(STRING_ELT(pack,0));
125 ff = (void (*)(void)) R_GetCCallable(pkg,"__pomp_load_stack_incr");
126 ff();
127 return R_NilValue;
128}
129
130SEXP load_stack_decr (SEXP pack) {
131 SEXP s;
132 const char *pkg;
133 void (*ff)(int *);
134 PROTECT(s = ScalarInteger(NA_INTEGER));
135 pkg = (const char *) CHAR(STRING_ELT(pack,0));
136 ff = (void (*)(int *)) R_GetCCallable(pkg,"__pomp_load_stack_decr");
137 ff(INTEGER(s));
138 if (*(INTEGER(s)) < 0) err("impossible!");
139 UNPROTECT(1);
140 return s;
141}
#define err(...)
Definition pomp.h:21
static R_INLINE SEXP matchnames(SEXP provided, SEXP needed, const char *where)
pompfunmode
@ Rfun
@ native
@ undef
@ regNative
static R_INLINE SEXP getListElement(SEXP list, const char *str)
SEXP load_stack_decr(SEXP pack)
Definition pomp_fun.c:130
SEXP load_stack_incr(SEXP pack)
Definition pomp_fun.c:121
SEXP pomp_fun_handler(SEXP pfun, SEXP gnsi, pompfunmode *mode, SEXP S, SEXP P, SEXP O, SEXP C)
Definition pomp_fun.c:30
static R_INLINE SEXP name_index(SEXP provided, SEXP object, const char *slot, const char *humanreadable)
Definition pomp_fun.c:10
pompfunmode mode
Definition trajectory.c:126
SEXP fn
Definition trajectory.c:138