integrate_ode_bdf.hpp
Go to the documentation of this file.
#ifndef STAN_MATH_REV_MAT_FUNCTOR_INTEGRATE_ODE_BDF_HPP
#define STAN_MATH_REV_MAT_FUNCTOR_INTEGRATE_ODE_BDF_HPP
#include <stan/math/prim/arr/fun/value_of.hpp>
#include <stan/math/prim/scal/err/check_less.hpp>
#include <stan/math/prim/scal/err/check_finite.hpp>
#include <stan/math/prim/arr/err/check_nonzero_size.hpp>
#include <stan/math/prim/arr/err/check_ordered.hpp>
#include <stan/math/rev/scal/meta/is_var.hpp>
#include <stan/math/prim/scal/meta/return_type.hpp>
#include <stan/math/rev/mat/functor/cvodes_utils.hpp>
#include <stan/math/rev/mat/functor/cvodes_ode_data.hpp>
#include <stan/math/rev/arr/fun/decouple_ode_states.hpp>
#include <cvodes/cvodes.h>
#include <cvodes/cvodes_band.h>
#include <cvodes/cvodes_dense.h>
#include <nvector/nvector_serial.h>
#include <algorithm>
#include <ostream>
#include <vector>
namespace stan {
namespace math {
inline void free_cvodes_memory(N_Vector& cvodes_state,
N_Vector* cvodes_state_sens,
void* cvodes_mem, size_t S) {
N_VDestroy_Serial(cvodes_state);
if (cvodes_state_sens != NULL)
N_VDestroyVectorArray_Serial(cvodes_state_sens, S);
CVodeFree(&cvodes_mem);
}
template <typename F, typename T_initial, typename T_param>
std::vector<std::vector<typename stan::return_type<T_initial,
T_param>::type> >
integrate_ode_bdf(const F& f,
const std::vector<T_initial>& y0,
double t0,
const std::vector<double>& ts,
const std::vector<T_param>& theta,
const std::vector<double>& x,
const std::vector<int>& x_int,
std::ostream* msgs = 0,
double relative_tolerance = 1e-10,
double absolute_tolerance = 1e-10,
long int max_num_steps = 1e8) { // NOLINT(runtime/int)
typedef stan::is_var<T_initial> initial_var;
typedef stan::is_var<T_param> param_var;
check_finite("integrate_ode_bdf", "initial state", y0);
check_finite("integrate_ode_bdf", "initial time", t0);
check_finite("integrate_ode_bdf", "times", ts);
check_finite("integrate_ode_bdf", "parameter vector", theta);
check_finite("integrate_ode_bdf", "continuous data", x);
check_nonzero_size("integrate_ode_bdf", "times", ts);
check_nonzero_size("integrate_ode_bdf", "initial state", y0);
check_ordered("integrate_ode_bdf", "times", ts);
check_less("integrate_ode_bdf", "initial time", t0, ts[0]);
if (relative_tolerance <= 0)
invalid_argument("integrate_ode_bdf",
"relative_tolerance,", relative_tolerance,
"", ", must be greater than 0");
if (absolute_tolerance <= 0)
invalid_argument("integrate_ode_bdf",
"absolute_tolerance,", absolute_tolerance,
"", ", must be greater than 0");
if (max_num_steps <= 0)
invalid_argument("integrate_ode_bdf",
"max_num_steps,", max_num_steps,
"", ", must be greater than 0");
const size_t N = y0.size();
const size_t M = theta.size();
// total number of sensitivities for initial values and params
const size_t S = (initial_var::value ? N : 0)
+ (param_var::value ? M : 0);
const size_t size = N * (S + 1); // size of the coupled system
std::vector<double> state(value_of(y0));
N_Vector cvodes_state(N_VMake_Serial(N, &state[0]));
N_Vector* cvodes_state_sens = NULL;
typedef cvodes_ode_data<F, T_initial, T_param> ode_data;
ode_data cvodes_data(f, y0, theta, x, x_int, msgs);
void* cvodes_mem = CVodeCreate(CV_BDF, CV_NEWTON);
if (cvodes_mem == NULL)
throw std::runtime_error("CVodeCreate failed to allocate memory");
std::vector<std::vector<double> >
y_coupled(ts.size(), std::vector<double>(size, 0));
try {
cvodes_check_flag(CVodeInit(cvodes_mem, &ode_data::ode_rhs,
t0, cvodes_state),
"CVodeInit");
// Assign pointer to this as user data
cvodes_check_flag(CVodeSetUserData(cvodes_mem,
reinterpret_cast<void*>(&cvodes_data)),
"CVodeSetUserData");
cvodes_set_options(cvodes_mem,
relative_tolerance, absolute_tolerance,
max_num_steps);
// for the stiff solvers we need to reserve additional
// memory and provide a Jacobian function call
cvodes_check_flag(CVDense(cvodes_mem, N), "CVDense");
cvodes_check_flag(CVDlsSetDenseJacFn(cvodes_mem,
&ode_data::dense_jacobian),
"CVDlsSetDenseJacFn");
// initialize forward sensitivity system of CVODES as needed
if (S > 0) {
cvodes_state_sens = N_VCloneVectorArray_Serial(S, cvodes_state);
for (size_t s = 0; s < S; s++)
N_VConst(RCONST(0.0), cvodes_state_sens[s]);
// for varying initials, first N sensitivity systems
// are for initials which have as initial the identity matrix
if (initial_var::value) {
for (size_t n = 0; n < N; n++)
NV_Ith_S(cvodes_state_sens[n], n) = 1.0;
}
cvodes_check_flag(CVodeSensInit(cvodes_mem, static_cast<int>(S),
CV_STAGGERED,
&ode_data::ode_rhs_sens,
cvodes_state_sens),
"CVodeSensInit");
cvodes_check_flag(CVodeSensEEtolerances(cvodes_mem),
"CVodeSensEEtolerances");
}
double t_init = t0;
for (size_t n = 0; n < ts.size(); ++n) {
double t_final = ts[n];
if (t_final != t_init)
cvodes_check_flag(CVode(cvodes_mem, t_final, cvodes_state,
&t_init, CV_NORMAL),
"CVode");
std::copy(state.begin(), state.end(), y_coupled[n].begin());
if (S > 0) {
cvodes_check_flag(CVodeGetSens(cvodes_mem, &t_init,
cvodes_state_sens),
"CVodeGetSens");
for (size_t s = 0; s < S; s++)
std::copy(NV_DATA_S(cvodes_state_sens[s]),
NV_DATA_S(cvodes_state_sens[s]) + N,
y_coupled[n].begin() + N + s * N);
}
t_init = t_final;
}
} catch (const std::exception& e) {
free_cvodes_memory(cvodes_state, cvodes_state_sens, cvodes_mem, S);
throw;
}
free_cvodes_memory(cvodes_state, cvodes_state_sens, cvodes_mem, S);
return decouple_ode_states(y_coupled, y0, theta);
}
}
}
#endif
stan::math::check_finite
void check_finite(const char *function, const char *name, const T_y &y)
Check if y is finite.
Definition: check_finite.hpp:57
stan::math::integrate_ode_bdf
std::vector< std::vector< typename stan::return_type< T_initial, T_param >::type > > integrate_ode_bdf(const F &f, const std::vector< T_initial > &y0, double t0, const std::vector< double > &ts, const std::vector< T_param > &theta, const std::vector< double > &x, const std::vector< int > &x_int, std::ostream *msgs=0, double relative_tolerance=1e-10, double absolute_tolerance=1e-10, long int max_num_steps=1e8)
Return the solutions for the specified system of ordinary differential equations given the specified ...
Definition: integrate_ode_bdf.hpp:83
stan::math::check_nonzero_size
void check_nonzero_size(const char *function, const char *name, const T_y &y)
Check if the specified matrix/vector is of non-zero size.
Definition: check_nonzero_size.hpp:27
stan::math::cvodes_set_options
void cvodes_set_options(void *cvodes_mem, double rel_tol, double abs_tol, long int max_num_steps)
Definition: cvodes_utils.hpp:30
value_of.hpp
stan
Definition: log_sum_exp.hpp:8
stan::math::check_ordered
void check_ordered(const char *function, const char *name, const std::vector< T_y > &y)
Check if the specified vector is sorted into strictly increasing order.
Definition: check_ordered.hpp:29
stan::math::value_of
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition: value_of.hpp:16
stan::is_var
Definition: is_var.hpp:7
stan::return_type
Metaprogram to calculate the base scalar return type resulting from promoting all the scalar types of...
Definition: return_type.hpp:19
return_type.hpp
stan::math::free_cvodes_memory
void free_cvodes_memory(N_Vector &cvodes_state, N_Vector *cvodes_state_sens, void *cvodes_mem, size_t S)
Free memory allocated for CVODES state, sensitivity, and general memory.
Definition: integrate_ode_bdf.hpp:34
cvodes_utils.hpp
stan::math::cvodes_ode_data
CVODES ode data holder object which is used during CVODES integration for CVODES callbacks.
Definition: cvodes_ode_data.hpp:26
stan::math::cvodes_check_flag
void cvodes_check_flag(int flag, const std::string &func_name)
Definition: cvodes_utils.hpp:22
stan::math::invalid_argument
void invalid_argument(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
Throw an invalid_argument exception with a consistently formatted message.
Definition: invalid_argument.hpp:31
cvodes_ode_data.hpp
stan::math::decouple_ode_states
std::vector< std::vector< typename stan::return_type< T_initial, T_param >::type > > decouple_ode_states(const std::vector< std::vector< double > > &y, const std::vector< T_initial > &y0, const std::vector< T_param > &theta)
Takes sensitivity output from integrators and returns results in precomputed_gradients format...
Definition: decouple_ode_states.hpp:37
stan::math::e
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:94
decouple_ode_states.hpp
stan::math::size
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
Definition: size.hpp:17
check_ordered.hpp
check_finite.hpp
is_var.hpp
check_nonzero_size.hpp
check_less.hpp
stan::math::check_less
void check_less(const char *function, const char *name, const T_y &y, const T_high &high)
Check if y is strictly less than high.
Definition: check_less.hpp:78

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