-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathev_record.hpp
286 lines (266 loc) · 9.16 KB
/
ev_record.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/**
* @file ev_record.hpp
* @author Yi Zhang <[email protected]>
* @date Wed Aug 26 23:43:13 2020
*
* @brief raw event record
*
*
*/
#ifndef STAN_MATH_TORSTEN_NONMEN_EVENTS_RECORD_HPP
#define STAN_MATH_TORSTEN_NONMEN_EVENTS_RECORD_HPP
#include <stan/math/prim/fun/value_of.hpp>
#include <stan/math/rev/fun/value_of.hpp>
#include <stan/math/prim/meta/return_type.hpp>
#include <Eigen/Dense>
#include <numeric>
#include <string>
#include <vector>
namespace torsten {
/**
* Raw events record in the form of NONMEN, except that
* for the population input @c len consisting of data record
* length for each individual.
* @tparam T0 type of scalar for time of events.
* @tparam T1 type of scalar for amount at each event.
* @tparam T2 type of scalar for rate at each event.
* @tparam T3 type of scalar for inter-dose inteveral at each event.
* @tparam theta_container type of container for parameter. <code>linode</code> model uses
* matrix as parameter, other than <code>std::vector</code> used by others.
*/
template <typename T0, typename T1, typename T2, typename T3>
struct NONMENEventsRecord {
using T_scalar = typename stan::return_type_t<T0, T1, T2, T3>;
using T_time = typename stan::return_type_t<T0, T1, T2, T3>;
using T_rate = T2;
using T_amt = T1;
using T_par_rate = T2;
using T_par_ii = T3;
private:
/// <code>len</code> needs actual variable to ref to.
const std::vector<int> len_1_;
public:
static const double lag_time_min; /**< minimum lag time allowed */
/// nb. of compartments
const int ncmt;
/// begin id for each subject in concat vector <code>time_</code>, etc
std::vector<int> begin_;
/// data length for each subject
const std::vector<int>& len_;
/// nb. of events in the entire population
const int total_num_event_times;
/// event time
const std::vector<T0>& time_;
/// dosing amount
const std::vector<T1>& amt_;
/// dosing rate
const std::vector<T2>& rate_;
/// dosing interval
const std::vector<T3>& ii_;
/// dosing event id\n
/// (0) observation\n
/// (1) dosing\n
/// (2) other\n
/// (3) reset\n
/// (4) reset AND dosing
const std::vector<int>& evid_;
/// event compartment
const std::vector<int>& cmt_;
/// nb. of additional doses
const std::vector<int>& addl_;
/// steady-states flag
const std::vector<int>& ss_;
/**
* Constructor using population data with parameter give as
* matrix, such as in linear ODE models
* @param[in] n number of compartments in model
* @param[in] len record length for each individual.
* @param[in] time times of events
* @param[in] amt amount at each event
* @param[in] rate rate at each event
* @param[in] ii inter-dose interval at each event
* @param[in] evid event identity: \n
* (0) observation\n
* (1) dosing\n
* (2) other \n
* (3) reset \n
* (4) reset AND dosing
* @param[in] cmt compartment number at each event
* @param[in] addl additional dosing at each event
* @param[in] ss steady state approximation at each event (0: no, 1: yes)
*/
template <typename T0_, typename T1_, typename T2_, typename T3_>
NONMENEventsRecord(int n,
const std::vector<int>& len,
const std::vector<T0_>& time,
const std::vector<T1_>& amt,
const std::vector<T2_>& rate,
const std::vector<T3_>& ii,
const std::vector<int>& evid,
const std::vector<int>& cmt,
const std::vector<int>& addl,
const std::vector<int>& ss) :
len_1_(),
ncmt(n),
begin_(len.size()),
len_(len),
total_num_event_times(std::accumulate(len_.begin(), len_.end(), 0)),
time_ (time ),
amt_ (amt ),
rate_ (rate ),
ii_ (ii ),
evid_ (evid ),
cmt_ (cmt ),
addl_ (addl ),
ss_ (ss )
{
begin_[0] = 0;
std::partial_sum(len.begin(), len.end() - 1, begin_.begin() + 1);
}
/**
* Constructor using individual data with parameter give as
* matrix, such as in linear ODE models
* @param[in] n number of compartments in model
* @param[in] time times of events
* @param[in] amt amount at each event
* @param[in] rate rate at each event
* @param[in] ii inter-dose interval at each event
* @param[in] evid event identity: \n
* (0) observation \n
* (1) dosing\n
* (2) other \n
* (3) reset \n
* (4) reset AND dosing
* @param[in] cmt compartment number at each event
* @param[in] addl additional dosing at each event
* @param[in] ss steady state approximation at each event (0: no, 1: yes)
*/
template <typename T0_, typename T1_, typename T2_, typename T3_>
NONMENEventsRecord(int n,
const std::vector<T0_>& time,
const std::vector<T1_>& amt,
const std::vector<T2_>& rate,
const std::vector<T3_>& ii,
const std::vector<int>& evid,
const std::vector<int>& cmt,
const std::vector<int>& addl,
const std::vector<int>& ss) :
len_1_(1, time.size()),
ncmt(n),
begin_{0},
len_(len_1_),
total_num_event_times(std::accumulate(len_.begin(), len_.end(), 0)),
time_ (time ),
amt_ (amt ),
rate_ (rate ),
ii_ (ii ),
evid_ (evid ),
cmt_ (cmt ),
addl_ (addl ),
ss_ (ss )
{}
/**
* begin of parameters for a subject @c id
* in @c pMatrix. It is assumed that all the paramter are
* either constant or time dependent.
*
* @param id subject id
*
* @return begin index in @c pMatrix for the subject
*/
template<typename T>
int begin_param(int id, const std::vector<T>& param) const {
return param.size() == len_.size() ? id : begin_[id];
}
/**
* length of parameters for a subject @c id
* in @c pMatrix. It is assumed that all the paramter are
* either constant or time dependent.
*
* @param id subject id
*
* @return len in @c pMatrix for the subject
*/
template<typename T>
int len_param(int id, const std::vector<T>& param) const {
return param.size() == len_.size() ? 1 : len_[id];
}
/**
* check the exisitence of steady state dosing events
* for the 1st subject, used for single-individual data.
*
* @return if the subject has any SS dosing event.
*/
inline bool has_ss_dosing() const {
return has_ss_dosing(0);
}
/**
* check the exisitence of steady state dosing events
*
* @param id subject id
*
* @return if the subject has any SS dosing event.
*/
inline bool has_ss_dosing(int id) const {
bool res = false;
int begin = begin_[id];
int end = size_t(id + 1) == len_.size() ? time_.size() : begin_[id + 1];
for (int i = begin; i < end; ++i) {
if ((evid_[i] == 1 || evid_[i] == 4) && ss_[i] != 0) {
res = true;
break;
}
}
return res;
}
/**
* check the exisitence of time-lagged events
*
* @param id subject id
*
* @return if the subject has any time-lagged dosing event.
*/
template<typename T>
inline bool has_positive_param(int id, const std::vector<std::vector<T>>& params) const {
using stan::math::value_of;
return std::any_of(params.begin() + begin_param(id, params),
params.begin() + begin_param(id, params) + len_param(id, params),
[](const std::vector<T>& v) {
return std::any_of(v.begin(), v.end(), [](const T& x) { return std::abs(value_of(x)) > lag_time_min; });
});
}
/**
* check the exisitence of time-lagged dosing events
* for the 1st subject, used for single-individual data.
*
* @return if the subject has any time-lagged dosing event.
*/
template<typename T>
inline bool has_positive_param(const std::vector<std::vector<T>>& params) const {
return has_positive_param(0, params);
}
/**
* @param id subject id
*
* @return nb. of events for the subject
*/
inline int num_event_times(int id) const {
return len_.at(id);
}
/**
* @return nb. of events for subject 0.
*/
inline int num_event_times() const {
return len_.at(0);
}
/**
* @return population size.
*/
inline int num_subjects() const {
return len_.size();
}
};
template <typename T0, typename T1, typename T2, typename T3>
const double NONMENEventsRecord<T0, T1, T2, T3>::lag_time_min = 1.e-12;
}
#endif