#pragma once #include // define an analytic jacobian for the hornberg for Stan's CVODES // solver by partial template specialisation namespace stan { namespace math { // todo: idealy, we derive the specialised ode_model from the // general one which gives possibly syntax problem which is why we // chose to use a typedef, maybe we need another helper... not // sure. template<> struct ode_system { typedef pbpkautojac_model_namespace::pbpk_functor__ F; const F& f_; const std::vector theta_; const std::vector& x_; const std::vector& x_int_; std::ostream* msgs_; ode_system(const F& f, const std::vector theta, const std::vector& x, const std::vector& x_int, std::ostream* msgs) : f_(f), theta_(theta), x_(x), x_int_(x_int), msgs_(msgs) {} inline void operator()(const double t, const std::vector& y, // std::vector& dy_dt) const { // dy_dt = f_(t, y, theta_, x_, x_int_, msgs_); // the previous two lines for 2.14.0 // the next two lines for 2.17.1 Eigen::Map>& dy_dt) const { std::vector dy_dt_ = f_(t, y, theta_, x_, x_int_, msgs_); for(size_t i = 0; i < dy_dt_.size(); i++) dy_dt(i) = dy_dt_[i]; } template inline void jacobian(const double t, const std::vector& y, Eigen::MatrixBase& fy, Eigen::MatrixBase& Jy ) const { using Eigen::VectorXd; using std::vector; using std::pow; const vector f = f_(t, y, theta_, x_, x_int_, msgs_); fy = VectorXd::Map(&f[0], f.size()); Jy.setZero(); Eigen::Map J = Eigen::Map(&Jy(0,0), Jy.cols()*Jy.rows()); // dy/dt=f(y,theta) // df/dy #include "states.txt" } template inline void jacobian(const double t, const std::vector& y, Eigen::MatrixBase& fy, Eigen::MatrixBase& Jy, Eigen::MatrixBase& Jtheta ) const { using Eigen::VectorXd; using std::vector; using std::pow; jacobian(t, y, fy, Jy); //const vector& parms = theta_; Jtheta.setZero(); Eigen::Map J = Eigen::Map(&Jtheta(0,0), Jtheta.cols()*Jtheta.rows()); // df/dtheta #include "params.txt" } }; } }