108 const Eigen::VectorXd& R,
109 const Eigen::VectorXd& g,
double pop,
110 int use_pop,
double pop_floor,
int nht,
112 const int u0 = seed.size();
113 const int ot = R.size();
114 const int G = g.size();
115 st.I = Eigen::VectorXd::Zero(u0 + ot);
116 st.I.head(u0) = seed;
117 st.lambda.resize(ot);
121 st.flag = Eigen::VectorXd::Zero(ot);
122 double C = use_pop ? seed.sum() : 0.0;
123 for (
int s = 0; s < ot; ++s) {
124 const int u = u0 + s;
125 const int K = std::min(G, u + 1) - 1;
127 = K > 0 ? st.I.segment(u - K, K).dot(g.segment(G - 1 - K, K)) : 0.0;
128 st.lambda(s) = lambda;
131 const double sraw = pop - C;
132 const bool s_active = sraw >= pop_floor;
133 const double S = s_active ? sraw : pop_floor;
134 const double a = R(s) * lambda / S;
135 const double e = std::exp(-a);
136 const double h = 1.0 - e;
137 const bool h_active = h >= 0.0;
138 st.flag(s) = 1 + 2 * s_active + 4 * h_active;
142 inf = S * (h_active ? h : 0.0);
147 if (use_pop && s < ot - 1) {
168 const Eigen::VectorXd& g,
int use_pop,
169 const Eigen::VectorXd& Ibar_in,
170 Eigen::VectorXd& seedbar, Eigen::VectorXd& Rbar,
171 Eigen::VectorXd& gbar,
double& popbar) {
172 const int ot = R.size();
173 const int G = g.size();
174 const int u0 = st.I.size() - ot;
175 Eigen::VectorXd Ibar = Ibar_in;
177 for (
int s = ot - 1; s >= 0; --s) {
178 const int u = u0 + s;
179 if (use_pop && s < ot - 1) {
182 const double ib = Ibar(u);
184 const int flag =
static_cast<int>(st.flag(s));
186 const double S = st.S(s);
189 const double abar = ib * S * st.e(s);
190 Sbar = ib * (1.0 - st.e(s)) - abar * st.a(s) / S;
191 Rbar(s) += abar * st.lambda(s) / S;
192 lambdabar = abar * R(s) / S;
201 Rbar(s) += ib * st.lambda(s);
202 lambdabar = ib * R(s);
204 const int K = std::min(G, u + 1) - 1;
206 Ibar.segment(u - K, K) += lambdabar * g.segment(G - 1 - K, K);
207 gbar.segment(G - 1 - K, K) += lambdabar * st.I.segment(u - K, K);
210 seedbar = Ibar.head(u0);
212 seedbar.array() += Cbar;
238inline Eigen::Matrix<stan::return_type_t<T0, T1, T2, T3>, Eigen::Dynamic, 1>
240 const int& use_pop,
const double& pop_floor,
const int& nht,
243 using stan::math::var;
244 using stan::math::value_of;
245 constexpr bool seed_var = stan::is_var<stan::value_type_t<T0>>::value;
246 constexpr bool R_var = stan::is_var<stan::value_type_t<T1>>::value;
247 constexpr bool g_var = stan::is_var<stan::value_type_t<T2>>::value;
248 constexpr bool pop_var = stan::is_var<T3>::value;
249 if (seed.size() < 1) {
250 throw std::domain_error(
"renewal_infections: seeding time must be >= 1");
252 const double pop_d = value_of(pop);
253 if constexpr (!seed_var && !R_var && !g_var && !pop_var) {
256 use_pop, pop_floor, nht, st);
259 arena_t<Eigen::Matrix<stan::value_type_t<T0>, -1, 1>> seed_a = seed;
260 arena_t<Eigen::Matrix<stan::value_type_t<T1>, -1, 1>> R_a = R;
261 arena_t<Eigen::Matrix<stan::value_type_t<T2>, -1, 1>> g_a = g;
262 arena_t<Eigen::VectorXd> R_val = value_of(R_a);
263 arena_t<Eigen::VectorXd> g_val = value_of(g_a);
266 pop_floor, nht, fwd);
269 const int n = fwd.
I.size();
270 arena_t<Eigen::Matrix<var, -1, 1>> res(n);
271 for (
int i = 0; i < n; ++i) {
272 res.coeffRef(i) = var(fwd.
I(i));
275 stan::math::reverse_pass_callback([=]()
mutable {
276 Eigen::VectorXd seedbar;
277 Eigen::VectorXd Rbar = Eigen::VectorXd::Zero(R_val.size());
278 Eigen::VectorXd gbar = Eigen::VectorXd::Zero(g_val.size());
281 seedbar, Rbar, gbar, popbar);
282 if constexpr (seed_var) {
283 seed_a.adj() += seedbar;
285 if constexpr (R_var) {
288 if constexpr (g_var) {
291 if constexpr (pop_var) {
292 pop_v.adj() += popbar;
295 return Eigen::Matrix<var, -1, 1>(res);
void renewal_forward(const Eigen::VectorXd &seed, const Eigen::VectorXd &R, const Eigen::VectorXd &g, double pop, int use_pop, double pop_floor, int nht, State &st)
void renewal_reverse(const State &st, const Eigen::VectorXd &R, const Eigen::VectorXd &g, int use_pop, const Eigen::VectorXd &Ibar_in, Eigen::VectorXd &seedbar, Eigen::VectorXd &Rbar, Eigen::VectorXd &gbar, double &popbar)
Eigen::Matrix< stan::return_type_t< T0, T1, T2, T3 >, Eigen::Dynamic, 1 > renewal_infections(const T0 &seed, const T1 &R, const T2 &g, const T3 &pop, const int &use_pop, const double &pop_floor, const int &nht, std::ostream *)