1 #ifndef STAN__AGRAD__REV__ODE__COUPLED_ODE_SYSTEM_HPP
2 #define STAN__AGRAD__REV__ODE__COUPLED_ODE_SYSTEM_HPP
35 std::vector<std::vector<stan::agrad::var> >& y) {
36 for (
size_t n = 0; n < y.size(); n++)
37 for (
size_t m = 0; m < y0.size(); m++)
67 const std::vector<stan::agrad::var>&
theta_;
69 const std::vector<double>&
x_;
89 const std::vector<double>& y0,
90 const std::vector<stan::agrad::var>& theta,
91 const std::vector<double>& x,
92 const std::vector<int>& x_int,
97 theta_dbl_(theta.
size(), 0.0),
105 for (
int m = 0; m <
M_; m++)
124 std::vector<double>& dy_dt,
129 vector<double> y_base(y.begin(), y.begin()+
N_);
130 dy_dt = f_(t,y_base,theta_dbl_,x_,x_int_,msgs_);
132 dy_dt.size(),
N_,
"dy_dt",
133 static_cast<double*
>(0));
135 vector<double> coupled_sys(
N_ *
M_);
136 vector<var> theta_temp;
138 vector<var> dy_dt_temp;
142 for (
int i = 0; i <
N_; i++) {
150 for (
int j = 0; j <
N_; j++) {
151 y_temp.push_back(y[j]);
152 vars.push_back(y_temp[j]);
155 for (
int j = 0; j <
M_; j++) {
156 theta_temp.push_back(theta_dbl_[j]);
157 vars.push_back(theta_temp[j]);
159 dy_dt_temp = f_(t,y_temp,theta_temp,x_,x_int_,msgs_);
160 dy_dt_temp[i].grad(vars, grad);
162 for (
int j = 0; j <
M_; j++) {
166 double temp_deriv = grad[y_temp.size() + j];
167 for (
int k = 0; k <
N_; k++)
168 temp_deriv += y[N_ + N_ * j + k] * grad[k];
170 coupled_sys[i + j *
N_] = temp_deriv;
172 }
catch (
const std::exception&
e) {
179 dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
205 std::vector<double> state(
size_, 0.0);
206 for (
int n = 0; n <
N_; n++)
207 state[n] = y0_dbl_[n];
218 std::vector<std::vector<stan::agrad::var> >
221 std::vector<stan::agrad::var> temp_vars;
222 std::vector<double> temp_gradients;
223 std::vector<std::vector<stan::agrad::var> > y_return(y.size());
225 for (
size_t i = 0; i < y.size(); i++) {
229 for (
size_t j = 0; j <
N_; j++) {
230 temp_gradients.clear();
233 for (
size_t k = 0; k <
M_; k++)
234 temp_gradients.push_back(y[i][y0_dbl_.size()
235 + y0_dbl_.size() * k + j]);
241 y_return[i] = temp_vars;
280 template <
typename F>
284 const std::vector<stan::agrad::var>&
y0_;
287 const std::vector<double>&
x_;
308 const std::vector<stan::agrad::var>& y0,
309 const std::vector<double>& theta,
310 const std::vector<double>& x,
311 const std::vector<int>& x_int,
315 y0_dbl_(y0.
size(), 0.0),
324 for (
int n = 0; n <
N_; n++)
342 std::vector<double>& dy_dt,
344 std::vector<double> y_base(y.begin(), y.begin() +
N_);
345 for (
int n = 0; n <
N_; n++)
346 y_base[n] += y0_dbl_[n];
348 dy_dt = f_(t,y_base,theta_dbl_,x_,x_int_,msgs_);
350 dy_dt.size(),
N_,
"dy_dt",
351 static_cast<double*
>(0));
353 std::vector<double> coupled_sys(N_ * N_);
355 std::vector<stan::agrad::var> y_temp;
356 std::vector<stan::agrad::var> dy_dt_temp;
357 std::vector<double>
grad;
358 std::vector<stan::agrad::var> vars;
360 for (
int i = 0; i <
N_; i++) {
367 for (
int j = 0; j <
N_; j++) {
368 y_temp.push_back(y[j] + y0_dbl_[j]);
369 vars.push_back(y_temp[j]);
372 dy_dt_temp = f_(t,y_temp,theta_dbl_,x_,x_int_,msgs_);
373 dy_dt_temp[i].grad(vars, grad);
375 for (
int j = 0; j <
N_; j++) {
379 double temp_deriv = grad[j];
380 for (
int k = 0; k <
N_; k++)
381 temp_deriv += y[N_ + N_ * j + k] * grad[k];
383 coupled_sys[i+j*
N_] = temp_deriv;
385 }
catch (
const std::exception&
e) {
392 dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
419 return std::vector<double>(
size_, 0.0);
429 std::vector<std::vector<stan::agrad::var> >
435 vector<var> temp_vars;
436 vector<double> temp_gradients;
437 vector<vector<var> > y_return(y.size());
439 for (
size_t i = 0; i < y.size(); i++) {
443 for (
size_t j = 0; j <
N_; j++) {
444 temp_gradients.clear();
447 for (
size_t k = 0; k <
N_; k++)
448 temp_gradients.push_back(y[i][y0_.size() + y0_.size() * k + j]);
451 y0_, temp_gradients));
454 y_return[i] = temp_vars;
505 template <
typename F>
508 const std::vector<stan::agrad::var>&
y0_;
510 const std::vector<stan::agrad::var>&
theta_;
512 const std::vector<double>&
x_;
533 const std::vector<stan::agrad::var>& y0,
534 const std::vector<stan::agrad::var>& theta,
535 const std::vector<double>& x,
536 const std::vector<int>& x_int,
540 y0_dbl_(y0.
size(), 0.0),
542 theta_dbl_(theta.
size(), 0.0),
550 for (
int n = 0; n <
N_; n++)
553 for (
int m = 0; m <
M_; m++)
571 std::vector<double>& dy_dt,
576 vector<double> y_base(y.begin(), y.begin()+
N_);
577 for (
int n = 0; n <
N_; n++)
578 y_base[n] += y0_dbl_[n];
580 dy_dt = f_(t,y_base,theta_dbl_,x_,x_int_,msgs_);
582 dy_dt.size(),
N_,
"dy_dt",
583 static_cast<double*
>(0));
585 vector<double> coupled_sys(N_ * (N_ +
M_));
586 vector<var> theta_temp;
588 vector<var> dy_dt_temp;
592 for (
int i = 0; i <
N_; i++) {
601 for (
int j = 0; j <
N_; j++) {
602 y_temp.push_back(y[j] + y0_dbl_[j]);
603 vars.push_back(y_temp[j]);
606 for (
int j = 0; j <
M_; j++) {
607 theta_temp.push_back(theta_dbl_[j]);
608 vars.push_back(theta_temp[j]);
611 dy_dt_temp = f_(t,y_temp,theta_temp,x_,x_int_,msgs_);
612 dy_dt_temp[i].grad(vars, grad);
614 for (
int j = 0; j < N_+
M_; j++) {
618 double temp_deriv = grad[j];
619 for (
int k = 0; k <
N_; k++)
620 temp_deriv += y[N_ + N_ * j + k] * grad[k];
622 coupled_sys[i + j *
N_] = temp_deriv;
624 }
catch (
const std::exception&
e) {
630 dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
654 return std::vector<double>(
size_, 0.0);
664 std::vector<std::vector<stan::agrad::var> >
670 vector<var> vars = y0_;
671 vars.insert(vars.end(), theta_.begin(), theta_.end());
673 vector<var> temp_vars;
674 vector<double> temp_gradients;
675 vector<vector<var> > y_return(y.size());
677 for (
size_t i = 0; i < y.size(); i++) {
681 for (
size_t j = 0; j <
N_; j++) {
682 temp_gradients.clear();
685 for (
size_t k = 0; k < N_ +
M_; k++)
686 temp_gradients.push_back(y[i][N_ + N_ * k + j]);
689 vars, temp_gradients));
691 y_return[i] = temp_vars;
bool check_equal(const char *function, const T_y &y, const T_eq &eq, const char *name, T_result *result)
const std::vector< double > & y0_dbl_
const std::vector< stan::agrad::var > & theta_
int size() const
Returns the size of the coupled system.
static void start_nested()
Record the current position so that recover_memory_nested() can find it.
const std::vector< int > & x_int_
var precomputed_gradients(const double value, const std::vector< var > &vars, const std::vector< double > &gradients)
This function is provided for Stan users that want to compute gradients without using Stan's auto-dif...
std::vector< double > y0_dbl_
int size() const
Returns the size of the coupled system.
static void grad(chainable *vi)
Compute the gradient for all variables starting from the specified root variable implementation.
const std::vector< double > & x_
std::vector< std::vector< stan::agrad::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...
T value_of(const fvar< T > &v)
Return the value of the specified variable.
int size() const
Returns the size of the coupled system.
const std::vector< int > & x_int_
coupled_ode_system(const F &f, const std::vector< double > &y0, const std::vector< stan::agrad::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.
const std::vector< stan::agrad::var > & y0_
coupled_ode_system(const F &f, const std::vector< stan::agrad::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)
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.
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...
std::vector< std::vector< stan::agrad::var > > decouple_states(const std::vector< std::vector< double > > &y)
Returns the base ODE system state corresponding to the specified coupled system state.
void add_initial_values(const std::vector< stan::agrad::var > &y0, std::vector< std::vector< stan::agrad::var > > &y)
Increment the state derived from the coupled system in the with the original initial state...
const std::vector< stan::agrad::var > & theta_
std::vector< double > theta_dbl_
std::vector< std::vector< stan::agrad::var > > decouple_states(const std::vector< std::vector< double > > &y)
Return the solutions to the basic ODE system, including appropriate autodiff partial derivatives...
Independent (input) and dependent (output) variables for gradients.
double e()
Return the base of the natural logarithm.
std::vector< double > y0_dbl_
int size(const std::vector< T > &x)
Base template class for a coupled ordinary differential equation system, which adds sensitivities to ...
const std::vector< double > & theta_dbl_
const std::vector< double > & x_
static void recover_memory_nested()
Recover only the memory used for the top nested call.
std::vector< double > initial_state()
Returns the initial state of the coupled system.
std::vector< double > initial_state()
Returns the initial state of the coupled system.
const std::vector< double > & x_
const std::vector< int > & x_int_
coupled_ode_system(const F &f, const std::vector< stan::agrad::var > &y0, const std::vector< stan::agrad::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...
std::vector< double > theta_dbl_
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...
const std::vector< stan::agrad::var > & y0_