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