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;
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 
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>
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:
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:
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:
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:
300  map<key_type,mapped_type> data;
301 };
302 
303 template<class key_type, class 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:
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