Microsimulation API

rcpp_table.h
Go to the documentation of this file.
1 #ifndef RCPP_TABLE_H
2 #define RCPP_TABLE_H
3
4 #include <Rcpp.h>
5
6 #include <functional>
7 #include <boost/tuple/tuple.hpp>
8 #include <boost/tuple/tuple_comparison.hpp>
9 #include <set>
10
11 using namespace std;
12 using namespace Rcpp;
13 using boost::get;
14
15 // TODO: re-write the DataFrameView class and adapt the Table class for it.
16
17 class Interpolate {
18 public:
19 vector<double> x, y, slope;
20 Interpolate() {
21 }
22 Interpolate(vector<double> inx, vector<double> iny) :
23 x(inx), y(iny) {
24 // calculate the slope between points
25 for (size_t i=0; i<x.size()-1; i++) {
26 slope.push_back((y[i+1]-y[i]) / (x[i+1]-x[i]));
27 }
28 }
29 double approx(double xfind) {
30 int i;
31 if (xfind<=x[0]) return y[0];
32 else if (xfind>=*(--x.end())) return *(--y.end());
33 else {
34 i = lower_bound(x.begin(), x.end(), xfind) - x.begin();
35 return y[i]+slope[i]*(xfind-x[i]);
36 }
37 }
38 double operator()(double xfind) {
39 if (xfind<=x[0]) return y[0];
40 int i = lower_bound(x.begin(), x.end(), xfind) - x.begin();
41 return y[--i];
42 }
43 };
44
53 class NumericInterpolate {
54 public:
55 NumericVector x, y, slope;
56 int n;
57 NumericInterpolate() : x(0), y(0), slope(0), n(0) {
58 }
59 NumericInterpolate(DataFrame df, int i0=0, int i1=1) {
60 // calculate the slope between points
61 x = df(i0);
62 y = df(i1);
63 n = x.size();
64 prepare();
65 }
66 void prepare() {
67 for (int i=0; i<n-1; i++) {
68 slope.push_back((y[i+1]-y[i]) / (x[i+1]-x[i]));
69 }
70 }
71 void push_back(pair<double,double> xy) {
72 x.push_back(xy.first);
73 y.push_back(xy.second);
74 n++;
75 }
76 double approx(double xfind) {
77 int i;
78 if (xfind<=x[0]) return y[0];
79 else if (xfind>=x[n-1]) return y[n-1]+slope[n-2]*(xfind-x[n-1]); // linear
80 else {
81 i = lower_bound(x.begin(), x.end(), xfind) - 1 - x.begin();
82 return y[i]+slope[i]*(xfind-x[i]);
83 }
84 }
85 double operator()(double xfind) {
86 if (xfind<=x[0]) return y[0];
87 int i = lower_bound(x.begin(), x.end(), xfind) - x.begin();
88 return y[--i];
89 }
90 double invert(double yfind) { // assumes that the function is increasing
91 int i;
92 if (yfind<=y[0]) return x[0];
93 else if (yfind>=y[n-1]) return x[n-1]+(yfind-y[n-1])/slope[n-2];
94 else {
95 i = lower_bound(y.begin(), y.end(), yfind) - 1 - y.begin();
96 return x[i]+(yfind-y[i])/slope[i];
97 }
98 }
99 double invert(double yfind, double xentry) { // assumes that the function is increasing
100 double yentry = approx(xentry);
101 return invert(yfind - yentry);
102 }
103 double invert_decreasing(double yfind) { // assumes that the function is decreasing
104 int i;
105 if (yfind>=y[0]) return x[0];
106 else if (yfind<y[n-1]) return x[n-1]+(yfind-y[n-1])/slope[n-2];
107 else {
108 i = lower_bound(y.begin(), y.end(), yfind, greater<double>()) - 1 - y.begin();
109 return x[i]+(yfind-y[i])/slope[i];
110 }
111 }
112 };
113
114
115 template<class T>
116 T set_lower_bound(set<T,greater<T> > aset, T value) {
117 return value<*aset.rbegin() ? *aset.rbegin() : *aset.lower_bound(value);
118 }
119
120 template <class T>
121 class DataFrameSelect {
122 public:
123 Vector<Rcpp::traits::r_sexptype_traits<T>::rtype> data;
124 DataFrameSelect(const DataFrame & df, int i = 0) {
125 data = df(i); // copy
126 }
127 DataFrameSelect(const DataFrame & df, string name) {
128 data = df[name];
129 }
130 T operator[](int i) {
131 return(data[i]);
132 }
133 int size() {
134 return data.size();
135 }
136 };
137
144 struct null_type {};
145
146 template<class I0 = null_type, class I1 = null_type, class I2 = null_type,
147 class I3 = null_type, class I4 = null_type, class Outcome = null_type>
148 class Table {
149 public:
150 Table() {}
151 typedef boost::tuple<I0,I1,I2,I3,I4> key_type;
152 typedef Outcome mapped_type;
153 typedef boost::tuple<
154 set<I0, greater<I0> >,
155 set<I1, greater<I1> >,
156 set<I2, greater<I2> >,
157 set<I3, greater<I3> >,
158 set<I4, greater<I4> >
159 > Axis;
160 void insert(I0 key0, I1 key1, I2 key2, I3 key3, I4 key4, Outcome outcome) {
161 key_type key = key_type(key0,key1,key2,key3,key4);
162 get<0>(axis).insert(key0);
163 get<1>(axis).insert(key1);
164 get<2>(axis).insert(key2);
165 get<3>(axis).insert(key3);
166 get<4>(axis).insert(key4);
167 data[key] = outcome;
168 }
169 virtual Outcome operator()(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4) {
170 return data[key_type(set_lower_bound(get<0>(axis), i0),
171 set_lower_bound(get<1>(axis), i1),
172 set_lower_bound(get<2>(axis), i2),
173 set_lower_bound(get<3>(axis), i3),
174 set_lower_bound(get<4>(axis), i4))];
175 }
176 Table(const DataFrame & df, string s0, string s1, string s2, string s3, string s4, string s5) {
177 DataFrameSelect<I0> df0(df,s0);
178 DataFrameSelect<I1> df1(df,s1);
179 DataFrameSelect<I2> df2(df,s2);
180 DataFrameSelect<I3> df3(df,s3);
181 DataFrameSelect<I4> df4(df,s4);
182 DataFrameSelect<Outcome> df5(df,s5);
183 for (int i=0; i<df0.size(); i++) {
184 insert(df0[i],df1[i],df2[i],df3[i],df4[i], df5[i]);
185 }
186 }
187 private:
188 Axis axis;
189 map<key_type,mapped_type> data;
190 };
191
192 template<class I0, class I1, class I2, class I3, class Outcome>
193 class Table<I0,I1,I2,I3,Outcome> {
194 public:
195 typedef boost::tuple<I0,I1,I2,I3> key_type;
196 typedef Outcome mapped_type;
197 typedef boost::tuple<
198 set<I0, greater<I0> >,
199 set<I1, greater<I1> >,
200 set<I2, greater<I2> >,
201 set<I3, greater<I3> >
202 > Axis;
203 Table() {}
204 void insert(I0 key0, I1 key1, I2 key2, I3 key3, mapped_type outcome) {
205 key_type key = key_type(key0,key1,key2,key3);
206 get<0>(axis).insert(key0);
207 get<1>(axis).insert(key1);
208 get<2>(axis).insert(key2);
209 get<3>(axis).insert(key3);
210 data[key] = outcome;
211 }
212 virtual Outcome operator()(I0 i0, I1 i1, I2 i2, I3 i3) {
213 return data[key_type(set_lower_bound(get<0>(axis), i0),
214 set_lower_bound(get<1>(axis), i1),
215 set_lower_bound(get<2>(axis), i2),
216 set_lower_bound(get<3>(axis), i3))];
217 }
218 Table(const DataFrame & df, string s0, string s1, string s2, string s3, string s4) {
219 DataFrameSelect<I0> df0(df,s0);
220 DataFrameSelect<I1> df1(df,s1);
221 DataFrameSelect<I2> df2(df,s2);
222 DataFrameSelect<I3> df3(df,s3);
223 DataFrameSelect<Outcome> df4(df,s4);
224 for (int i=0; i<df0.size(); i++) {
225 insert(df0[i],df1[i],df2[i],df3[i], df4[i]);
226 }
227 }
228 private:
229 Axis axis;
230 map<key_type,mapped_type> data;
231 };
232
233 template<class I0, class I1, class I2, class Outcome>
234 class Table<I0,I1,I2,Outcome> {
235 public:
236 typedef boost::tuple<I0,I1,I2> key_type;
237 typedef Outcome mapped_type;
238 typedef boost::tuple<
239 set<I0, greater<I0> >,
240 set<I1, greater<I1> >,
241 set<I2, greater<I2> >
242 > Axis;
243 Table() {}
244 void insert(I0 key0, I1 key1, I2 key2, mapped_type outcome) {
245 key_type key = key_type(key0,key1,key2);
246 get<0>(axis).insert(key0);
247 get<1>(axis).insert(key1);
248 get<2>(axis).insert(key2);
249 data[key] = outcome;
250 }
251 virtual Outcome operator()(I0 i0, I1 i1, I2 i2) {
252 return data[key_type(set_lower_bound(get<0>(axis), i0),
253 set_lower_bound(get<1>(axis), i1),
254 set_lower_bound(get<2>(axis), i2))];
255 }
256 Table(const DataFrame & df, string s0, string s1, string s2, string s3) {
257 DataFrameSelect<I0> df0(df,s0);
258 DataFrameSelect<I1> df1(df,s1);
259 DataFrameSelect<I2> df2(df,s2);
260 DataFrameSelect<Outcome> df3(df,s3);
261 for (int i=0; i<df0.size(); i++) {
262 insert(df0[i],df1[i],df2[i], df3[i]);
263 }
264 }
265 private:
266 Axis axis;
267 map<key_type,mapped_type> data;
268 };
269
270 template<class I0, class I1, class Outcome>
271 class Table<I0,I1,Outcome> {
272 public:
273 typedef boost::tuple<I0,I1> key_type;
274 typedef Outcome mapped_type;
275 typedef boost::tuple<
276 set<I0, greater<I0> >,
277 set<I1, greater<I1> >
278 > Axis;
279 Table() {}
280 void insert(I0 key0, I1 key1, mapped_type outcome) {
281 key_type key = key_type(key0,key1);
282 get<0>(axis).insert(key0);
283 get<1>(axis).insert(key1);
284 data[key] = outcome;
285 }
286 virtual Outcome operator()(I0 i0, I1 i1) {
287 return data[key_type(set_lower_bound(get<0>(axis), i0),
288 set_lower_bound(get<1>(axis), i1))];
289 }
290 Table(const DataFrame & df, string s0, string s1, string s2) {
291 DataFrameSelect<I0> df0(df,s0);
292 DataFrameSelect<I1> df1(df,s1);
293 DataFrameSelect<Outcome> df2(df,s2);
294 for (int i=0; i<df0.size(); i++) {
295 insert(df0[i],df1[i], df2[i]);
296 }
297 }
298 private:
299 Axis axis;
300 map<key_type,mapped_type> data;
301 };
302
303 template<class key_type, class mapped_type>
304 class Table<key_type,mapped_type> {
305 public:
306 typedef set<key_type, greater<key_type> > Axis;
307 Table() {}
308 void insert(const key_type& key, const mapped_type& outcome) {
309 axis.insert(key);
310 data[key] = outcome;
311 }
312 virtual mapped_type operator()(key_type key) {
313 return data[set_lower_bound(axis,key)];
314 }
315 Table(const DataFrame & df, string s0, string s1) {
316 DataFrameSelect<key_type> df0(df,s0);
317 DataFrameSelect<mapped_type> df1(df,s1);
318 for (int i=0; i<df0.size(); i++) {
319 insert(key_type(df0[i]), mapped_type(df1[i]));
320 }
321 }
322 private:
323 Axis axis;
324 map<key_type,mapped_type> data;
325 };
326
327 #endif /* RCPP_TABLE_H */
Table< I0, I1, I2, I3, Outcome >::data
map< key_type, mapped_type > data
Definition: rcpp_table.h:230
null_type
A table class for lookups. For the case of a single key, this is a small extension to std::map,...
Definition: rcpp_table.h:144
Interpolate
Definition: rcpp_table.h:17
Table< I0, I1, I2, Outcome >::mapped_type
Outcome mapped_type
Definition: rcpp_table.h:237
Interpolate::y
vector< double > y
Definition: rcpp_table.h:19
Table::data
map< key_type, mapped_type > data
Definition: rcpp_table.h:189
Table< I0, I1, I2, Outcome >::axis
Axis axis
Definition: rcpp_table.h:266
Interpolate::approx
double approx(double xfind)
Definition: rcpp_table.h:29
Table< I0, I1, I2, Outcome >::Table
Table()
Definition: rcpp_table.h:243
DataFrameSelect::DataFrameSelect
DataFrameSelect(const DataFrame &df, string name)
Definition: rcpp_table.h:127
Table< I0, I1, Outcome >::operator()
virtual Outcome operator()(I0 i0, I1 i1)
Definition: rcpp_table.h:286
DataFrameSelect::data
Vector< Rcpp::traits::r_sexptype_traits< T >::rtype > data
Definition: rcpp_table.h:123
Interpolate::operator()
double operator()(double xfind)
Definition: rcpp_table.h:38
DataFrameSelect
Definition: rcpp_table.h:121
Table< I0, I1, I2, Outcome >::key_type
boost::tuple< I0, I1, I2 > key_type
Definition: rcpp_table.h:236
Table::Table
Table(const DataFrame &df, string s0, string s1, string s2, string s3, string s4, string s5)
Definition: rcpp_table.h:176
Table< I0, I1, I2, I3, Outcome >::operator()
virtual Outcome operator()(I0 i0, I1 i1, I2 i2, I3 i3)
Definition: rcpp_table.h:212
Table< I0, I1, I2, I3, Outcome >::Table
Table()
Definition: rcpp_table.h:203
Interpolate::Interpolate
Interpolate()
Definition: rcpp_table.h:20
DataFrameSelect::DataFrameSelect
DataFrameSelect(const DataFrame &df, int i=0)
Definition: rcpp_table.h:124
NumericInterpolate::push_back
void push_back(pair< double, double > xy)
Definition: rcpp_table.h:71
NumericInterpolate::approx
double approx(double xfind)
Definition: rcpp_table.h:76
Table< I0, I1, I2, I3, Outcome >::mapped_type
Outcome mapped_type
Definition: rcpp_table.h:196
NumericInterpolate::y
NumericVector y
Definition: rcpp_table.h:55
Table
Definition: rcpp_table.h:148
Interpolate::Interpolate
Interpolate(vector< double > inx, vector< double > iny)
Definition: rcpp_table.h:22
Table< key_type, mapped_type >::Table
Table()
Definition: rcpp_table.h:307
Table< I0, I1, Outcome >::Table
Table(const DataFrame &df, string s0, string s1, string s2)
Definition: rcpp_table.h:290
Table< I0, I1, I2, Outcome >::data
map< key_type, mapped_type > data
Definition: rcpp_table.h:267
NumericInterpolate::NumericInterpolate
NumericInterpolate(DataFrame df, int i0=0, int i1=1)
Definition: rcpp_table.h:59
Table::Axis
boost::tuple< set< I0, greater< I0 > >, set< I1, greater< I1 > >, set< I2, greater< I2 > >, set< I3, greater< I3 > >, set< I4, greater< I4 > > > Axis
Definition: rcpp_table.h:159
NumericInterpolate::invert
double invert(double yfind)
Definition: rcpp_table.h:90
Table< I0, I1, I2, Outcome >::insert
void insert(I0 key0, I1 key1, I2 key2, mapped_type outcome)
Definition: rcpp_table.h:244
Table< I0, I1, I2, I3, Outcome >::Axis
boost::tuple< set< I0, greater< I0 > >, set< I1, greater< I1 > >, set< I2, greater< I2 > >, set< I3, greater< I3 > > > Axis
Definition: rcpp_table.h:202
NumericInterpolate::invert_decreasing
double invert_decreasing(double yfind)
Definition: rcpp_table.h:103
Table< key_type, mapped_type >::data
map< key_type, mapped_type > data
Definition: rcpp_table.h:324
DataFrameSelect::operator[]
T operator[](int i)
Definition: rcpp_table.h:130
Table< I0, I1, Outcome >::key_type
boost::tuple< I0, I1 > key_type
Definition: rcpp_table.h:273
Rcpp
Definition: microsimulation.h:77
Table< I0, I1, Outcome >::axis
Axis axis
Definition: rcpp_table.h:299
NumericInterpolate::NumericInterpolate
NumericInterpolate()
Definition: rcpp_table.h:57
Table< key_type, mapped_type >::Table
Table(const DataFrame &df, string s0, string s1)
Definition: rcpp_table.h:315
NumericInterpolate::n
int n
Definition: rcpp_table.h:56
NumericInterpolate::operator()
double operator()(double xfind)
Definition: rcpp_table.h:85
Table::Table
Table()
Definition: rcpp_table.h:150
Table< key_type, mapped_type >::Axis
set< key_type, greater< key_type > > Axis
Definition: rcpp_table.h:306
NumericInterpolate::prepare
void prepare()
Definition: rcpp_table.h:66
Table< I0, I1, Outcome >::data
map< key_type, mapped_type > data
Definition: rcpp_table.h:300
Table::insert
void insert(I0 key0, I1 key1, I2 key2, I3 key3, I4 key4, Outcome outcome)
Definition: rcpp_table.h:160
Table< key_type, mapped_type >::operator()
virtual mapped_type operator()(key_type key)
Definition: rcpp_table.h:312
Table::axis
Axis axis
Definition: rcpp_table.h:188
Table::operator()
virtual Outcome operator()(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4)
Definition: rcpp_table.h:169
set_lower_bound
T set_lower_bound(set< T, greater< T > > aset, T value)
Definition: rcpp_table.h:116
Table< I0, I1, Outcome >::Table
Table()
Definition: rcpp_table.h:279
Table::mapped_type
Outcome mapped_type
Definition: rcpp_table.h:152
NumericInterpolate
Definition: rcpp_table.h:53
Table< I0, I1, I2, Outcome >::Table
Table(const DataFrame &df, string s0, string s1, string s2, string s3)
Definition: rcpp_table.h:256
Table< I0, I1, I2, I3, Outcome >::Table
Table(const DataFrame &df, string s0, string s1, string s2, string s3, string s4)
Definition: rcpp_table.h:218
Table< key_type, mapped_type >::insert
void insert(const key_type &key, const mapped_type &outcome)
Definition: rcpp_table.h:308
DataFrameSelect::size
int size()
Definition: rcpp_table.h:133
Table< I0, I1, I2, Outcome >::operator()
virtual Outcome operator()(I0 i0, I1 i1, I2 i2)
Definition: rcpp_table.h:251
Table< I0, I1, Outcome >::insert
void insert(I0 key0, I1 key1, mapped_type outcome)
Definition: rcpp_table.h:280
NumericInterpolate::invert
double invert(double yfind, double xentry)
Definition: rcpp_table.h:99
Table< I0, I1, I2, I3, Outcome >::axis
Axis axis
Definition: rcpp_table.h:229
Table::key_type
boost::tuple< I0, I1, I2, I3, I4 > key_type
Definition: rcpp_table.h:151
Table< I0, I1, I2, Outcome >::Axis
boost::tuple< set< I0, greater< I0 > >, set< I1, greater< I1 > >, set< I2, greater< I2 > > > Axis
Definition: rcpp_table.h:242
Table< I0, I1, I2, I3, Outcome >::key_type
boost::tuple< I0, I1, I2, I3 > key_type
Definition: rcpp_table.h:195
Table< I0, I1, Outcome >::mapped_type
Outcome mapped_type
Definition: rcpp_table.h:274
Table< I0, I1, Outcome >::Axis
boost::tuple< set< I0, greater< I0 > >, set< I1, greater< I1 > > > Axis
Definition: rcpp_table.h:278
Table< key_type, mapped_type >::axis
Axis axis
Definition: rcpp_table.h:323
Table< I0, I1, I2, I3, Outcome >::insert
void insert(I0 key0, I1 key1, I2 key2, I3 key3, mapped_type outcome)
Definition: rcpp_table.h:204