All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Groups
coupled_ode_system.hpp
Go to the documentation of this file.
#ifndef STAN_MATH_REV_ARR_FUNCTOR_COUPLED_ODE_SYSTEM_HPP
#define STAN_MATH_REV_ARR_FUNCTOR_COUPLED_ODE_SYSTEM_HPP
#include <stan/math/rev/scal/fun/value_of.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/prim/scal/err/check_equal.hpp>
#include <stan/math/prim/arr/functor/coupled_ode_system.hpp>
#include <ostream>
#include <vector>
namespace stan {
namespace math {
// This code is in this directory because it includes var
// It is in namespace stan::math so that the partial template
// specializations are treated as such.
void add_initial_values(const std::vector<stan::math::var>& y0,
std::vector<std::vector<stan::math::var> >& y) {
for (size_t n = 0; n < y.size(); n++)
for (size_t m = 0; m < y0.size(); m++)
y[n][m] += y0[m];
}
template <typename F>
struct coupled_ode_system <F, double, stan::math::var> {
const F& f_;
const std::vector<double>& y0_dbl_;
const std::vector<stan::math::var>& theta_;
std::vector<double> theta_dbl_;
const std::vector<double>& x_;
const std::vector<int>& x_int_;
const size_t N_;
const size_t M_;
const size_t size_;
std::ostream* msgs_;
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)
: f_(f),
y0_dbl_(y0),
theta_(theta),
theta_dbl_(theta.size(), 0.0),
x_(x),
x_int_(x_int),
N_(y0.size()),
M_(theta.size()),
size_(N_ + N_ * M_),
msgs_(msgs) {
for (size_t m = 0; m < M_; m++)
theta_dbl_[m] = stan::math::value_of(theta[m]);
}
void operator()(const std::vector<double>& y,
std::vector<double>& dy_dt,
double t) {
using std::vector;
using stan::math::var;
vector<double> y_base(y.begin(), y.begin()+N_);
dy_dt = f_(t, y_base, theta_dbl_, x_, x_int_, msgs_);
stan::math::check_equal("coupled_ode_system",
"dy_dt", dy_dt.size(), N_);
vector<double> coupled_sys(N_ * M_);
vector<var> theta_temp;
vector<var> y_temp;
vector<var> dy_dt_temp;
vector<double> grad;
vector<var> vars;
for (size_t i = 0; i < N_; i++) {
theta_temp.clear();
y_temp.clear();
dy_dt_temp.clear();
grad.clear();
vars.clear();
try {
stan::math::start_nested();
for (size_t j = 0; j < N_; j++) {
y_temp.push_back(y[j]);
vars.push_back(y_temp[j]);
}
for (size_t j = 0; j < M_; j++) {
theta_temp.push_back(theta_dbl_[j]);
vars.push_back(theta_temp[j]);
}
dy_dt_temp = f_(t, y_temp, theta_temp, x_, x_int_, msgs_);
dy_dt_temp[i].grad(vars, grad);
for (size_t j = 0; j < M_; j++) {
// orders derivatives by equation (i.e. if there are 2 eqns
// (y1, y2) and 2 parameters (a, b), dy_dt will be ordered as:
// dy1_dt, dy2_dt, dy1_da, dy2_da, dy1_db, dy2_db
double temp_deriv = grad[y_temp.size() + j];
for (size_t k = 0; k < N_; k++)
temp_deriv += y[N_ + N_ * j + k] * grad[k];
coupled_sys[i + j * N_] = temp_deriv;
}
} catch (const std::exception& e) {
stan::math::recover_memory_nested();
throw;
}
stan::math::recover_memory_nested();
}
dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
}
size_t size() const {
return size_;
}
std::vector<double> initial_state() {
std::vector<double> state(size_, 0.0);
for (size_t n = 0; n < N_; n++)
state[n] = y0_dbl_[n];
return state;
}
std::vector<std::vector<stan::math::var> >
decouple_states(const std::vector<std::vector<double> >& y) {
using stan::math::precomputed_gradients;
std::vector<stan::math::var> temp_vars;
std::vector<double> temp_gradients;
std::vector<std::vector<stan::math::var> > y_return(y.size());
for (size_t i = 0; i < y.size(); i++) {
temp_vars.clear();
// iterate over number of equations
for (size_t j = 0; j < N_; j++) {
temp_gradients.clear();
// iterate over parameters for each equation
for (size_t k = 0; k < M_; k++)
temp_gradients.push_back(y[i][y0_dbl_.size()
+ y0_dbl_.size() * k + j]);
temp_vars.push_back(precomputed_gradients(y[i][j],
theta_,
temp_gradients));
}
y_return[i] = temp_vars;
}
return y_return;
}
};
template <typename F>
struct coupled_ode_system <F, stan::math::var, double> {
const F& f_;
const std::vector<stan::math::var>& y0_;
std::vector<double> y0_dbl_;
const std::vector<double>& theta_dbl_;
const std::vector<double>& x_;
const std::vector<int>& x_int_;
std::ostream* msgs_;
const size_t N_;
const size_t M_;
const size_t size_;
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)
: f_(f),
y0_(y0),
y0_dbl_(y0.size(), 0.0),
theta_dbl_(theta),
x_(x),
x_int_(x_int),
msgs_(msgs),
N_(y0.size()),
M_(theta.size()),
size_(N_ + N_ * N_) {
for (size_t n = 0; n < N_; n++)
y0_dbl_[n] = stan::math::value_of(y0_[n]);
}
void operator()(const std::vector<double>& y,
std::vector<double>& dy_dt,
double t) {
std::vector<double> y_base(y.begin(), y.begin() + N_);
for (size_t n = 0; n < N_; n++)
y_base[n] += y0_dbl_[n];
dy_dt = f_(t, y_base, theta_dbl_, x_, x_int_, msgs_);
stan::math::check_equal("coupled_ode_system",
"dy_dt", dy_dt.size(), N_);
std::vector<double> coupled_sys(N_ * N_);
std::vector<stan::math::var> y_temp;
std::vector<stan::math::var> dy_dt_temp;
std::vector<double> grad;
std::vector<stan::math::var> vars;
for (size_t i = 0; i < N_; i++) {
y_temp.clear();
dy_dt_temp.clear();
grad.clear();
vars.clear();
try {
stan::math::start_nested();
for (size_t j = 0; j < N_; j++) {
y_temp.push_back(y[j] + y0_dbl_[j]);
vars.push_back(y_temp[j]);
}
dy_dt_temp = f_(t, y_temp, theta_dbl_, x_, x_int_, msgs_);
dy_dt_temp[i].grad(vars, grad);
for (size_t j = 0; j < N_; j++) {
// orders derivatives by equation (i.e. if there are 2 eqns
// (y1, y2) and 2 parameters (a, b), dy_dt will be ordered as:
// dy1_dt, dy2_dt, dy1_da, dy2_da, dy1_db, dy2_db
double temp_deriv = grad[j];
for (size_t k = 0; k < N_; k++)
temp_deriv += y[N_ + N_ * j + k] * grad[k];
coupled_sys[i+j*N_] = temp_deriv;
}
} catch (const std::exception& e) {
stan::math::recover_memory_nested();
throw;
}
stan::math::recover_memory_nested();
}
dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
}
size_t size() const {
return size_;
}
std::vector<double> initial_state() {
return std::vector<double>(size_, 0.0);
}
std::vector<std::vector<stan::math::var> >
decouple_states(const std::vector<std::vector<double> >& y) {
using stan::math::precomputed_gradients;
using stan::math::var;
using std::vector;
vector<var> temp_vars;
vector<double> temp_gradients;
vector<vector<var> > y_return(y.size());
for (size_t i = 0; i < y.size(); i++) {
temp_vars.clear();
// iterate over number of equations
for (size_t j = 0; j < N_; j++) {
temp_gradients.clear();
// iterate over parameters for each equation
for (size_t k = 0; k < N_; k++)
temp_gradients.push_back(y[i][y0_.size() + y0_.size() * k + j]);
temp_vars.push_back(precomputed_gradients(y[i][j],
y0_, temp_gradients));
}
y_return[i] = temp_vars;
}
add_initial_values(y0_, y_return);
return y_return;
}
};
template <typename F>
struct coupled_ode_system <F, stan::math::var, stan::math::var> {
const F& f_;
const std::vector<stan::math::var>& y0_;
std::vector<double> y0_dbl_;
const std::vector<stan::math::var>& theta_;
std::vector<double> theta_dbl_;
const std::vector<double>& x_;
const std::vector<int>& x_int_;
const size_t N_;
const size_t M_;
const size_t size_;
std::ostream* msgs_;
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)
: f_(f),
y0_(y0),
y0_dbl_(y0.size(), 0.0),
theta_(theta),
theta_dbl_(theta.size(), 0.0),
x_(x),
x_int_(x_int),
N_(y0.size()),
M_(theta.size()),
size_(N_ + N_ * (N_ + M_)),
msgs_(msgs) {
for (size_t n = 0; n < N_; n++)
y0_dbl_[n] = stan::math::value_of(y0[n]);
for (size_t m = 0; m < M_; m++)
theta_dbl_[m] = stan::math::value_of(theta[m]);
}
void operator()(const std::vector<double>& y,
std::vector<double>& dy_dt,
double t) {
using std::vector;
using stan::math::var;
vector<double> y_base(y.begin(), y.begin()+N_);
for (size_t n = 0; n < N_; n++)
y_base[n] += y0_dbl_[n];
dy_dt = f_(t, y_base, theta_dbl_, x_, x_int_, msgs_);
stan::math::check_equal("coupled_ode_system",
"dy_dt", dy_dt.size(), N_);
vector<double> coupled_sys(N_ * (N_ + M_));
vector<var> theta_temp;
vector<var> y_temp;
vector<var> dy_dt_temp;
vector<double> grad;
vector<var> vars;
for (size_t i = 0; i < N_; i++) {
theta_temp.clear();
y_temp.clear();
dy_dt_temp.clear();
grad.clear();
vars.clear();
try {
stan::math::start_nested();
for (size_t j = 0; j < N_; j++) {
y_temp.push_back(y[j] + y0_dbl_[j]);
vars.push_back(y_temp[j]);
}
for (size_t j = 0; j < M_; j++) {
theta_temp.push_back(theta_dbl_[j]);
vars.push_back(theta_temp[j]);
}
dy_dt_temp = f_(t, y_temp, theta_temp, x_, x_int_, msgs_);
dy_dt_temp[i].grad(vars, grad);
for (size_t j = 0; j < N_+M_; j++) {
// orders derivatives by equation (i.e. if there are 2 eqns
// (y1, y2) and 2 parameters (a, b), dy_dt will be ordered as:
// dy1_dt, dy2_dt, dy1_da, dy2_da, dy1_db, dy2_db
double temp_deriv = grad[j];
for (size_t k = 0; k < N_; k++)
temp_deriv += y[N_ + N_ * j + k] * grad[k];
coupled_sys[i + j * N_] = temp_deriv;
}
} catch (const std::exception& e) {
stan::math::recover_memory_nested();
throw;
}
stan::math::recover_memory_nested();
}
dy_dt.insert(dy_dt.end(), coupled_sys.begin(), coupled_sys.end());
}
size_t size() const {
return size_;
}
std::vector<double> initial_state() {
return std::vector<double>(size_, 0.0);
}
std::vector<std::vector<stan::math::var> >
decouple_states(const std::vector<std::vector<double> >& y) {
using std::vector;
using stan::math::var;
using stan::math::precomputed_gradients;
vector<var> vars = y0_;
vars.insert(vars.end(), theta_.begin(), theta_.end());
vector<var> temp_vars;
vector<double> temp_gradients;
vector<vector<var> > y_return(y.size());
for (size_t i = 0; i < y.size(); i++) {
temp_vars.clear();
// iterate over number of equations
for (size_t j = 0; j < N_; j++) {
temp_gradients.clear();
// iterate over parameters for each equation
for (size_t k = 0; k < N_ + M_; k++)
temp_gradients.push_back(y[i][N_ + N_ * k + j]);
temp_vars.push_back(precomputed_gradients(y[i][j],
vars, temp_gradients));
}
y_return[i] = temp_vars;
}
add_initial_values(y0_, y_return);
return y_return;
}
};
}
}
#endif
stan::math::precomputed_gradients
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...
Definition: precomputed_gradients.hpp:98
stan::math::coupled_ode_system< F, stan::math::var, double >::msgs_
std::ostream * msgs_
Definition: coupled_ode_system.hpp:281
core.hpp
stan::math::coupled_ode_system< F, double, stan::math::var >::decouple_states
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.
Definition: coupled_ode_system.hpp:213
stan::math::coupled_ode_system< F, double, stan::math::var >::theta_
const std::vector< stan::math::var > & theta_
Definition: coupled_ode_system.hpp:63
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::y0_dbl_
std::vector< double > y0_dbl_
Definition: coupled_ode_system.hpp:498
stan::math::coupled_ode_system< F, stan::math::var, double >::decouple_states
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...
Definition: coupled_ode_system.hpp:420
stan::math::coupled_ode_system< F, double, stan::math::var >::coupled_ode_system
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.
Definition: coupled_ode_system.hpp:84
stan::math::coupled_ode_system< F, double, stan::math::var >::theta_dbl_
std::vector< double > theta_dbl_
Definition: coupled_ode_system.hpp:64
stan::math::value_of
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition: value_of.hpp:16
stan::math::coupled_ode_system< F, double, stan::math::var >::f_
const F & f_
Definition: coupled_ode_system.hpp:61
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::msgs_
std::ostream * msgs_
Definition: coupled_ode_system.hpp:506
stan::math::grad
static void grad(chainable *vi)
Compute the gradient for all variables starting from the specified root variable implementation.
Definition: grad.hpp:30
stan::math::coupled_ode_system< F, double, stan::math::var >::initial_state
std::vector< double > initial_state()
Returns the initial state of the coupled system.
Definition: coupled_ode_system.hpp:198
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::decouple_states
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...
Definition: coupled_ode_system.hpp:652
stan::math::var
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:32
stan::math::coupled_ode_system< F, double, stan::math::var >::size
size_t size() const
Returns the size of the coupled system.
Definition: coupled_ode_system.hpp:181
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::theta_dbl_
std::vector< double > theta_dbl_
Definition: coupled_ode_system.hpp:500
stan::math::coupled_ode_system< F, stan::math::var, double >::theta_dbl_
const std::vector< double > & theta_dbl_
Definition: coupled_ode_system.hpp:278
M_
int M_
Definition: mdivide_left.hpp:19
stan::math::coupled_ode_system< F, double, stan::math::var >::operator()
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...
Definition: coupled_ode_system.hpp:118
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::f_
const F & f_
Definition: coupled_ode_system.hpp:496
size_
size_t size_
Definition: dot_self.hpp:18
stan::math::coupled_ode_system< F, stan::math::var, double >::initial_state
std::vector< double > initial_state()
Returns the initial state of the coupled system.
Definition: coupled_ode_system.hpp:408
stan::math::coupled_ode_system< F, stan::math::var, double >::coupled_ode_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 ...
Definition: coupled_ode_system.hpp:299
check_equal.hpp
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::N_
const size_t N_
Definition: coupled_ode_system.hpp:503
stan::math::coupled_ode_system< F, double, stan::math::var >::N_
const size_t N_
Definition: coupled_ode_system.hpp:67
stan::math::coupled_ode_system< F, stan::math::var, double >::size_
const size_t size_
Definition: coupled_ode_system.hpp:284
stan::math::coupled_ode_system< F, double, stan::math::var >::msgs_
std::ostream * msgs_
Definition: coupled_ode_system.hpp:70
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::operator()
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...
Definition: coupled_ode_system.hpp:558
stan::math::coupled_ode_system< F, stan::math::var, double >::x_int_
const std::vector< int > & x_int_
Definition: coupled_ode_system.hpp:280
stan::math::check_equal
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.
Definition: check_equal.hpp:90
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::M_
const size_t M_
Definition: coupled_ode_system.hpp:504
stan::math::coupled_ode_system< F, double, stan::math::var >::y0_dbl_
const std::vector< double > & y0_dbl_
Definition: coupled_ode_system.hpp:62
stan::math::add_initial_values
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...
Definition: coupled_ode_system.hpp:31
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::x_
const std::vector< double > & x_
Definition: coupled_ode_system.hpp:501
stan::math::coupled_ode_system< F, double, stan::math::var >::x_int_
const std::vector< int > & x_int_
Definition: coupled_ode_system.hpp:66
stan::math::coupled_ode_system< F, stan::math::var, double >::operator()
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...
Definition: coupled_ode_system.hpp:332
stan::math::coupled_ode_system< F, stan::math::var, double >::f_
const F & f_
Definition: coupled_ode_system.hpp:275
stan::math::e
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:95
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::y0_
const std::vector< stan::math::var > & y0_
Definition: coupled_ode_system.hpp:497
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::initial_state
std::vector< double > initial_state()
Returns the initial state of the coupled system.
Definition: coupled_ode_system.hpp:640
stan::math::size
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
Definition: size.hpp:17
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::theta_
const std::vector< stan::math::var > & theta_
Definition: coupled_ode_system.hpp:499
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::coupled_ode_system
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...
Definition: coupled_ode_system.hpp:521
stan::math::coupled_ode_system< F, stan::math::var, double >::N_
const size_t N_
Definition: coupled_ode_system.hpp:282
stan::math::coupled_ode_system< F, stan::math::var, double >::x_
const std::vector< double > & x_
Definition: coupled_ode_system.hpp:279
stan::math::coupled_ode_system< F, double, stan::math::var >::x_
const std::vector< double > & x_
Definition: coupled_ode_system.hpp:65
stan::math::coupled_ode_system
Base template class for a coupled ordinary differential equation system, which adds sensitivities to ...
Definition: coupled_ode_system.hpp:26
stan::math::recover_memory_nested
static void recover_memory_nested()
Recover only the memory used for the top nested call.
Definition: recover_memory_nested.hpp:21
coupled_ode_system.hpp
stan::math::coupled_ode_system< F, stan::math::var, double >::y0_
const std::vector< stan::math::var > & y0_
Definition: coupled_ode_system.hpp:276
stan::math::coupled_ode_system< F, stan::math::var, double >::M_
const size_t M_
Definition: coupled_ode_system.hpp:283
stan::math::coupled_ode_system< F, double, stan::math::var >::size_
const size_t size_
Definition: coupled_ode_system.hpp:69
stan::math::coupled_ode_system< F, stan::math::var, double >::y0_dbl_
std::vector< double > y0_dbl_
Definition: coupled_ode_system.hpp:277
stan::math::coupled_ode_system< F, stan::math::var, double >::size
size_t size() const
Returns the size of the coupled system.
Definition: coupled_ode_system.hpp:390
N_
int N_
Definition: mdivide_left.hpp:20
stan::math::coupled_ode_system< F, double, stan::math::var >::M_
const size_t M_
Definition: coupled_ode_system.hpp:68
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::size_
const size_t size_
Definition: coupled_ode_system.hpp:505
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::size
size_t size() const
Returns the size of the coupled system.
Definition: coupled_ode_system.hpp:625
value_of.hpp
stan::math::coupled_ode_system< F, stan::math::var, stan::math::var >::x_int_
const std::vector< int > & x_int_
Definition: coupled_ode_system.hpp:502
stan::math::start_nested
static void start_nested()
Record the current position so that recover_memory_nested() can find it.
Definition: start_nested.hpp:13

[ Stan Home Page ] © 2011–2015, Stan Development Team.