1 #ifndef STAN_MATH_REV_ARR_FUNCTOR_COUPLED_ODE_SYSTEM_HPP
2 #define STAN_MATH_REV_ARR_FUNCTOR_COUPLED_ODE_SYSTEM_HPP
32 std::vector<std::vector<stan::math::var> >& y) {
33 for (
size_t n = 0; n < y.size(); n++)
34 for (
size_t m = 0; m < y0.size(); m++)
63 const std::vector<stan::math::var>&
theta_;
65 const std::vector<double>&
x_;
85 const std::vector<double>& y0,
86 const std::vector<stan::math::var>& theta,
87 const std::vector<double>& x,
88 const std::vector<int>& x_int,
93 theta_dbl_(theta.
size(), 0.0),
100 for (
size_t m = 0; m <
M_; m++)
119 std::vector<double>& dy_dt,
124 vector<double> y_base(y.begin(), y.begin()+
N_);
125 dy_dt = f_(t, y_base, theta_dbl_, x_, x_int_, msgs_);
127 "dy_dt", dy_dt.size(),
N_);
129 vector<double> coupled_sys(
N_ *
M_);
130 vector<var> theta_temp;
132 vector<var> dy_dt_temp;
136 for (
size_t i = 0; i <
N_; i++) {
144 for (
size_t j = 0; j <
N_; j++) {
145 y_temp.push_back(y[j]);
146 vars.push_back(y_temp[j]);
149 for (
size_t j = 0; j <
M_; j++) {
150 theta_temp.push_back(theta_dbl_[j]);
151 vars.push_back(theta_temp[j]);
153 dy_dt_temp = f_(t, y_temp, theta_temp, x_, x_int_, msgs_);
154 dy_dt_temp[i].grad(vars, grad);
156 for (
size_t j = 0; j <
M_; j++) {
160 double temp_deriv = grad[y_temp.size() + j];
161 for (
size_t k = 0; k <
N_; k++)
162 temp_deriv += y[N_ + N_ * j + k] * grad[k];
164 coupled_sys[i + j *
N_] = temp_deriv;
166 }
catch (
const std::exception&
e) {
173 dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
199 std::vector<double> state(
size_, 0.0);
200 for (
size_t n = 0; n <
N_; n++)
201 state[n] = y0_dbl_[n];
212 std::vector<std::vector<stan::math::var> >
215 std::vector<stan::math::var> temp_vars;
216 std::vector<double> temp_gradients;
217 std::vector<std::vector<stan::math::var> > y_return(y.size());
219 for (
size_t i = 0; i < y.size(); i++) {
223 for (
size_t j = 0; j <
N_; j++) {
224 temp_gradients.clear();
227 for (
size_t k = 0; k <
M_; k++)
228 temp_gradients.push_back(y[i][y0_dbl_.size()
229 + y0_dbl_.size() * k + j]);
235 y_return[i] = temp_vars;
273 template <
typename F>
276 const std::vector<stan::math::var>&
y0_;
279 const std::vector<double>&
x_;
300 const std::vector<stan::math::var>& y0,
301 const std::vector<double>& theta,
302 const std::vector<double>& x,
303 const std::vector<int>& x_int,
307 y0_dbl_(y0.
size(), 0.0),
315 for (
size_t n = 0; n <
N_; n++)
333 std::vector<double>& dy_dt,
335 std::vector<double> y_base(y.begin(), y.begin() +
N_);
336 for (
size_t n = 0; n <
N_; n++)
337 y_base[n] += y0_dbl_[n];
339 dy_dt = f_(t, y_base, theta_dbl_, x_, x_int_, msgs_);
341 "dy_dt", dy_dt.size(),
N_);
343 std::vector<double> coupled_sys(N_ * N_);
345 std::vector<stan::math::var> y_temp;
346 std::vector<stan::math::var> dy_dt_temp;
347 std::vector<double>
grad;
348 std::vector<stan::math::var> vars;
350 for (
size_t i = 0; i <
N_; i++) {
357 for (
size_t j = 0; j <
N_; j++) {
358 y_temp.push_back(y[j] + y0_dbl_[j]);
359 vars.push_back(y_temp[j]);
362 dy_dt_temp = f_(t, y_temp, theta_dbl_, x_, x_int_, msgs_);
363 dy_dt_temp[i].grad(vars, grad);
365 for (
size_t j = 0; j <
N_; j++) {
369 double temp_deriv = grad[j];
370 for (
size_t k = 0; k <
N_; k++)
371 temp_deriv += y[N_ + N_ * j + k] * grad[k];
373 coupled_sys[i+j*
N_] = temp_deriv;
375 }
catch (
const std::exception&
e) {
382 dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
409 return std::vector<double>(
size_, 0.0);
419 std::vector<std::vector<stan::math::var> >
425 vector<var> temp_vars;
426 vector<double> temp_gradients;
427 vector<vector<var> > y_return(y.size());
429 for (
size_t i = 0; i < y.size(); i++) {
433 for (
size_t j = 0; j <
N_; j++) {
434 temp_gradients.clear();
437 for (
size_t k = 0; k <
N_; k++)
438 temp_gradients.push_back(y[i][y0_.size() + y0_.size() * k + j]);
441 y0_, temp_gradients));
444 y_return[i] = temp_vars;
494 template <
typename F>
497 const std::vector<stan::math::var>&
y0_;
499 const std::vector<stan::math::var>&
theta_;
501 const std::vector<double>&
x_;
522 const std::vector<stan::math::var>& y0,
523 const std::vector<stan::math::var>& theta,
524 const std::vector<double>& x,
525 const std::vector<int>& x_int,
529 y0_dbl_(y0.
size(), 0.0),
531 theta_dbl_(theta.
size(), 0.0),
538 for (
size_t n = 0; n <
N_; n++)
541 for (
size_t m = 0; m <
M_; m++)
559 std::vector<double>& dy_dt,
564 vector<double> y_base(y.begin(), y.begin()+
N_);
565 for (
size_t n = 0; n <
N_; n++)
566 y_base[n] += y0_dbl_[n];
568 dy_dt = f_(t, y_base, theta_dbl_, x_, x_int_, msgs_);
570 "dy_dt", dy_dt.size(),
N_);
572 vector<double> coupled_sys(N_ * (N_ +
M_));
573 vector<var> theta_temp;
575 vector<var> dy_dt_temp;
579 for (
size_t i = 0; i <
N_; i++) {
588 for (
size_t j = 0; j <
N_; j++) {
589 y_temp.push_back(y[j] + y0_dbl_[j]);
590 vars.push_back(y_temp[j]);
593 for (
size_t j = 0; j <
M_; j++) {
594 theta_temp.push_back(theta_dbl_[j]);
595 vars.push_back(theta_temp[j]);
598 dy_dt_temp = f_(t, y_temp, theta_temp, x_, x_int_, msgs_);
599 dy_dt_temp[i].grad(vars, grad);
601 for (
size_t j = 0; j < N_+
M_; j++) {
605 double temp_deriv = grad[j];
606 for (
size_t k = 0; k <
N_; k++)
607 temp_deriv += y[N_ + N_ * j + k] * grad[k];
609 coupled_sys[i + j *
N_] = temp_deriv;
611 }
catch (
const std::exception&
e) {
617 dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
641 return std::vector<double>(
size_, 0.0);
651 std::vector<std::vector<stan::math::var> >
657 vector<var> vars = y0_;
658 vars.insert(vars.end(), theta_.begin(), theta_.end());
660 vector<var> temp_vars;
661 vector<double> temp_gradients;
662 vector<vector<var> > y_return(y.size());
664 for (
size_t i = 0; i < y.size(); i++) {
668 for (
size_t j = 0; j <
N_; j++) {
669 temp_gradients.clear();
672 for (
size_t k = 0; k < N_ +
M_; k++)
673 temp_gradients.push_back(y[i][N_ + N_ * k + j]);
676 vars, temp_gradients));
678 y_return[i] = temp_vars;
var precomputed_gradients(const double value, const std::vector< var > &operands, const std::vector< double > &gradients)
This function returns a var for an expression that has the specified value, vector of operands...
std::vector< std::vector< stan::math::var > > decouple_states(const std::vector< std::vector< double > > &y)
Returns the base ODE system state corresponding to the specified coupled system state.
const std::vector< stan::math::var > & theta_
std::vector< double > y0_dbl_
std::vector< std::vector< stan::math::var > > decouple_states(const std::vector< std::vector< double > > &y)
Return the solutions to the basic ODE system, including appropriate autodiff partial derivatives...
coupled_ode_system(const F &f, const std::vector< double > &y0, const std::vector< stan::math::var > &theta, const std::vector< double > &x, const std::vector< int > &x_int, std::ostream *msgs)
Construct a coupled ODE system with the specified base ODE system, base initial state, parameters, data, and a message stream.
std::vector< double > theta_dbl_
T value_of(const fvar< T > &v)
Return the value of the specified variable.
static void grad(chainable *vi)
Compute the gradient for all variables starting from the specified root variable implementation.
std::vector< double > initial_state()
Returns the initial state of the coupled system.
std::vector< std::vector< stan::math::var > > decouple_states(const std::vector< std::vector< double > > &y)
Return the basic ODE solutions given the specified coupled system solutions, including the partials v...
Independent (input) and dependent (output) variables for gradients.
size_t size() const
Returns the size of the coupled system.
std::vector< double > theta_dbl_
const std::vector< double > & theta_dbl_
void operator()(const std::vector< double > &y, std::vector< double > &dy_dt, double t)
Assign the derivative vector with the system derivatives at the specified state and time...
std::vector< double > initial_state()
Returns the initial state of the coupled system.
coupled_ode_system(const F &f, const std::vector< stan::math::var > &y0, const std::vector< double > &theta, const std::vector< double > &x, const std::vector< int > &x_int, std::ostream *msgs)
Construct a coupled ODE system for an unknown initial state and known parameters givne the specified ...
void operator()(const std::vector< double > &y, std::vector< double > &dy_dt, double t)
Populates the derivative vector with derivatives of the coupled ODE system state with respect to time...
const std::vector< int > & x_int_
bool check_equal(const char *function, const char *name, const T_y &y, const T_eq &eq)
Return true if y is equal to eq.
const std::vector< double > & y0_dbl_
void add_initial_values(const std::vector< stan::math::var > &y0, std::vector< std::vector< stan::math::var > > &y)
Increment the state derived from the coupled system in the with the original initial state...
const std::vector< double > & x_
const std::vector< int > & x_int_
void operator()(const std::vector< double > &y, std::vector< double > &dy_dt, double t)
Calculates the derivative of the coupled ode system with respect to the state y at time t...
double e()
Return the base of the natural logarithm.
const std::vector< stan::math::var > & y0_
std::vector< double > initial_state()
Returns the initial state of the coupled system.
int size(const std::vector< T > &x)
const std::vector< stan::math::var > & theta_
coupled_ode_system(const F &f, const std::vector< stan::math::var > &y0, const std::vector< stan::math::var > &theta, const std::vector< double > &x, const std::vector< int > &x_int, std::ostream *msgs)
Construct a coupled ODE system with unknown initial value and known parameters, given the base ODE sy...
const std::vector< double > & x_
const std::vector< double > & x_
Base template class for a coupled ordinary differential equation system, which adds sensitivities to ...
static void recover_memory_nested()
Recover only the memory used for the top nested call.
const std::vector< stan::math::var > & y0_
std::vector< double > y0_dbl_
size_t size() const
Returns the size of the coupled system.
size_t size() const
Returns the size of the coupled system.
const std::vector< int > & x_int_
static void start_nested()
Record the current position so that recover_memory_nested() can find it.