coupled_ode_system.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_PRIM_ARR_FUNCTOR_COUPLED_ODE_SYSTEM_HPP
2 #define STAN_MATH_PRIM_ARR_FUNCTOR_COUPLED_ODE_SYSTEM_HPP
3 
5 #include <ostream>
6 #include <vector>
7 
8 namespace stan {
9 namespace math {
10 
11 /**
12  * Base template class for a coupled ordinary differential equation
13  * system, which adds sensitivities to the base system.
14  *
15  * This template class declaration should not be instantiated
16  * directly --- it is just here to serve as a base for its
17  * specializations, some of which are defined in namespace
18  * <code>stan::math</code>.
19  *
20  * @tparam F the functor for the base ode system
21  * @tparam T1 type of the initial state
22  * @tparam T2 type of the parameters
23  */
24 template <typename F, typename T1, typename T2>
26 
27 /**
28  * The coupled ode system for known initial values and known
29  * parameters.
30  *
31  * <p>This coupled system does not add anything to the base
32  * system used to construct it, but is here for generality of the
33  * integration implementation.
34  *
35  * @tparam F type of system function for the base ODE system.
36  */
37 template <typename F>
38 class coupled_ode_system<F, double, double> {
39  public:
40  const F& f_;
41  const std::vector<double>& y0_dbl_;
42  const std::vector<double>& theta_dbl_;
43  const std::vector<double>& x_;
44  const std::vector<int>& x_int_;
45  const size_t N_;
46  const size_t M_;
47  const size_t size_;
48  std::ostream* msgs_;
49 
50  /**
51  * Construct the coupled ODE system from the base system
52  * function, initial state, parameters, data and a stream for
53  * messages.
54  *
55  * @param[in] f base ode system functor.
56  * @param[in] y0 initial state of the base ode.
57  * @param[in] theta parameters of the base ode.
58  * @param[in] x real data.
59  * @param[in] x_int integer data.
60  * @param[in, out] msgs print stream.
61  */
62  coupled_ode_system(const F& f, const std::vector<double>& y0,
63  const std::vector<double>& theta,
64  const std::vector<double>& x,
65  const std::vector<int>& x_int, std::ostream* msgs)
66  : f_(f),
67  y0_dbl_(y0),
68  theta_dbl_(theta),
69  x_(x),
70  x_int_(x_int),
71  N_(y0.size()),
72  M_(theta.size()),
73  size_(N_),
74  msgs_(msgs) {}
75 
76  /**
77  * Calculates the derivative of the coupled ode system with
78  * respect to the specified state at the specified time using
79  * the system state function.
80  *
81  * The derivative vector created is the same length as the
82  * length as the state vector.
83  *
84  * @param[in] y current state of the coupled ode.
85  * @param[out] dy_dt populated with derivatives of the coupled
86  * system evaluated at specified state and time.
87  * @param[in] t time.
88  * @throw exception if the system function does not return
89  * a derivative vector of the same size as the state vector.
90  */
91  void operator()(const std::vector<double>& y, std::vector<double>& dy_dt,
92  double t) const {
93  dy_dt = f_(t, y, theta_dbl_, x_, x_int_, msgs_);
94  check_size_match("coupled_ode_system", "y", y.size(), "dy_dt",
95  dy_dt.size());
96  }
97 
98  /**
99  * Returns the size of the coupled system.
100  *
101  * @return size of the coupled system.
102  */
103  int size() const { return size_; }
104 
105  /**
106  * Returns the initial state of the coupled system, which is
107  * identical to the base ODE original state in this
108  * implementation because the initial state is known.
109  *
110  * The return value is a vector of length size() where the first
111  * N (base ode system size) parameters are the initial
112  * conditions of the base ode system and the rest of the initial
113  * conditions is 0.
114  *
115  * @return initial state of the coupled system
116  */
117  std::vector<double> initial_state() const {
118  std::vector<double> state(size_, 0.0);
119  for (size_t n = 0; n < N_; n++)
120  state[n] = y0_dbl_[n];
121  return state;
122  }
123 
124  /**
125  * Returns the base portion of the coupled state.
126  *
127  * <p>In this class's implementation, the coupled system is
128  * equivalent to the base system, so this function just returns
129  * its input.
130  *
131  * @param y the vector of the coupled states after solving the ode
132  * @return the decoupled states
133  */
134  std::vector<std::vector<double> > decouple_states(
135  const std::vector<std::vector<double> >& y) const {
136  return y;
137  }
138 };
139 
140 } // namespace math
141 } // namespace stan
142 #endif
#define F(x, y, z)
void check_size_match(const char *function, const char *name_i, T_size1 i, const char *name_j, T_size2 j)
size_t size_
Definition: dot_self.hpp:18
int size(const std::vector< T > &x)
Definition: size.hpp:17
coupled_ode_system(const F &f, const std::vector< double > &y0, const std::vector< double > &theta, const std::vector< double > &x, const std::vector< int > &x_int, std::ostream *msgs)
void operator()(const std::vector< double > &y, std::vector< double > &dy_dt, double t) const
int N_
std::vector< std::vector< double > > decouple_states(const std::vector< std::vector< double > > &y) const