
#ifndef MODELS_HPP
#define MODELS_HPP
#define STAN__SERVICES__COMMAND_HPP
#include <rstan/rstaninc.hpp>
// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_Exponential_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_Exponential");
    reader.add_event(62, 60, "end", "model_Exponential");
    return reader;
}

template <typename T0__, typename T1__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__>::type, Eigen::Dynamic,1>
log_h(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_h", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_h(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_h;  // dummy to suppress unused var warning

        stan::math::initialize(log_h, DUMMY_VAR__);
        stan::math::fill(log_h,DUMMY_VAR__);


        stan::math::assign(log_h, stan::math::log(rate));
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_h);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_h_functor__ {
    template <typename T0__, typename T1__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) const {
        return log_h(t, rate, pstream__);
    }
};

template <typename T0__, typename T1__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__>::type, Eigen::Dynamic,1>
log_S(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_S", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_S(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_S;  // dummy to suppress unused var warning

        stan::math::initialize(log_S, DUMMY_VAR__);
        stan::math::fill(log_S,DUMMY_VAR__);


        stan::math::assign(log_S, elt_multiply(minus(rate),t));
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_S);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_S_functor__ {
    template <typename T0__, typename T1__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) const {
        return log_S(t, rate, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__>
typename boost::math::tools::promote_args<T0__, T1__, T2__>::type
surv_exponential_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ prob;
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);


        stan::math::assign(log_lik, add(elt_multiply(d,log_h(t,rate, pstream__)),log_S(t,rate, pstream__)));
        stan::math::assign(prob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(prob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__>
typename boost::math::tools::promote_args<T0__, T1__, T2__>::type
surv_exponential_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) {
    return surv_exponential_lpdf<false>(t,d,rate, pstream__);
}


struct surv_exponential_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) const {
        return surv_exponential_lpdf(t, d, rate, pstream__);
    }
};

class model_Exponential : public prob_grad {
private:
    int n;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X;
    vector_d mu_beta;
    vector_d sigma_beta;
public:
    model_Exponential(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_Exponential(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_Exponential_namespace::model_Exponential";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(n,H));
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    X(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }

            // validate, data variables
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_Exponential() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);


            // transformed parameters
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(linpred(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: linpred" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(mu(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: mu" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(surv_exponential_lpdf<propto__>(t, d, mu, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("beta");
        names__.push_back("linpred");
        names__.push_back("mu");
        names__.push_back("rate");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_Exponential_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d beta = in__.vector_constrain(H);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(linpred[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(mu[k_0__]);
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ rate;
            (void) rate;  // dummy to suppress unused var warning

            stan::math::initialize(rate, DUMMY_VAR__);
            stan::math::fill(rate,DUMMY_VAR__);


            stan::math::assign(rate, stan::math::exp(get_base1(beta,1,"beta",1)));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(rate);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_Exponential";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_Gamma_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_Gamma");
    reader.add_event(51, 49, "end", "model_Gamma");
    return reader;
}

class model_Gamma : public prob_grad {
private:
    int n_obs;
    int n_cens;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X_obs;
    matrix_d X_cens;
    vector_d mu_beta;
    vector_d sigma_beta;
    double a_alpha;
    double b_alpha;
public:
    model_Gamma(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_Gamma(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_Gamma_namespace::model_Gamma";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n_obs", "int", context__.to_vec());
            n_obs = int(0);
            vals_i__ = context__.vals_i("n_obs");
            pos__ = 0;
            n_obs = vals_i__[pos__++];
            context__.validate_dims("data initialization", "n_cens", "int", context__.to_vec());
            n_cens = int(0);
            vals_i__ = context__.vals_i("n_cens");
            pos__ = 0;
            n_cens = vals_i__[pos__++];
            validate_non_negative_index("t", "n_obs", n_obs);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n_obs));
            validate_non_negative_index("t", "n_obs", n_obs);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n_obs));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n_obs;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n_cens", n_cens);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n_cens));
            validate_non_negative_index("d", "n_cens", n_cens);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n_cens));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n_cens;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X_obs", "n_obs", n_obs);
            validate_non_negative_index("X_obs", "H", H);
            context__.validate_dims("data initialization", "X_obs", "matrix_d", context__.to_vec(n_obs,H));
            validate_non_negative_index("X_obs", "n_obs", n_obs);
            validate_non_negative_index("X_obs", "H", H);
            X_obs = matrix_d(static_cast<Eigen::VectorXd::Index>(n_obs),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X_obs");
            pos__ = 0;
            size_t X_obs_m_mat_lim__ = n_obs;
            size_t X_obs_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_obs_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_obs_m_mat_lim__; ++m_mat__) {
                    X_obs(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("X_cens", "n_cens", n_cens);
            validate_non_negative_index("X_cens", "H", H);
            context__.validate_dims("data initialization", "X_cens", "matrix_d", context__.to_vec(n_cens,H));
            validate_non_negative_index("X_cens", "n_cens", n_cens);
            validate_non_negative_index("X_cens", "H", H);
            X_cens = matrix_d(static_cast<Eigen::VectorXd::Index>(n_cens),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X_cens");
            pos__ = 0;
            size_t X_cens_m_mat_lim__ = n_cens;
            size_t X_cens_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_cens_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_cens_m_mat_lim__; ++m_mat__) {
                    X_cens(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "a_alpha", "double", context__.to_vec());
            a_alpha = double(0);
            vals_r__ = context__.vals_r("a_alpha");
            pos__ = 0;
            a_alpha = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_alpha", "double", context__.to_vec());
            b_alpha = double(0);
            vals_r__ = context__.vals_r("b_alpha");
            pos__ = 0;
            b_alpha = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"n_obs",n_obs,1);
            check_greater_or_equal(function__,"n_cens",n_cens,0);
            check_greater_or_equal(function__,"t",t,0);
            check_greater_or_equal(function__,"d",d,0);
            check_greater_or_equal(function__,"H",H,1);
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"a_alpha",a_alpha,0);
            check_greater_or_equal(function__,"b_alpha",b_alpha,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            ++num_params_r__;
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            validate_non_negative_index("cens", "n_cens", n_cens);
            num_params_r__ += n_cens;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_Gamma() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("alpha")))
            throw std::runtime_error("variable alpha missing");
        vals_r__ = context__.vals_r("alpha");
        pos__ = 0U;
        context__.validate_dims("initialization", "alpha", "double", context__.to_vec());
        double alpha(0);
        alpha = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,alpha);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable alpha: ") + e.what());
        }

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("cens")))
            throw std::runtime_error("variable cens missing");
        vals_r__ = context__.vals_r("cens");
        pos__ = 0U;
        validate_non_negative_index("cens", "n_cens", n_cens);
        context__.validate_dims("initialization", "cens", "vector_d", context__.to_vec(n_cens));
        vector_d cens(static_cast<Eigen::VectorXd::Index>(n_cens));
        for (int j1__ = 0U; j1__ < n_cens; ++j1__)
            cens(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_lb_unconstrain(1,cens);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable cens: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            local_scalar_t__ alpha;
            (void) alpha;  // dummy to suppress unused var warning
            if (jacobian__)
                alpha = in__.scalar_lb_constrain(0,lp__);
            else
                alpha = in__.scalar_lb_constrain(0);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  cens;
            (void) cens;  // dummy to suppress unused var warning
            if (jacobian__)
                cens = in__.vector_lb_constrain(1,n_cens,lp__);
            else
                cens = in__.vector_lb_constrain(1,n_cens);


            // transformed parameters
            validate_non_negative_index("loglambda_obs", "n_obs", n_obs);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  loglambda_obs(static_cast<Eigen::VectorXd::Index>(n_obs));
            (void) loglambda_obs;  // dummy to suppress unused var warning

            stan::math::initialize(loglambda_obs, DUMMY_VAR__);
            stan::math::fill(loglambda_obs,DUMMY_VAR__);
            validate_non_negative_index("loglambda_cens", "n_cens", n_cens);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  loglambda_cens(static_cast<Eigen::VectorXd::Index>(n_cens));
            (void) loglambda_cens;  // dummy to suppress unused var warning

            stan::math::initialize(loglambda_cens, DUMMY_VAR__);
            stan::math::fill(loglambda_cens,DUMMY_VAR__);
            validate_non_negative_index("lambda_obs", "n_obs", n_obs);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  lambda_obs(static_cast<Eigen::VectorXd::Index>(n_obs));
            (void) lambda_obs;  // dummy to suppress unused var warning

            stan::math::initialize(lambda_obs, DUMMY_VAR__);
            stan::math::fill(lambda_obs,DUMMY_VAR__);
            validate_non_negative_index("lambda_cens", "n_cens", n_cens);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  lambda_cens(static_cast<Eigen::VectorXd::Index>(n_cens));
            (void) lambda_cens;  // dummy to suppress unused var warning

            stan::math::initialize(lambda_cens, DUMMY_VAR__);
            stan::math::fill(lambda_cens,DUMMY_VAR__);


            stan::math::assign(loglambda_cens, add(multiply(X_cens,beta),stan::math::log(d)));
            for (int i = 1; i <= n_cens; ++i) {

                stan::model::assign(lambda_cens, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(loglambda_cens,i,"loglambda_cens",1)), 
                            "assigning variable lambda_cens");
            }
            stan::math::assign(loglambda_obs, multiply(X_obs,beta));
            for (int i = 1; i <= n_obs; ++i) {

                stan::model::assign(lambda_obs, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(loglambda_obs,i,"loglambda_obs",1)), 
                            "assigning variable lambda_obs");
            }

            // validate transformed parameters
            for (int i0__ = 0; i0__ < n_obs; ++i0__) {
                if (stan::math::is_uninitialized(loglambda_obs(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: loglambda_obs" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n_cens; ++i0__) {
                if (stan::math::is_uninitialized(loglambda_cens(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: loglambda_cens" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n_obs; ++i0__) {
                if (stan::math::is_uninitialized(lambda_obs(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: lambda_obs" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n_cens; ++i0__) {
                if (stan::math::is_uninitialized(lambda_cens(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: lambda_cens" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(gamma_log<propto__>(alpha, a_alpha, b_alpha));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(gamma_log<propto__>(cens, alpha, lambda_cens));
            lp_accum__.add(gamma_log<propto__>(t, alpha, lambda_obs));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("alpha");
        names__.push_back("beta");
        names__.push_back("cens");
        names__.push_back("loglambda_obs");
        names__.push_back("loglambda_cens");
        names__.push_back("lambda_obs");
        names__.push_back("lambda_cens");
        names__.push_back("rate");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n_cens);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n_obs);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n_cens);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n_obs);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n_cens);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_Gamma_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        double alpha = in__.scalar_lb_constrain(0);
        vector_d beta = in__.vector_constrain(H);
        vector_d cens = in__.vector_lb_constrain(1,n_cens);
        vars__.push_back(alpha);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n_cens; ++k_0__) {
            vars__.push_back(cens[k_0__]);
            }

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            validate_non_negative_index("loglambda_obs", "n_obs", n_obs);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  loglambda_obs(static_cast<Eigen::VectorXd::Index>(n_obs));
            (void) loglambda_obs;  // dummy to suppress unused var warning

            stan::math::initialize(loglambda_obs, DUMMY_VAR__);
            stan::math::fill(loglambda_obs,DUMMY_VAR__);
            validate_non_negative_index("loglambda_cens", "n_cens", n_cens);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  loglambda_cens(static_cast<Eigen::VectorXd::Index>(n_cens));
            (void) loglambda_cens;  // dummy to suppress unused var warning

            stan::math::initialize(loglambda_cens, DUMMY_VAR__);
            stan::math::fill(loglambda_cens,DUMMY_VAR__);
            validate_non_negative_index("lambda_obs", "n_obs", n_obs);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  lambda_obs(static_cast<Eigen::VectorXd::Index>(n_obs));
            (void) lambda_obs;  // dummy to suppress unused var warning

            stan::math::initialize(lambda_obs, DUMMY_VAR__);
            stan::math::fill(lambda_obs,DUMMY_VAR__);
            validate_non_negative_index("lambda_cens", "n_cens", n_cens);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  lambda_cens(static_cast<Eigen::VectorXd::Index>(n_cens));
            (void) lambda_cens;  // dummy to suppress unused var warning

            stan::math::initialize(lambda_cens, DUMMY_VAR__);
            stan::math::fill(lambda_cens,DUMMY_VAR__);


            stan::math::assign(loglambda_cens, add(multiply(X_cens,beta),stan::math::log(d)));
            for (int i = 1; i <= n_cens; ++i) {

                stan::model::assign(lambda_cens, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(loglambda_cens,i,"loglambda_cens",1)), 
                            "assigning variable lambda_cens");
            }
            stan::math::assign(loglambda_obs, multiply(X_obs,beta));
            for (int i = 1; i <= n_obs; ++i) {

                stan::model::assign(lambda_obs, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(loglambda_obs,i,"loglambda_obs",1)), 
                            "assigning variable lambda_obs");
            }

            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            for (int k_0__ = 0; k_0__ < n_obs; ++k_0__) {
            vars__.push_back(loglambda_obs[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n_cens; ++k_0__) {
            vars__.push_back(loglambda_cens[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n_obs; ++k_0__) {
            vars__.push_back(lambda_obs[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n_cens; ++k_0__) {
            vars__.push_back(lambda_cens[k_0__]);
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ rate;
            (void) rate;  // dummy to suppress unused var warning

            stan::math::initialize(rate, DUMMY_VAR__);
            stan::math::fill(rate,DUMMY_VAR__);


            stan::math::assign(rate, stan::math::exp(get_base1(beta,1,"beta",1)));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(rate);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_Gamma";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "cens" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n_obs; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "loglambda_obs" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "loglambda_cens" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n_obs; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "lambda_obs" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "lambda_cens" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "cens" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n_obs; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "loglambda_obs" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "loglambda_cens" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n_obs; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "lambda_obs" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "lambda_cens" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_GenF_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_GenF");
    reader.add_event(101, 99, "end", "model_GenF");
    return reader;
}

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type
genf_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
              const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
              const T2__& sigma,
              const T3__& Q,
              const T4__& P, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("prob", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  prob(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);
        local_scalar_t__ lprob;
        (void) lprob;  // dummy to suppress unused var warning

        stan::math::initialize(lprob, DUMMY_VAR__);
        stan::math::fill(lprob,DUMMY_VAR__);
        local_scalar_t__ tmp;
        (void) tmp;  // dummy to suppress unused var warning

        stan::math::initialize(tmp, DUMMY_VAR__);
        stan::math::fill(tmp,DUMMY_VAR__);
        local_scalar_t__ delta;
        (void) delta;  // dummy to suppress unused var warning

        stan::math::initialize(delta, DUMMY_VAR__);
        stan::math::fill(delta,DUMMY_VAR__);
        local_scalar_t__ s1;
        (void) s1;  // dummy to suppress unused var warning

        stan::math::initialize(s1, DUMMY_VAR__);
        stan::math::fill(s1,DUMMY_VAR__);
        local_scalar_t__ s2;
        (void) s2;  // dummy to suppress unused var warning

        stan::math::initialize(s2, DUMMY_VAR__);
        stan::math::fill(s2,DUMMY_VAR__);
        validate_non_negative_index("expw", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  expw(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) expw;  // dummy to suppress unused var warning

        stan::math::initialize(expw, DUMMY_VAR__);
        stan::math::fill(expw,DUMMY_VAR__);


        stan::math::assign(tmp, (pow(Q,2) + (2 * P)));
        stan::math::assign(delta, pow(tmp,0.5));
        stan::math::assign(s1, (2 / (tmp + (Q * delta))));
        stan::math::assign(s2, (2 / (tmp - (Q * delta))));
        for (int i = 1; i <= num_elements(x); ++i) {

            stan::model::assign(expw, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        (pow(get_base1(x,i,"x",1),(delta / sigma)) * stan::math::exp(((-(get_base1(mu,i,"mu",1)) * delta) / sigma))), 
                        "assigning variable expw");
            stan::model::assign(prob, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        (((((stan::math::log(delta) + (((s1 / sigma) * delta) * (stan::math::log(get_base1(x,i,"x",1)) - get_base1(mu,i,"mu",1)))) + (s1 * (stan::math::log(s1) - stan::math::log(s2)))) - stan::math::log((sigma * get_base1(x,i,"x",1)))) - ((s1 + s2) * stan::math::log((1 + ((s1 * get_base1(expw,i,"expw",1)) / s2))))) - lbeta(s1,s2)), 
                        "assigning variable prob");
        }
        stan::math::assign(lprob, sum(prob));
        return stan::math::promote_scalar<fun_return_scalar_t__>(lprob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__, typename T4__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type
genf_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
              const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
              const T2__& sigma,
              const T3__& Q,
              const T4__& P, std::ostream* pstream__) {
    return genf_lpdf<false>(x,mu,sigma,Q,P, pstream__);
}


struct genf_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
              const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
              const T2__& sigma,
              const T3__& Q,
              const T4__& P, std::ostream* pstream__) const {
        return genf_lpdf(x, mu, sigma, Q, P, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__, typename T5__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type
genf_cens_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                   const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                   const T2__& sigma,
                   const T3__& Q,
                   const T4__& P,
                   const Eigen::Matrix<T5__, Eigen::Dynamic,1>& u, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("prob", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  prob(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);
        local_scalar_t__ lprob;
        (void) lprob;  // dummy to suppress unused var warning

        stan::math::initialize(lprob, DUMMY_VAR__);
        stan::math::fill(lprob,DUMMY_VAR__);
        local_scalar_t__ tmp;
        (void) tmp;  // dummy to suppress unused var warning

        stan::math::initialize(tmp, DUMMY_VAR__);
        stan::math::fill(tmp,DUMMY_VAR__);
        local_scalar_t__ delta;
        (void) delta;  // dummy to suppress unused var warning

        stan::math::initialize(delta, DUMMY_VAR__);
        stan::math::fill(delta,DUMMY_VAR__);
        local_scalar_t__ s1;
        (void) s1;  // dummy to suppress unused var warning

        stan::math::initialize(s1, DUMMY_VAR__);
        stan::math::fill(s1,DUMMY_VAR__);
        local_scalar_t__ s2;
        (void) s2;  // dummy to suppress unused var warning

        stan::math::initialize(s2, DUMMY_VAR__);
        stan::math::fill(s2,DUMMY_VAR__);
        validate_non_negative_index("expw", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  expw(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) expw;  // dummy to suppress unused var warning

        stan::math::initialize(expw, DUMMY_VAR__);
        stan::math::fill(expw,DUMMY_VAR__);
        validate_non_negative_index("tr", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  tr(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) tr;  // dummy to suppress unused var warning

        stan::math::initialize(tr, DUMMY_VAR__);
        stan::math::fill(tr,DUMMY_VAR__);


        stan::math::assign(tmp, (pow(Q,2) + (2 * P)));
        stan::math::assign(delta, pow(tmp,0.5));
        stan::math::assign(s1, (2 / (tmp + (Q * delta))));
        stan::math::assign(s2, (2 / (tmp - (Q * delta))));
        stan::math::assign(tr, elt_multiply(x,u));
        for (int i = 1; i <= num_elements(x); ++i) {

            stan::model::assign(expw, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        (pow(get_base1(tr,i,"tr",1),(delta / sigma)) * stan::math::exp(((-(get_base1(mu,i,"mu",1)) * delta) / sigma))), 
                        "assigning variable expw");
            stan::model::assign(prob, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        ((((((stan::math::log(get_base1(u,i,"u",1)) + stan::math::log(delta)) + (((s1 / sigma) * delta) * (stan::math::log(get_base1(tr,i,"tr",1)) - get_base1(mu,i,"mu",1)))) + (s1 * (stan::math::log(s1) - stan::math::log(s2)))) - stan::math::log((sigma * get_base1(tr,i,"tr",1)))) - ((s1 + s2) * stan::math::log((1 + ((s1 * get_base1(expw,i,"expw",1)) / s2))))) - lbeta(s1,s2)), 
                        "assigning variable prob");
        }
        stan::math::assign(lprob, sum(prob));
        return stan::math::promote_scalar<fun_return_scalar_t__>(lprob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__, typename T4__, typename T5__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type
genf_cens_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                   const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                   const T2__& sigma,
                   const T3__& Q,
                   const T4__& P,
                   const Eigen::Matrix<T5__, Eigen::Dynamic,1>& u, std::ostream* pstream__) {
    return genf_cens_lpdf<false>(x,mu,sigma,Q,P,u, pstream__);
}


struct genf_cens_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__, typename T5__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                   const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                   const T2__& sigma,
                   const T3__& Q,
                   const T4__& P,
                   const Eigen::Matrix<T5__, Eigen::Dynamic,1>& u, std::ostream* pstream__) const {
        return genf_cens_lpdf(x, mu, sigma, Q, P, u, pstream__);
    }
};

class model_GenF : public prob_grad {
private:
    int n_obs;
    int n_cens;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X_obs;
    matrix_d X_cens;
    vector_d mu_beta;
    vector_d sigma_beta;
    double a_sigma;
    double b_sigma;
    double mu_P;
    double sigma_P;
    double mu_Q;
    double sigma_Q;
public:
    model_GenF(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_GenF(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_GenF_namespace::model_GenF";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n_obs", "int", context__.to_vec());
            n_obs = int(0);
            vals_i__ = context__.vals_i("n_obs");
            pos__ = 0;
            n_obs = vals_i__[pos__++];
            context__.validate_dims("data initialization", "n_cens", "int", context__.to_vec());
            n_cens = int(0);
            vals_i__ = context__.vals_i("n_cens");
            pos__ = 0;
            n_cens = vals_i__[pos__++];
            validate_non_negative_index("t", "n_obs", n_obs);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n_obs));
            validate_non_negative_index("t", "n_obs", n_obs);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n_obs));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n_obs;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n_cens", n_cens);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n_cens));
            validate_non_negative_index("d", "n_cens", n_cens);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n_cens));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n_cens;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X_obs", "n_obs", n_obs);
            validate_non_negative_index("X_obs", "H", H);
            context__.validate_dims("data initialization", "X_obs", "matrix_d", context__.to_vec(n_obs,H));
            validate_non_negative_index("X_obs", "n_obs", n_obs);
            validate_non_negative_index("X_obs", "H", H);
            X_obs = matrix_d(static_cast<Eigen::VectorXd::Index>(n_obs),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X_obs");
            pos__ = 0;
            size_t X_obs_m_mat_lim__ = n_obs;
            size_t X_obs_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_obs_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_obs_m_mat_lim__; ++m_mat__) {
                    X_obs(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("X_cens", "n_cens", n_cens);
            validate_non_negative_index("X_cens", "H", H);
            context__.validate_dims("data initialization", "X_cens", "matrix_d", context__.to_vec(n_cens,H));
            validate_non_negative_index("X_cens", "n_cens", n_cens);
            validate_non_negative_index("X_cens", "H", H);
            X_cens = matrix_d(static_cast<Eigen::VectorXd::Index>(n_cens),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X_cens");
            pos__ = 0;
            size_t X_cens_m_mat_lim__ = n_cens;
            size_t X_cens_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_cens_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_cens_m_mat_lim__; ++m_mat__) {
                    X_cens(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "a_sigma", "double", context__.to_vec());
            a_sigma = double(0);
            vals_r__ = context__.vals_r("a_sigma");
            pos__ = 0;
            a_sigma = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_sigma", "double", context__.to_vec());
            b_sigma = double(0);
            vals_r__ = context__.vals_r("b_sigma");
            pos__ = 0;
            b_sigma = vals_r__[pos__++];
            context__.validate_dims("data initialization", "mu_P", "double", context__.to_vec());
            mu_P = double(0);
            vals_r__ = context__.vals_r("mu_P");
            pos__ = 0;
            mu_P = vals_r__[pos__++];
            context__.validate_dims("data initialization", "sigma_P", "double", context__.to_vec());
            sigma_P = double(0);
            vals_r__ = context__.vals_r("sigma_P");
            pos__ = 0;
            sigma_P = vals_r__[pos__++];
            context__.validate_dims("data initialization", "mu_Q", "double", context__.to_vec());
            mu_Q = double(0);
            vals_r__ = context__.vals_r("mu_Q");
            pos__ = 0;
            mu_Q = vals_r__[pos__++];
            context__.validate_dims("data initialization", "sigma_Q", "double", context__.to_vec());
            sigma_Q = double(0);
            vals_r__ = context__.vals_r("sigma_Q");
            pos__ = 0;
            sigma_Q = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"n_obs",n_obs,1);
            check_greater_or_equal(function__,"n_cens",n_cens,0);
            check_greater_or_equal(function__,"t",t,0);
            check_greater_or_equal(function__,"d",d,0);
            check_greater_or_equal(function__,"H",H,1);
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"a_sigma",a_sigma,0);
            check_greater_or_equal(function__,"b_sigma",b_sigma,0);
            check_greater_or_equal(function__,"sigma_P",sigma_P,0);
            check_greater_or_equal(function__,"sigma_Q",sigma_Q,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            ++num_params_r__;
            ++num_params_r__;
            ++num_params_r__;
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            validate_non_negative_index("cens", "n_cens", n_cens);
            num_params_r__ += n_cens;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_GenF() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("sigma")))
            throw std::runtime_error("variable sigma missing");
        vals_r__ = context__.vals_r("sigma");
        pos__ = 0U;
        context__.validate_dims("initialization", "sigma", "double", context__.to_vec());
        double sigma(0);
        sigma = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,sigma);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable sigma: ") + e.what());
        }

        if (!(context__.contains_r("Q")))
            throw std::runtime_error("variable Q missing");
        vals_r__ = context__.vals_r("Q");
        pos__ = 0U;
        context__.validate_dims("initialization", "Q", "double", context__.to_vec());
        double Q(0);
        Q = vals_r__[pos__++];
        try {
            writer__.scalar_unconstrain(Q);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable Q: ") + e.what());
        }

        if (!(context__.contains_r("logP")))
            throw std::runtime_error("variable logP missing");
        vals_r__ = context__.vals_r("logP");
        pos__ = 0U;
        context__.validate_dims("initialization", "logP", "double", context__.to_vec());
        double logP(0);
        logP = vals_r__[pos__++];
        try {
            writer__.scalar_unconstrain(logP);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable logP: ") + e.what());
        }

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("cens")))
            throw std::runtime_error("variable cens missing");
        vals_r__ = context__.vals_r("cens");
        pos__ = 0U;
        validate_non_negative_index("cens", "n_cens", n_cens);
        context__.validate_dims("initialization", "cens", "vector_d", context__.to_vec(n_cens));
        vector_d cens(static_cast<Eigen::VectorXd::Index>(n_cens));
        for (int j1__ = 0U; j1__ < n_cens; ++j1__)
            cens(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_lb_unconstrain(1,cens);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable cens: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            local_scalar_t__ sigma;
            (void) sigma;  // dummy to suppress unused var warning
            if (jacobian__)
                sigma = in__.scalar_lb_constrain(0,lp__);
            else
                sigma = in__.scalar_lb_constrain(0);

            local_scalar_t__ Q;
            (void) Q;  // dummy to suppress unused var warning
            if (jacobian__)
                Q = in__.scalar_constrain(lp__);
            else
                Q = in__.scalar_constrain();

            local_scalar_t__ logP;
            (void) logP;  // dummy to suppress unused var warning
            if (jacobian__)
                logP = in__.scalar_constrain(lp__);
            else
                logP = in__.scalar_constrain();

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  cens;
            (void) cens;  // dummy to suppress unused var warning
            if (jacobian__)
                cens = in__.vector_lb_constrain(1,n_cens,lp__);
            else
                cens = in__.vector_lb_constrain(1,n_cens);


            // transformed parameters
            local_scalar_t__ P;
            (void) P;  // dummy to suppress unused var warning

            stan::math::initialize(P, DUMMY_VAR__);
            stan::math::fill(P,DUMMY_VAR__);


            stan::math::assign(P, stan::math::exp(logP));

            // validate transformed parameters
            if (stan::math::is_uninitialized(P)) {
                std::stringstream msg__;
                msg__ << "Undefined transformed parameter: P";
                throw std::runtime_error(msg__.str());
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning
            check_greater_or_equal(function__,"P",P,0);

            // model body

            lp_accum__.add(gamma_log<propto__>(sigma, a_sigma, b_sigma));
            lp_accum__.add(normal_log<propto__>(logP, mu_P, sigma_P));
            lp_accum__.add(normal_log<propto__>(Q, mu_Q, sigma_Q));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(genf_cens_lpdf<propto__>(cens, multiply(X_cens,beta), sigma, Q, P, d, pstream__));
            lp_accum__.add(genf_lpdf<propto__>(t, multiply(X_obs,beta), sigma, Q, P, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("sigma");
        names__.push_back("Q");
        names__.push_back("logP");
        names__.push_back("beta");
        names__.push_back("cens");
        names__.push_back("P");
        names__.push_back("mu");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n_cens);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_GenF_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        double sigma = in__.scalar_lb_constrain(0);
        double Q = in__.scalar_constrain();
        double logP = in__.scalar_constrain();
        vector_d beta = in__.vector_constrain(H);
        vector_d cens = in__.vector_lb_constrain(1,n_cens);
        vars__.push_back(sigma);
        vars__.push_back(Q);
        vars__.push_back(logP);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n_cens; ++k_0__) {
            vars__.push_back(cens[k_0__]);
            }

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            local_scalar_t__ P;
            (void) P;  // dummy to suppress unused var warning

            stan::math::initialize(P, DUMMY_VAR__);
            stan::math::fill(P,DUMMY_VAR__);


            stan::math::assign(P, stan::math::exp(logP));

            // validate transformed parameters
            check_greater_or_equal(function__,"P",P,0);

            // write transformed parameters
            if (include_tparams__) {
        vars__.push_back(P);
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ mu;
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(mu, get_base1(beta,1,"beta",1));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(mu);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_GenF";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        param_name_stream__.str(std::string());
        param_name_stream__ << "sigma";
        param_names__.push_back(param_name_stream__.str());
        param_name_stream__.str(std::string());
        param_name_stream__ << "Q";
        param_names__.push_back(param_name_stream__.str());
        param_name_stream__.str(std::string());
        param_name_stream__ << "logP";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "cens" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "P";
            param_names__.push_back(param_name_stream__.str());
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "mu";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        param_name_stream__.str(std::string());
        param_name_stream__ << "sigma";
        param_names__.push_back(param_name_stream__.str());
        param_name_stream__.str(std::string());
        param_name_stream__ << "Q";
        param_names__.push_back(param_name_stream__.str());
        param_name_stream__.str(std::string());
        param_name_stream__ << "logP";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "cens" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "P";
            param_names__.push_back(param_name_stream__.str());
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "mu";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_GenGamma_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_GenGamma");
    reader.add_event(80, 78, "end", "model_GenGamma");
    return reader;
}

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
gen_gamma_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                   const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                   const T2__& sigma,
                   const T3__& Q, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("prob", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  prob(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);
        local_scalar_t__ lprob;
        (void) lprob;  // dummy to suppress unused var warning

        stan::math::initialize(lprob, DUMMY_VAR__);
        stan::math::fill(lprob,DUMMY_VAR__);
        validate_non_negative_index("w", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  w(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) w;  // dummy to suppress unused var warning

        stan::math::initialize(w, DUMMY_VAR__);
        stan::math::fill(w,DUMMY_VAR__);


        stan::math::assign(w, divide(subtract(stan::math::log(x),mu),sigma));
        for (int i = 1; i <= num_elements(x); ++i) {

            stan::model::assign(prob, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        ((((-(stan::math::log((sigma * get_base1(x,i,"x",1)))) + stan::math::log(stan::math::fabs(Q))) + (pow(Q,-(2)) * stan::math::log(pow(Q,-(2))))) + (pow(Q,-(2)) * ((Q * get_base1(w,i,"w",1)) - stan::math::exp((Q * get_base1(w,i,"w",1)))))) - stan::math::lgamma(pow(Q,-(2)))), 
                        "assigning variable prob");
        }
        stan::math::assign(lprob, sum(prob));
        return stan::math::promote_scalar<fun_return_scalar_t__>(lprob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
gen_gamma_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                   const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                   const T2__& sigma,
                   const T3__& Q, std::ostream* pstream__) {
    return gen_gamma_lpdf<false>(x,mu,sigma,Q, pstream__);
}


struct gen_gamma_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                   const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                   const T2__& sigma,
                   const T3__& Q, std::ostream* pstream__) const {
        return gen_gamma_lpdf(x, mu, sigma, Q, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type
gen_gamma_cens_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                        const T2__& sigma,
                        const T3__& Q,
                        const Eigen::Matrix<T4__, Eigen::Dynamic,1>& u, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("prob", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  prob(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);
        local_scalar_t__ lprob;
        (void) lprob;  // dummy to suppress unused var warning

        stan::math::initialize(lprob, DUMMY_VAR__);
        stan::math::fill(lprob,DUMMY_VAR__);
        validate_non_negative_index("w", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  w(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) w;  // dummy to suppress unused var warning

        stan::math::initialize(w, DUMMY_VAR__);
        stan::math::fill(w,DUMMY_VAR__);
        validate_non_negative_index("tr", "num_elements(x)", num_elements(x));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  tr(static_cast<Eigen::VectorXd::Index>(num_elements(x)));
        (void) tr;  // dummy to suppress unused var warning

        stan::math::initialize(tr, DUMMY_VAR__);
        stan::math::fill(tr,DUMMY_VAR__);


        stan::math::assign(tr, elt_multiply(x,u));
        stan::math::assign(w, divide(subtract(stan::math::log(tr),mu),sigma));
        for (int i = 1; i <= num_elements(x); ++i) {

            stan::model::assign(prob, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        (((((stan::math::log(get_base1(u,i,"u",1)) - stan::math::log((sigma * get_base1(tr,i,"tr",1)))) + stan::math::log(stan::math::fabs(Q))) + (pow(Q,-(2)) * stan::math::log(pow(Q,-(2))))) + (pow(Q,-(2)) * ((Q * get_base1(w,i,"w",1)) - stan::math::exp((Q * get_base1(w,i,"w",1)))))) - stan::math::lgamma(pow(Q,-(2)))), 
                        "assigning variable prob");
        }
        stan::math::assign(lprob, sum(prob));
        return stan::math::promote_scalar<fun_return_scalar_t__>(lprob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__, typename T4__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type
gen_gamma_cens_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                        const T2__& sigma,
                        const T3__& Q,
                        const Eigen::Matrix<T4__, Eigen::Dynamic,1>& u, std::ostream* pstream__) {
    return gen_gamma_cens_lpdf<false>(x,mu,sigma,Q,u, pstream__);
}


struct gen_gamma_cens_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__>::type>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& x,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mu,
                        const T2__& sigma,
                        const T3__& Q,
                        const Eigen::Matrix<T4__, Eigen::Dynamic,1>& u, std::ostream* pstream__) const {
        return gen_gamma_cens_lpdf(x, mu, sigma, Q, u, pstream__);
    }
};

class model_GenGamma : public prob_grad {
private:
    int n_obs;
    int n_cens;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X_obs;
    matrix_d X_cens;
    vector_d mu_beta;
    vector_d sigma_beta;
    double mu_Q;
    double sigma_Q;
    double a_sigma;
    double b_sigma;
public:
    model_GenGamma(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_GenGamma(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_GenGamma_namespace::model_GenGamma";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n_obs", "int", context__.to_vec());
            n_obs = int(0);
            vals_i__ = context__.vals_i("n_obs");
            pos__ = 0;
            n_obs = vals_i__[pos__++];
            context__.validate_dims("data initialization", "n_cens", "int", context__.to_vec());
            n_cens = int(0);
            vals_i__ = context__.vals_i("n_cens");
            pos__ = 0;
            n_cens = vals_i__[pos__++];
            validate_non_negative_index("t", "n_obs", n_obs);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n_obs));
            validate_non_negative_index("t", "n_obs", n_obs);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n_obs));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n_obs;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n_cens", n_cens);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n_cens));
            validate_non_negative_index("d", "n_cens", n_cens);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n_cens));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n_cens;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X_obs", "n_obs", n_obs);
            validate_non_negative_index("X_obs", "H", H);
            context__.validate_dims("data initialization", "X_obs", "matrix_d", context__.to_vec(n_obs,H));
            validate_non_negative_index("X_obs", "n_obs", n_obs);
            validate_non_negative_index("X_obs", "H", H);
            X_obs = matrix_d(static_cast<Eigen::VectorXd::Index>(n_obs),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X_obs");
            pos__ = 0;
            size_t X_obs_m_mat_lim__ = n_obs;
            size_t X_obs_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_obs_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_obs_m_mat_lim__; ++m_mat__) {
                    X_obs(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("X_cens", "n_cens", n_cens);
            validate_non_negative_index("X_cens", "H", H);
            context__.validate_dims("data initialization", "X_cens", "matrix_d", context__.to_vec(n_cens,H));
            validate_non_negative_index("X_cens", "n_cens", n_cens);
            validate_non_negative_index("X_cens", "H", H);
            X_cens = matrix_d(static_cast<Eigen::VectorXd::Index>(n_cens),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X_cens");
            pos__ = 0;
            size_t X_cens_m_mat_lim__ = n_cens;
            size_t X_cens_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_cens_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_cens_m_mat_lim__; ++m_mat__) {
                    X_cens(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "mu_Q", "double", context__.to_vec());
            mu_Q = double(0);
            vals_r__ = context__.vals_r("mu_Q");
            pos__ = 0;
            mu_Q = vals_r__[pos__++];
            context__.validate_dims("data initialization", "sigma_Q", "double", context__.to_vec());
            sigma_Q = double(0);
            vals_r__ = context__.vals_r("sigma_Q");
            pos__ = 0;
            sigma_Q = vals_r__[pos__++];
            context__.validate_dims("data initialization", "a_sigma", "double", context__.to_vec());
            a_sigma = double(0);
            vals_r__ = context__.vals_r("a_sigma");
            pos__ = 0;
            a_sigma = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_sigma", "double", context__.to_vec());
            b_sigma = double(0);
            vals_r__ = context__.vals_r("b_sigma");
            pos__ = 0;
            b_sigma = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"n_obs",n_obs,1);
            check_greater_or_equal(function__,"n_cens",n_cens,0);
            check_greater_or_equal(function__,"t",t,0);
            check_greater_or_equal(function__,"d",d,0);
            check_greater_or_equal(function__,"H",H,1);
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"sigma_Q",sigma_Q,0);
            check_greater_or_equal(function__,"a_sigma",a_sigma,0);
            check_greater_or_equal(function__,"b_sigma",b_sigma,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            ++num_params_r__;
            ++num_params_r__;
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            validate_non_negative_index("cens", "n_cens", n_cens);
            num_params_r__ += n_cens;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_GenGamma() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("Q")))
            throw std::runtime_error("variable Q missing");
        vals_r__ = context__.vals_r("Q");
        pos__ = 0U;
        context__.validate_dims("initialization", "Q", "double", context__.to_vec());
        double Q(0);
        Q = vals_r__[pos__++];
        try {
            writer__.scalar_unconstrain(Q);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable Q: ") + e.what());
        }

        if (!(context__.contains_r("sigma")))
            throw std::runtime_error("variable sigma missing");
        vals_r__ = context__.vals_r("sigma");
        pos__ = 0U;
        context__.validate_dims("initialization", "sigma", "double", context__.to_vec());
        double sigma(0);
        sigma = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,sigma);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable sigma: ") + e.what());
        }

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("cens")))
            throw std::runtime_error("variable cens missing");
        vals_r__ = context__.vals_r("cens");
        pos__ = 0U;
        validate_non_negative_index("cens", "n_cens", n_cens);
        context__.validate_dims("initialization", "cens", "vector_d", context__.to_vec(n_cens));
        vector_d cens(static_cast<Eigen::VectorXd::Index>(n_cens));
        for (int j1__ = 0U; j1__ < n_cens; ++j1__)
            cens(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_lb_unconstrain(1,cens);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable cens: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            local_scalar_t__ Q;
            (void) Q;  // dummy to suppress unused var warning
            if (jacobian__)
                Q = in__.scalar_constrain(lp__);
            else
                Q = in__.scalar_constrain();

            local_scalar_t__ sigma;
            (void) sigma;  // dummy to suppress unused var warning
            if (jacobian__)
                sigma = in__.scalar_lb_constrain(0,lp__);
            else
                sigma = in__.scalar_lb_constrain(0);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  cens;
            (void) cens;  // dummy to suppress unused var warning
            if (jacobian__)
                cens = in__.vector_lb_constrain(1,n_cens,lp__);
            else
                cens = in__.vector_lb_constrain(1,n_cens);


            // transformed parameters



            // validate transformed parameters

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(normal_log<propto__>(Q, mu_Q, sigma_Q));
            lp_accum__.add(gamma_log<propto__>(sigma, a_sigma, b_sigma));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(gen_gamma_cens_lpdf<propto__>(cens, multiply(X_cens,beta), sigma, Q, d, pstream__));
            lp_accum__.add(gen_gamma_lpdf<propto__>(t, multiply(X_obs,beta), sigma, Q, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("Q");
        names__.push_back("sigma");
        names__.push_back("beta");
        names__.push_back("cens");
        names__.push_back("mu");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n_cens);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_GenGamma_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        double Q = in__.scalar_constrain();
        double sigma = in__.scalar_lb_constrain(0);
        vector_d beta = in__.vector_constrain(H);
        vector_d cens = in__.vector_lb_constrain(1,n_cens);
        vars__.push_back(Q);
        vars__.push_back(sigma);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n_cens; ++k_0__) {
            vars__.push_back(cens[k_0__]);
            }

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {



            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ mu;
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(mu, get_base1(beta,1,"beta",1));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(mu);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_GenGamma";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        param_name_stream__.str(std::string());
        param_name_stream__ << "Q";
        param_names__.push_back(param_name_stream__.str());
        param_name_stream__.str(std::string());
        param_name_stream__ << "sigma";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "cens" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "mu";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        param_name_stream__.str(std::string());
        param_name_stream__ << "Q";
        param_names__.push_back(param_name_stream__.str());
        param_name_stream__.str(std::string());
        param_name_stream__ << "sigma";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= n_cens; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "cens" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "mu";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_Gompertz_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_Gompertz");
    reader.add_event(67, 65, "end", "model_Gompertz");
    return reader;
}

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_h(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_h", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_h(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_h;  // dummy to suppress unused var warning

        stan::math::initialize(log_h, DUMMY_VAR__);
        stan::math::fill(log_h,DUMMY_VAR__);


        stan::math::assign(log_h, add(stan::math::log(rate),multiply(shape,t)));
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_h);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_h_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) const {
        return log_h(t, shape, rate, pstream__);
    }
};

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_S(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_S", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_S(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_S;  // dummy to suppress unused var warning

        stan::math::initialize(log_S, DUMMY_VAR__);
        stan::math::fill(log_S,DUMMY_VAR__);


        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_S, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        ((-(get_base1(rate,i,"rate",1)) / shape) * (stan::math::exp((shape * get_base1(t,i,"t",1))) - 1)), 
                        "assigning variable log_S");
        }
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_S);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_S_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& rate, std::ostream* pstream__) const {
        return log_S(t, shape, rate, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_gompertz_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                       const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                       const T2__& shape,
                       const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ prob;
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);


        stan::math::assign(log_lik, add(elt_multiply(d,log_h(t,shape,scale, pstream__)),log_S(t,shape,scale, pstream__)));
        stan::math::assign(prob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(prob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_gompertz_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                       const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                       const T2__& shape,
                       const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    return surv_gompertz_lpdf<false>(t,d,shape,scale, pstream__);
}


struct surv_gompertz_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                       const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                       const T2__& shape,
                       const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return surv_gompertz_lpdf(t, d, shape, scale, pstream__);
    }
};

class model_Gompertz : public prob_grad {
private:
    int n;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X;
    vector_d mu_beta;
    vector_d sigma_beta;
    double a_alpha;
    double b_alpha;
public:
    model_Gompertz(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_Gompertz(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_Gompertz_namespace::model_Gompertz";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(n,H));
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    X(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "a_alpha", "double", context__.to_vec());
            a_alpha = double(0);
            vals_r__ = context__.vals_r("a_alpha");
            pos__ = 0;
            a_alpha = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_alpha", "double", context__.to_vec());
            b_alpha = double(0);
            vals_r__ = context__.vals_r("b_alpha");
            pos__ = 0;
            b_alpha = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"a_alpha",a_alpha,0);
            check_greater_or_equal(function__,"b_alpha",b_alpha,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            ++num_params_r__;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_Gompertz() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("alpha")))
            throw std::runtime_error("variable alpha missing");
        vals_r__ = context__.vals_r("alpha");
        pos__ = 0U;
        context__.validate_dims("initialization", "alpha", "double", context__.to_vec());
        double alpha(0);
        alpha = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,alpha);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable alpha: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            local_scalar_t__ alpha;
            (void) alpha;  // dummy to suppress unused var warning
            if (jacobian__)
                alpha = in__.scalar_lb_constrain(0,lp__);
            else
                alpha = in__.scalar_lb_constrain(0);


            // transformed parameters
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(linpred(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: linpred" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(mu(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: mu" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(gamma_log<propto__>(alpha, a_alpha, b_alpha));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(surv_gompertz_lpdf<propto__>(t, d, alpha, mu, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("beta");
        names__.push_back("alpha");
        names__.push_back("linpred");
        names__.push_back("mu");
        names__.push_back("rate");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_Gompertz_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d beta = in__.vector_constrain(H);
        double alpha = in__.scalar_lb_constrain(0);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
        vars__.push_back(alpha);

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(linpred[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(mu[k_0__]);
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ rate;
            (void) rate;  // dummy to suppress unused var warning

            stan::math::initialize(rate, DUMMY_VAR__);
            stan::math::fill(rate,DUMMY_VAR__);


            stan::math::assign(rate, stan::math::exp(get_base1(beta,1,"beta",1)));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(rate);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_Gompertz";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_PolyWeibull_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_PolyWeibull");
    reader.add_event(106, 104, "end", "model_PolyWeibull");
    return reader;
}

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
polyweibull_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                     const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                     const Eigen::Matrix<T2__, Eigen::Dynamic,1>& shape,
                     const Eigen::Matrix<T3__, Eigen::Dynamic,Eigen::Dynamic>& rate,
                     const int& M, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("h", "num_elements(t)", num_elements(t));
        validate_non_negative_index("h", "M", M);
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  h(static_cast<Eigen::VectorXd::Index>(num_elements(t)),static_cast<Eigen::VectorXd::Index>(M));
        (void) h;  // dummy to suppress unused var warning

        stan::math::initialize(h, DUMMY_VAR__);
        stan::math::fill(h,DUMMY_VAR__);
        validate_non_negative_index("log_S", "num_elements(t)", num_elements(t));
        validate_non_negative_index("log_S", "M", M);
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  log_S(static_cast<Eigen::VectorXd::Index>(num_elements(t)),static_cast<Eigen::VectorXd::Index>(M));
        (void) log_S;  // dummy to suppress unused var warning

        stan::math::initialize(log_S, DUMMY_VAR__);
        stan::math::fill(log_S,DUMMY_VAR__);
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ prob;
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);


        for (int j = 1; j <= M; ++j) {

            for (int i = 1; i <= num_elements(t); ++i) {

                stan::model::assign(h, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::cons_list(stan::model::index_uni(j), stan::model::nil_index_list())), 
                            ((get_base1(shape,j,"shape",1) * get_base1(rate,i,j,"rate",1)) * pow(get_base1(t,i,"t",1),(get_base1(shape,j,"shape",1) - 1))), 
                            "assigning variable h");
                stan::model::assign(log_S, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::cons_list(stan::model::index_uni(j), stan::model::nil_index_list())), 
                            (get_base1(rate,i,j,"rate",1) * pow(get_base1(t,i,"t",1),get_base1(shape,j,"shape",1))), 
                            "assigning variable log_S");
            }
        }
        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_lik, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        ((get_base1(d,i,"d",1) * stan::math::log(sum(stan::model::rvalue(h, stan::model::cons_list(stan::model::index_uni(i), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "h")))) - sum(stan::model::rvalue(log_S, stan::model::cons_list(stan::model::index_uni(i), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "log_S"))), 
                        "assigning variable log_lik");
        }
        stan::math::assign(prob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(prob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
polyweibull_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                     const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                     const Eigen::Matrix<T2__, Eigen::Dynamic,1>& shape,
                     const Eigen::Matrix<T3__, Eigen::Dynamic,Eigen::Dynamic>& rate,
                     const int& M, std::ostream* pstream__) {
    return polyweibull_lpdf<false>(t,d,shape,rate,M, pstream__);
}


struct polyweibull_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                     const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                     const Eigen::Matrix<T2__, Eigen::Dynamic,1>& shape,
                     const Eigen::Matrix<T3__, Eigen::Dynamic,Eigen::Dynamic>& rate,
                     const int& M, std::ostream* pstream__) const {
        return polyweibull_lpdf(t, d, shape, rate, M, pstream__);
    }
};

class model_PolyWeibull : public prob_grad {
private:
    int n;
    vector_d t;
    vector_d d;
    int H;
    int M;
    vector<matrix_d> X;
    matrix_d mu_beta;
    matrix_d sigma_beta;
public:
    model_PolyWeibull(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_PolyWeibull(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_PolyWeibull_namespace::model_PolyWeibull";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            context__.validate_dims("data initialization", "M", "int", context__.to_vec());
            M = int(0);
            vals_i__ = context__.vals_i("M");
            pos__ = 0;
            M = vals_i__[pos__++];
            validate_non_negative_index("X", "M", M);
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(M,n,H));
            validate_non_negative_index("X", "M", M);
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = std::vector<matrix_d>(M,matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H)));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    size_t X_limit_0__ = M;
                    for (size_t i_0__ = 0; i_0__ < X_limit_0__; ++i_0__) {
                        X[i_0__](m_mat__,n_mat__) = vals_r__[pos__++];
            }
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            validate_non_negative_index("mu_beta", "M", M);
            context__.validate_dims("data initialization", "mu_beta", "matrix_d", context__.to_vec(H,M));
            validate_non_negative_index("mu_beta", "H", H);
            validate_non_negative_index("mu_beta", "M", M);
            mu_beta = matrix_d(static_cast<Eigen::VectorXd::Index>(H),static_cast<Eigen::VectorXd::Index>(M));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_m_mat_lim__ = H;
            size_t mu_beta_n_mat_lim__ = M;
            for (size_t n_mat__ = 0; n_mat__ < mu_beta_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < mu_beta_m_mat_lim__; ++m_mat__) {
                    mu_beta(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("sigma_beta", "H", H);
            validate_non_negative_index("sigma_beta", "M", M);
            context__.validate_dims("data initialization", "sigma_beta", "matrix_d", context__.to_vec(H,M));
            validate_non_negative_index("sigma_beta", "H", H);
            validate_non_negative_index("sigma_beta", "M", M);
            sigma_beta = matrix_d(static_cast<Eigen::VectorXd::Index>(H),static_cast<Eigen::VectorXd::Index>(M));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_m_mat_lim__ = H;
            size_t sigma_beta_n_mat_lim__ = M;
            for (size_t n_mat__ = 0; n_mat__ < sigma_beta_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < sigma_beta_m_mat_lim__; ++m_mat__) {
                    sigma_beta(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }

            // validate, data variables
            check_greater_or_equal(function__,"H",H,2);
            check_greater_or_equal(function__,"M",M,2);
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("beta", "H", H);
            validate_non_negative_index("beta", "M", M);
            num_params_r__ += H * M;
            validate_non_negative_index("alpha", "M", M);
            num_params_r__ += M;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_PolyWeibull() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "M", M);
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(M,H));
        std::vector<vector_d> beta(M,vector_d(static_cast<Eigen::VectorXd::Index>(H)));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            for (int i0__ = 0U; i0__ < M; ++i0__)
                beta[i0__](j1__) = vals_r__[pos__++];
        for (int i0__ = 0U; i0__ < M; ++i0__)
            try {
            writer__.vector_unconstrain(beta[i0__]);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("alpha")))
            throw std::runtime_error("variable alpha missing");
        vals_r__ = context__.vals_r("alpha");
        pos__ = 0U;
        validate_non_negative_index("alpha", "M", M);
        context__.validate_dims("initialization", "alpha", "vector_d", context__.to_vec(M));
        vector_d alpha(static_cast<Eigen::VectorXd::Index>(M));
        for (int j1__ = 0U; j1__ < M; ++j1__)
            alpha(j1__) = vals_r__[pos__++];
        try {
            writer__.positive_ordered_unconstrain(alpha);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable alpha: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            vector<Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1> > beta;
            size_t dim_beta_0__ = M;
            beta.reserve(dim_beta_0__);
            for (size_t k_0__ = 0; k_0__ < dim_beta_0__; ++k_0__) {
                if (jacobian__)
                    beta.push_back(in__.vector_constrain(H,lp__));
                else
                    beta.push_back(in__.vector_constrain(H));
            }

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  alpha;
            (void) alpha;  // dummy to suppress unused var warning
            if (jacobian__)
                alpha = in__.positive_ordered_constrain(M,lp__);
            else
                alpha = in__.positive_ordered_constrain(M);


            // transformed parameters
            validate_non_negative_index("loglambda", "n", n);
            validate_non_negative_index("loglambda", "M", M);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  loglambda(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(M));
            (void) loglambda;  // dummy to suppress unused var warning

            stan::math::initialize(loglambda, DUMMY_VAR__);
            stan::math::fill(loglambda,DUMMY_VAR__);
            validate_non_negative_index("lambda", "n", n);
            validate_non_negative_index("lambda", "M", M);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  lambda(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(M));
            (void) lambda;  // dummy to suppress unused var warning

            stan::math::initialize(lambda, DUMMY_VAR__);
            stan::math::fill(lambda,DUMMY_VAR__);


            for (int m = 1; m <= M; ++m) {

                stan::model::assign(loglambda, 
                            stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_uni(m), stan::model::nil_index_list())), 
                            multiply(stan::model::rvalue(X, stan::model::cons_list(stan::model::index_uni(m), stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list()))), "X"),stan::model::rvalue(beta, stan::model::cons_list(stan::model::index_uni(m), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "beta")), 
                            "assigning variable loglambda");
                for (int i = 1; i <= n; ++i) {

                    stan::model::assign(lambda, 
                                stan::model::cons_list(stan::model::index_uni(i), stan::model::cons_list(stan::model::index_uni(m), stan::model::nil_index_list())), 
                                stan::math::exp(get_base1(loglambda,i,m,"loglambda",1)), 
                                "assigning variable lambda");
                }
            }

            // validate transformed parameters
            for (int i0__ = 0; i0__ < n; ++i0__) {
                for (int i1__ = 0; i1__ < M; ++i1__) {
                    if (stan::math::is_uninitialized(loglambda(i0__,i1__))) {
                        std::stringstream msg__;
                        msg__ << "Undefined transformed parameter: loglambda" << '[' << i0__ << ']' << '[' << i1__ << ']';
                        throw std::runtime_error(msg__.str());
                    }
                }
            }
            for (int i0__ = 0; i0__ < n; ++i0__) {
                for (int i1__ = 0; i1__ < M; ++i1__) {
                    if (stan::math::is_uninitialized(lambda(i0__,i1__))) {
                        std::stringstream msg__;
                        msg__ << "Undefined transformed parameter: lambda" << '[' << i0__ << ']' << '[' << i1__ << ']';
                        throw std::runtime_error(msg__.str());
                    }
                }
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            for (int m = 1; m <= M; ++m) {

                lp_accum__.add(normal_log<propto__>(stan::model::rvalue(beta, stan::model::cons_list(stan::model::index_uni(m), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "beta"), stan::model::rvalue(mu_beta, stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_uni(m), stan::model::nil_index_list())), "mu_beta"), stan::model::rvalue(sigma_beta, stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_uni(m), stan::model::nil_index_list())), "sigma_beta")));
            }
            lp_accum__.add(polyweibull_lpdf<propto__>(t, d, alpha, lambda, M, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("beta");
        names__.push_back("alpha");
        names__.push_back("loglambda");
        names__.push_back("lambda");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back(M);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(M);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dims__.push_back(M);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dims__.push_back(M);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_PolyWeibull_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector<vector_d> beta;
        size_t dim_beta_0__ = M;
        for (size_t k_0__ = 0; k_0__ < dim_beta_0__; ++k_0__) {
            beta.push_back(in__.vector_constrain(H));
        }
        vector_d alpha = in__.positive_ordered_constrain(M);
            for (int k_1__ = 0; k_1__ < H; ++k_1__) {
                for (int k_0__ = 0; k_0__ < M; ++k_0__) {
                vars__.push_back(beta[k_0__][k_1__]);
                }
            }
            for (int k_0__ = 0; k_0__ < M; ++k_0__) {
            vars__.push_back(alpha[k_0__]);
            }

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            validate_non_negative_index("loglambda", "n", n);
            validate_non_negative_index("loglambda", "M", M);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  loglambda(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(M));
            (void) loglambda;  // dummy to suppress unused var warning

            stan::math::initialize(loglambda, DUMMY_VAR__);
            stan::math::fill(loglambda,DUMMY_VAR__);
            validate_non_negative_index("lambda", "n", n);
            validate_non_negative_index("lambda", "M", M);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  lambda(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(M));
            (void) lambda;  // dummy to suppress unused var warning

            stan::math::initialize(lambda, DUMMY_VAR__);
            stan::math::fill(lambda,DUMMY_VAR__);


            for (int m = 1; m <= M; ++m) {

                stan::model::assign(loglambda, 
                            stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_uni(m), stan::model::nil_index_list())), 
                            multiply(stan::model::rvalue(X, stan::model::cons_list(stan::model::index_uni(m), stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list()))), "X"),stan::model::rvalue(beta, stan::model::cons_list(stan::model::index_uni(m), stan::model::cons_list(stan::model::index_omni(), stan::model::nil_index_list())), "beta")), 
                            "assigning variable loglambda");
                for (int i = 1; i <= n; ++i) {

                    stan::model::assign(lambda, 
                                stan::model::cons_list(stan::model::index_uni(i), stan::model::cons_list(stan::model::index_uni(m), stan::model::nil_index_list())), 
                                stan::math::exp(get_base1(loglambda,i,m,"loglambda",1)), 
                                "assigning variable lambda");
                }
            }

            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            for (int k_1__ = 0; k_1__ < M; ++k_1__) {
                for (int k_0__ = 0; k_0__ < n; ++k_0__) {
                vars__.push_back(loglambda(k_0__, k_1__));
                }
            }
            for (int k_1__ = 0; k_1__ < M; ++k_1__) {
                for (int k_0__ = 0; k_0__ < n; ++k_0__) {
                vars__.push_back(lambda(k_0__, k_1__));
                }
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities



            // validate generated quantities

            // write generated quantities
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_PolyWeibull";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_1__ = 1; k_1__ <= H; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= M; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "beta" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }
        for (int k_0__ = 1; k_0__ <= M; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "alpha" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_1__ = 1; k_1__ <= M; ++k_1__) {
                for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                    param_name_stream__.str(std::string());
                    param_name_stream__ << "loglambda" << '.' << k_0__ << '.' << k_1__;
                    param_names__.push_back(param_name_stream__.str());
                }
            }
            for (int k_1__ = 1; k_1__ <= M; ++k_1__) {
                for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                    param_name_stream__.str(std::string());
                    param_name_stream__ << "lambda" << '.' << k_0__ << '.' << k_1__;
                    param_names__.push_back(param_name_stream__.str());
                }
            }
        }


        if (!include_gqs__) return;
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_1__ = 1; k_1__ <= H; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= M; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "beta" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }
        for (int k_0__ = 1; k_0__ <= M; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "alpha" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_1__ = 1; k_1__ <= M; ++k_1__) {
                for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                    param_name_stream__.str(std::string());
                    param_name_stream__ << "loglambda" << '.' << k_0__ << '.' << k_1__;
                    param_names__.push_back(param_name_stream__.str());
                }
            }
            for (int k_1__ = 1; k_1__ <= M; ++k_1__) {
                for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                    param_name_stream__.str(std::string());
                    param_name_stream__ << "lambda" << '.' << k_0__ << '.' << k_1__;
                    param_names__.push_back(param_name_stream__.str());
                }
            }
        }


        if (!include_gqs__) return;
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_RP_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_RP");
    reader.add_event(53, 51, "end", "model_RP");
    return reader;
}

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__, typename T5__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type
rps_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
             const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
             const Eigen::Matrix<T2__, Eigen::Dynamic,1>& gamma,
             const Eigen::Matrix<T3__, Eigen::Dynamic,Eigen::Dynamic>& B,
             const Eigen::Matrix<T4__, Eigen::Dynamic,Eigen::Dynamic>& DB,
             const Eigen::Matrix<T5__, Eigen::Dynamic,1>& linpred, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("eta", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  eta(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) eta;  // dummy to suppress unused var warning

        stan::math::initialize(eta, DUMMY_VAR__);
        stan::math::fill(eta,DUMMY_VAR__);
        validate_non_negative_index("eta_prime", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  eta_prime(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) eta_prime;  // dummy to suppress unused var warning

        stan::math::initialize(eta_prime, DUMMY_VAR__);
        stan::math::fill(eta_prime,DUMMY_VAR__);
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ lprob;
        (void) lprob;  // dummy to suppress unused var warning

        stan::math::initialize(lprob, DUMMY_VAR__);
        stan::math::fill(lprob,DUMMY_VAR__);


        stan::math::assign(eta, add(multiply(B,gamma),linpred));
        stan::math::assign(eta_prime, multiply(DB,gamma));
        stan::math::assign(log_lik, subtract(elt_multiply(d,add(add(minus(stan::math::log(t)),stan::math::log(eta_prime)),eta)),stan::math::exp(eta)));
        stan::math::assign(lprob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(lprob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__, typename T4__, typename T5__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type
rps_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
             const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
             const Eigen::Matrix<T2__, Eigen::Dynamic,1>& gamma,
             const Eigen::Matrix<T3__, Eigen::Dynamic,Eigen::Dynamic>& B,
             const Eigen::Matrix<T4__, Eigen::Dynamic,Eigen::Dynamic>& DB,
             const Eigen::Matrix<T5__, Eigen::Dynamic,1>& linpred, std::ostream* pstream__) {
    return rps_lpdf<false>(t,d,gamma,B,DB,linpred, pstream__);
}


struct rps_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__, typename T4__, typename T5__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__, typename boost::math::tools::promote_args<T4__, T5__>::type>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
             const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
             const Eigen::Matrix<T2__, Eigen::Dynamic,1>& gamma,
             const Eigen::Matrix<T3__, Eigen::Dynamic,Eigen::Dynamic>& B,
             const Eigen::Matrix<T4__, Eigen::Dynamic,Eigen::Dynamic>& DB,
             const Eigen::Matrix<T5__, Eigen::Dynamic,1>& linpred, std::ostream* pstream__) const {
        return rps_lpdf(t, d, gamma, B, DB, linpred, pstream__);
    }
};

class model_RP : public prob_grad {
private:
    int n;
    int M;
    int H;
    vector_d t;
    vector_d d;
    matrix_d X;
    matrix_d B;
    matrix_d DB;
    vector_d mu_beta;
    vector_d sigma_beta;
    vector_d mu_gamma;
    vector_d sigma_gamma;
public:
    model_RP(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_RP(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_RP_namespace::model_RP";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            context__.validate_dims("data initialization", "M", "int", context__.to_vec());
            M = int(0);
            vals_i__ = context__.vals_i("M");
            pos__ = 0;
            M = vals_i__[pos__++];
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(n,H));
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    X(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("B", "n", n);
            validate_non_negative_index("B", "(M + 2)", (M + 2));
            context__.validate_dims("data initialization", "B", "matrix_d", context__.to_vec(n,(M + 2)));
            validate_non_negative_index("B", "n", n);
            validate_non_negative_index("B", "(M + 2)", (M + 2));
            B = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>((M + 2)));
            vals_r__ = context__.vals_r("B");
            pos__ = 0;
            size_t B_m_mat_lim__ = n;
            size_t B_n_mat_lim__ = (M + 2);
            for (size_t n_mat__ = 0; n_mat__ < B_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < B_m_mat_lim__; ++m_mat__) {
                    B(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("DB", "n", n);
            validate_non_negative_index("DB", "(M + 2)", (M + 2));
            context__.validate_dims("data initialization", "DB", "matrix_d", context__.to_vec(n,(M + 2)));
            validate_non_negative_index("DB", "n", n);
            validate_non_negative_index("DB", "(M + 2)", (M + 2));
            DB = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>((M + 2)));
            vals_r__ = context__.vals_r("DB");
            pos__ = 0;
            size_t DB_m_mat_lim__ = n;
            size_t DB_n_mat_lim__ = (M + 2);
            for (size_t n_mat__ = 0; n_mat__ < DB_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < DB_m_mat_lim__; ++m_mat__) {
                    DB(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("mu_gamma", "(M + 2)", (M + 2));
            context__.validate_dims("data initialization", "mu_gamma", "vector_d", context__.to_vec((M + 2)));
            validate_non_negative_index("mu_gamma", "(M + 2)", (M + 2));
            mu_gamma = vector_d(static_cast<Eigen::VectorXd::Index>((M + 2)));
            vals_r__ = context__.vals_r("mu_gamma");
            pos__ = 0;
            size_t mu_gamma_i_vec_lim__ = (M + 2);
            for (size_t i_vec__ = 0; i_vec__ < mu_gamma_i_vec_lim__; ++i_vec__) {
                mu_gamma[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_gamma", "(M + 2)", (M + 2));
            context__.validate_dims("data initialization", "sigma_gamma", "vector_d", context__.to_vec((M + 2)));
            validate_non_negative_index("sigma_gamma", "(M + 2)", (M + 2));
            sigma_gamma = vector_d(static_cast<Eigen::VectorXd::Index>((M + 2)));
            vals_r__ = context__.vals_r("sigma_gamma");
            pos__ = 0;
            size_t sigma_gamma_i_vec_lim__ = (M + 2);
            for (size_t i_vec__ = 0; i_vec__ < sigma_gamma_i_vec_lim__; ++i_vec__) {
                sigma_gamma[i_vec__] = vals_r__[pos__++];
            }

            // validate, data variables
            check_greater_or_equal(function__,"n",n,1);
            check_greater_or_equal(function__,"M",M,0);
            check_greater_or_equal(function__,"H",H,1);
            check_greater_or_equal(function__,"t",t,0);
            check_greater_or_equal(function__,"d",d,0);
            check_less_or_equal(function__,"d",d,1);
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"sigma_gamma",sigma_gamma,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("gamma", "(M + 2)", (M + 2));
            num_params_r__ += (M + 2);
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_RP() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("gamma")))
            throw std::runtime_error("variable gamma missing");
        vals_r__ = context__.vals_r("gamma");
        pos__ = 0U;
        validate_non_negative_index("gamma", "(M + 2)", (M + 2));
        context__.validate_dims("initialization", "gamma", "vector_d", context__.to_vec((M + 2)));
        vector_d gamma(static_cast<Eigen::VectorXd::Index>((M + 2)));
        for (int j1__ = 0U; j1__ < (M + 2); ++j1__)
            gamma(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(gamma);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable gamma: ") + e.what());
        }

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  gamma;
            (void) gamma;  // dummy to suppress unused var warning
            if (jacobian__)
                gamma = in__.vector_constrain((M + 2),lp__);
            else
                gamma = in__.vector_constrain((M + 2));

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);


            // transformed parameters



            // validate transformed parameters

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(normal_log<propto__>(gamma, mu_gamma, sigma_gamma));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(rps_lpdf<propto__>(t, d, gamma, B, DB, multiply(X,beta), pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("gamma");
        names__.push_back("beta");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back((M + 2));
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_RP_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d gamma = in__.vector_constrain((M + 2));
        vector_d beta = in__.vector_constrain(H);
            for (int k_0__ = 0; k_0__ < (M + 2); ++k_0__) {
            vars__.push_back(gamma[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {



            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            }
            if (!include_gqs__) return;
            // declare and define generated quantities



            // validate generated quantities

            // write generated quantities
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_RP";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= (M + 2); ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "gamma" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
        }


        if (!include_gqs__) return;
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= (M + 2); ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "gamma" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
        }


        if (!include_gqs__) return;
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_WeibullAF_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_WeibullAF");
    reader.add_event(67, 65, "end", "model_WeibullAF");
    return reader;
}

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_h(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_h", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_h(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_h;  // dummy to suppress unused var warning

        stan::math::initialize(log_h, DUMMY_VAR__);
        stan::math::fill(log_h,DUMMY_VAR__);


        stan::math::assign(log_h, subtract(add(stan::math::log(shape),multiply((shape - 1),stan::math::log(elt_divide(t,scale)))),stan::math::log(scale)));
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_h);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_h_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return log_h(t, shape, scale, pstream__);
    }
};

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_S(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_S", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_S(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_S;  // dummy to suppress unused var warning

        stan::math::initialize(log_S, DUMMY_VAR__);
        stan::math::fill(log_S,DUMMY_VAR__);


        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_S, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        -(pow((get_base1(t,i,"t",1) / get_base1(scale,i,"scale",1)),shape)), 
                        "assigning variable log_S");
        }
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_S);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_S_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return log_S(t, shape, scale, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_weibullAF_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const T2__& shape,
                        const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ prob;
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);


        stan::math::assign(log_lik, add(elt_multiply(d,log_h(t,shape,scale, pstream__)),log_S(t,shape,scale, pstream__)));
        stan::math::assign(prob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(prob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_weibullAF_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const T2__& shape,
                        const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    return surv_weibullAF_lpdf<false>(t,d,shape,scale, pstream__);
}


struct surv_weibullAF_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const T2__& shape,
                        const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return surv_weibullAF_lpdf(t, d, shape, scale, pstream__);
    }
};

class model_WeibullAF : public prob_grad {
private:
    int n;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X;
    vector_d mu_beta;
    vector_d sigma_beta;
    double a_alpha;
    double b_alpha;
public:
    model_WeibullAF(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_WeibullAF(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_WeibullAF_namespace::model_WeibullAF";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(n,H));
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    X(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "a_alpha", "double", context__.to_vec());
            a_alpha = double(0);
            vals_r__ = context__.vals_r("a_alpha");
            pos__ = 0;
            a_alpha = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_alpha", "double", context__.to_vec());
            b_alpha = double(0);
            vals_r__ = context__.vals_r("b_alpha");
            pos__ = 0;
            b_alpha = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"a_alpha",a_alpha,0);
            check_greater_or_equal(function__,"b_alpha",b_alpha,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            ++num_params_r__;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_WeibullAF() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("alpha")))
            throw std::runtime_error("variable alpha missing");
        vals_r__ = context__.vals_r("alpha");
        pos__ = 0U;
        context__.validate_dims("initialization", "alpha", "double", context__.to_vec());
        double alpha(0);
        alpha = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,alpha);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable alpha: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            local_scalar_t__ alpha;
            (void) alpha;  // dummy to suppress unused var warning
            if (jacobian__)
                alpha = in__.scalar_lb_constrain(0,lp__);
            else
                alpha = in__.scalar_lb_constrain(0);


            // transformed parameters
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(linpred(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: linpred" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(mu(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: mu" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(gamma_log<propto__>(alpha, a_alpha, b_alpha));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(surv_weibullAF_lpdf<propto__>(t, d, alpha, mu, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("beta");
        names__.push_back("alpha");
        names__.push_back("linpred");
        names__.push_back("mu");
        names__.push_back("scale");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_WeibullAF_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d beta = in__.vector_constrain(H);
        double alpha = in__.scalar_lb_constrain(0);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
        vars__.push_back(alpha);

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(linpred[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(mu[k_0__]);
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ scale;
            (void) scale;  // dummy to suppress unused var warning

            stan::math::initialize(scale, DUMMY_VAR__);
            stan::math::fill(scale,DUMMY_VAR__);


            stan::math::assign(scale, stan::math::exp(get_base1(beta,1,"beta",1)));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(scale);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_WeibullAF";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "scale";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "scale";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_WeibullPH_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_WeibullPH");
    reader.add_event(67, 65, "end", "model_WeibullPH");
    return reader;
}

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_h(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_h", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_h(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_h;  // dummy to suppress unused var warning

        stan::math::initialize(log_h, DUMMY_VAR__);
        stan::math::fill(log_h,DUMMY_VAR__);


        stan::math::assign(log_h, subtract(add(stan::math::log(shape),multiply((shape - 1),stan::math::log(elt_divide(t,scale)))),stan::math::log(scale)));
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_h);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_h_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return log_h(t, shape, scale, pstream__);
    }
};

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_S(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_S", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_S(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_S;  // dummy to suppress unused var warning

        stan::math::initialize(log_S, DUMMY_VAR__);
        stan::math::fill(log_S,DUMMY_VAR__);


        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_S, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        -(pow((get_base1(t,i,"t",1) / get_base1(scale,i,"scale",1)),shape)), 
                        "assigning variable log_S");
        }
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_S);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_S_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return log_S(t, shape, scale, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_weibullPH_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const T2__& shape,
                        const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ prob;
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);


        stan::math::assign(log_lik, add(elt_multiply(d,log_h(t,shape,scale, pstream__)),log_S(t,shape,scale, pstream__)));
        stan::math::assign(prob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(prob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_weibullPH_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const T2__& shape,
                        const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    return surv_weibullPH_lpdf<false>(t,d,shape,scale, pstream__);
}


struct surv_weibullPH_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const T2__& shape,
                        const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return surv_weibullPH_lpdf(t, d, shape, scale, pstream__);
    }
};

class model_WeibullPH : public prob_grad {
private:
    int n;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X;
    vector_d mu_beta;
    vector_d sigma_beta;
    double a_alpha;
    double b_alpha;
public:
    model_WeibullPH(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_WeibullPH(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_WeibullPH_namespace::model_WeibullPH";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(n,H));
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    X(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "a_alpha", "double", context__.to_vec());
            a_alpha = double(0);
            vals_r__ = context__.vals_r("a_alpha");
            pos__ = 0;
            a_alpha = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_alpha", "double", context__.to_vec());
            b_alpha = double(0);
            vals_r__ = context__.vals_r("b_alpha");
            pos__ = 0;
            b_alpha = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"a_alpha",a_alpha,0);
            check_greater_or_equal(function__,"b_alpha",b_alpha,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            ++num_params_r__;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_WeibullPH() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("alpha")))
            throw std::runtime_error("variable alpha missing");
        vals_r__ = context__.vals_r("alpha");
        pos__ = 0U;
        context__.validate_dims("initialization", "alpha", "double", context__.to_vec());
        double alpha(0);
        alpha = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,alpha);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable alpha: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            local_scalar_t__ alpha;
            (void) alpha;  // dummy to suppress unused var warning
            if (jacobian__)
                alpha = in__.scalar_lb_constrain(0,lp__);
            else
                alpha = in__.scalar_lb_constrain(0);


            // transformed parameters
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, divide(minus(multiply(X,beta)),alpha));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(linpred(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: linpred" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(mu(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: mu" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(gamma_log<propto__>(alpha, a_alpha, b_alpha));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(surv_weibullPH_lpdf<propto__>(t, d, alpha, mu, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("beta");
        names__.push_back("alpha");
        names__.push_back("linpred");
        names__.push_back("mu");
        names__.push_back("scale");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_WeibullPH_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d beta = in__.vector_constrain(H);
        double alpha = in__.scalar_lb_constrain(0);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
        vars__.push_back(alpha);

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, divide(minus(multiply(X,beta)),alpha));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(linpred[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(mu[k_0__]);
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ scale;
            (void) scale;  // dummy to suppress unused var warning

            stan::math::initialize(scale, DUMMY_VAR__);
            stan::math::fill(scale,DUMMY_VAR__);


            stan::math::assign(scale, stan::math::exp(get_base1(beta,1,"beta",1)));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(scale);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_WeibullPH";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "scale";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "scale";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_logLogistic_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_logLogistic");
    reader.add_event(70, 68, "end", "model_logLogistic");
    return reader;
}

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_h(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_h", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_h(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_h;  // dummy to suppress unused var warning

        stan::math::initialize(log_h, DUMMY_VAR__);
        stan::math::fill(log_h,DUMMY_VAR__);


        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_h, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        (((stan::math::log(shape) - stan::math::log(get_base1(scale,i,"scale",1))) + ((shape - 1) * (stan::math::log(get_base1(t,i,"t",1)) - stan::math::log(get_base1(scale,i,"scale",1))))) - stan::math::log((1 + pow((get_base1(t,i,"t",1) / get_base1(scale,i,"scale",1)),shape)))), 
                        "assigning variable log_h");
        }
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_h);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_h_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return log_h(t, shape, scale, pstream__);
    }
};

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_S(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_S", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_S(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_S;  // dummy to suppress unused var warning

        stan::math::initialize(log_S, DUMMY_VAR__);
        stan::math::fill(log_S,DUMMY_VAR__);


        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_S, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        -(stan::math::log((1 + pow((get_base1(t,i,"t",1) / get_base1(scale,i,"scale",1)),shape)))), 
                        "assigning variable log_S");
        }
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_S);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_S_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const T1__& shape,
          const Eigen::Matrix<T2__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return log_S(t, shape, scale, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_loglogistic_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                          const T2__& shape,
                          const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ prob;
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);


        stan::math::assign(log_lik, add(elt_multiply(d,log_h(t,shape,scale, pstream__)),log_S(t,shape,scale, pstream__)));
        stan::math::assign(prob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(prob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_loglogistic_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                          const T2__& shape,
                          const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) {
    return surv_loglogistic_lpdf<false>(t,d,shape,scale, pstream__);
}


struct surv_loglogistic_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                          const T2__& shape,
                          const Eigen::Matrix<T3__, Eigen::Dynamic,1>& scale, std::ostream* pstream__) const {
        return surv_loglogistic_lpdf(t, d, shape, scale, pstream__);
    }
};

class model_logLogistic : public prob_grad {
private:
    int n;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X;
    vector_d mu_beta;
    vector_d sigma_beta;
    double a_alpha;
    double b_alpha;
public:
    model_logLogistic(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_logLogistic(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_logLogistic_namespace::model_logLogistic";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(n,H));
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    X(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "a_alpha", "double", context__.to_vec());
            a_alpha = double(0);
            vals_r__ = context__.vals_r("a_alpha");
            pos__ = 0;
            a_alpha = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_alpha", "double", context__.to_vec());
            b_alpha = double(0);
            vals_r__ = context__.vals_r("b_alpha");
            pos__ = 0;
            b_alpha = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            check_greater_or_equal(function__,"a_alpha",a_alpha,0);
            check_greater_or_equal(function__,"b_alpha",b_alpha,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            ++num_params_r__;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_logLogistic() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("alpha")))
            throw std::runtime_error("variable alpha missing");
        vals_r__ = context__.vals_r("alpha");
        pos__ = 0U;
        context__.validate_dims("initialization", "alpha", "double", context__.to_vec());
        double alpha(0);
        alpha = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,alpha);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable alpha: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            local_scalar_t__ alpha;
            (void) alpha;  // dummy to suppress unused var warning
            if (jacobian__)
                alpha = in__.scalar_lb_constrain(0,lp__);
            else
                alpha = in__.scalar_lb_constrain(0);


            // transformed parameters
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(linpred(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: linpred" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }
            for (int i0__ = 0; i0__ < n; ++i0__) {
                if (stan::math::is_uninitialized(mu(i0__))) {
                    std::stringstream msg__;
                    msg__ << "Undefined transformed parameter: mu" << '[' << i0__ << ']';
                    throw std::runtime_error(msg__.str());
                }
            }

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(gamma_log<propto__>(alpha, a_alpha, b_alpha));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(surv_loglogistic_lpdf<propto__>(t, d, alpha, mu, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("beta");
        names__.push_back("alpha");
        names__.push_back("linpred");
        names__.push_back("mu");
        names__.push_back("rate");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(n);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_logLogistic_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d beta = in__.vector_constrain(H);
        double alpha = in__.scalar_lb_constrain(0);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
        vars__.push_back(alpha);

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {
            validate_non_negative_index("linpred", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  linpred(static_cast<Eigen::VectorXd::Index>(n));
            (void) linpred;  // dummy to suppress unused var warning

            stan::math::initialize(linpred, DUMMY_VAR__);
            stan::math::fill(linpred,DUMMY_VAR__);
            validate_non_negative_index("mu", "n", n);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  mu(static_cast<Eigen::VectorXd::Index>(n));
            (void) mu;  // dummy to suppress unused var warning

            stan::math::initialize(mu, DUMMY_VAR__);
            stan::math::fill(mu,DUMMY_VAR__);


            stan::math::assign(linpred, multiply(X,beta));
            for (int i = 1; i <= n; ++i) {

                stan::model::assign(mu, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            stan::math::exp(get_base1(linpred,i,"linpred",1)), 
                            "assigning variable mu");
            }

            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(linpred[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < n; ++k_0__) {
            vars__.push_back(mu[k_0__]);
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ rate;
            (void) rate;  // dummy to suppress unused var warning

            stan::math::initialize(rate, DUMMY_VAR__);
            stan::math::fill(rate,DUMMY_VAR__);


            stan::math::assign(rate, stan::math::exp(get_base1(beta,1,"beta",1)));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(rate);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_logLogistic";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "linpred" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
            for (int k_0__ = 1; k_0__ <= n; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "mu" << '.' << k_0__;
                param_names__.push_back(param_name_stream__.str());
            }
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "rate";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model_logNormal_namespace {

using std::istream;
using std::string;
using std::stringstream;
using std::vector;
using stan::io::dump;
using stan::math::lgamma;
using stan::model::prob_grad;
using namespace stan::math;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model_logNormal");
    reader.add_event(62, 60, "end", "model_logNormal");
    return reader;
}

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_S(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mean,
          const T2__& sd, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_S", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_S(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_S;  // dummy to suppress unused var warning

        stan::math::initialize(log_S, DUMMY_VAR__);
        stan::math::fill(log_S,DUMMY_VAR__);


        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_S, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        stan::math::log((1 - Phi(((stan::math::log(get_base1(t,i,"t",1)) - get_base1(mean,i,"mean",1)) / sd)))), 
                        "assigning variable log_S");
        }
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_S);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_S_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mean,
          const T2__& sd, std::ostream* pstream__) const {
        return log_S(t, mean, sd, pstream__);
    }
};

template <typename T0__, typename T1__, typename T2__>
Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
log_h(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mean,
          const T2__& sd, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_h", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_h(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_h;  // dummy to suppress unused var warning

        stan::math::initialize(log_h, DUMMY_VAR__);
        stan::math::fill(log_h,DUMMY_VAR__);
        validate_non_negative_index("ls", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  ls(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) ls;  // dummy to suppress unused var warning

        stan::math::initialize(ls, DUMMY_VAR__);
        stan::math::fill(ls,DUMMY_VAR__);


        stan::math::assign(ls, log_S(t,mean,sd, pstream__));
        for (int i = 1; i <= num_elements(t); ++i) {

            stan::model::assign(log_h, 
                        stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                        (lognormal_log(get_base1(t,i,"t",1),get_base1(mean,i,"mean",1),sd) - get_base1(ls,i,"ls",1)), 
                        "assigning variable log_h");
        }
        return stan::math::promote_scalar<fun_return_scalar_t__>(log_h);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}


struct log_h_functor__ {
    template <typename T0__, typename T1__, typename T2__>
        Eigen::Matrix<typename boost::math::tools::promote_args<T0__, T1__, T2__>::type, Eigen::Dynamic,1>
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
          const Eigen::Matrix<T1__, Eigen::Dynamic,1>& mean,
          const T2__& sd, std::ostream* pstream__) const {
        return log_h(t, mean, sd, pstream__);
    }
};

template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_lognormal_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const Eigen::Matrix<T2__, Eigen::Dynamic,1>& mean,
                        const T3__& sd, std::ostream* pstream__) {
    typedef typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type local_scalar_t__;
    typedef local_scalar_t__ fun_return_scalar_t__;
    const static bool propto__ = true;
    (void) propto__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

    int current_statement_begin__ = -1;
    try {
        {
        validate_non_negative_index("log_lik", "num_elements(t)", num_elements(t));
        Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  log_lik(static_cast<Eigen::VectorXd::Index>(num_elements(t)));
        (void) log_lik;  // dummy to suppress unused var warning

        stan::math::initialize(log_lik, DUMMY_VAR__);
        stan::math::fill(log_lik,DUMMY_VAR__);
        local_scalar_t__ prob;
        (void) prob;  // dummy to suppress unused var warning

        stan::math::initialize(prob, DUMMY_VAR__);
        stan::math::fill(prob,DUMMY_VAR__);


        stan::math::assign(log_lik, add(elt_multiply(d,log_h(t,mean,sd, pstream__)),log_S(t,mean,sd, pstream__)));
        stan::math::assign(prob, sum(log_lik));
        return stan::math::promote_scalar<fun_return_scalar_t__>(prob);
        }
    } catch (const std::exception& e) {
        stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
        // Next line prevents compiler griping about no return
        throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
    }
}
template <typename T0__, typename T1__, typename T2__, typename T3__>
typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
surv_lognormal_lpdf(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const Eigen::Matrix<T2__, Eigen::Dynamic,1>& mean,
                        const T3__& sd, std::ostream* pstream__) {
    return surv_lognormal_lpdf<false>(t,d,mean,sd, pstream__);
}


struct surv_lognormal_lpdf_functor__ {
    template <bool propto, typename T0__, typename T1__, typename T2__, typename T3__>
        typename boost::math::tools::promote_args<T0__, T1__, T2__, T3__>::type
    operator()(const Eigen::Matrix<T0__, Eigen::Dynamic,1>& t,
                        const Eigen::Matrix<T1__, Eigen::Dynamic,1>& d,
                        const Eigen::Matrix<T2__, Eigen::Dynamic,1>& mean,
                        const T3__& sd, std::ostream* pstream__) const {
        return surv_lognormal_lpdf(t, d, mean, sd, pstream__);
    }
};

class model_logNormal : public prob_grad {
private:
    int n;
    vector_d t;
    vector_d d;
    int H;
    matrix_d X;
    vector_d mu_beta;
    vector_d sigma_beta;
    double a_alpha;
    double b_alpha;
public:
    model_logNormal(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model_logNormal(stan::io::var_context& context__,
        unsigned int random_seed__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, random_seed__, pstream__);
    }

    void ctor_body(stan::io::var_context& context__,
                   unsigned int random_seed__,
                   std::ostream* pstream__) {
        typedef double local_scalar_t__;

        boost::ecuyer1988 base_rng__ =
          stan::services::util::create_rng(random_seed__, 0);
        (void) base_rng__;  // suppress unused var warning

        current_statement_begin__ = -1;

        static const char* function__ = "model_logNormal_namespace::model_logNormal";
        (void) function__;  // dummy to suppress unused var warning
        size_t pos__;
        (void) pos__;  // dummy to suppress unused var warning
        std::vector<int> vals_i__;
        std::vector<double> vals_r__;
        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            context__.validate_dims("data initialization", "n", "int", context__.to_vec());
            n = int(0);
            vals_i__ = context__.vals_i("n");
            pos__ = 0;
            n = vals_i__[pos__++];
            validate_non_negative_index("t", "n", n);
            context__.validate_dims("data initialization", "t", "vector_d", context__.to_vec(n));
            validate_non_negative_index("t", "n", n);
            t = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("t");
            pos__ = 0;
            size_t t_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < t_i_vec_lim__; ++i_vec__) {
                t[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("d", "n", n);
            context__.validate_dims("data initialization", "d", "vector_d", context__.to_vec(n));
            validate_non_negative_index("d", "n", n);
            d = vector_d(static_cast<Eigen::VectorXd::Index>(n));
            vals_r__ = context__.vals_r("d");
            pos__ = 0;
            size_t d_i_vec_lim__ = n;
            for (size_t i_vec__ = 0; i_vec__ < d_i_vec_lim__; ++i_vec__) {
                d[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "H", "int", context__.to_vec());
            H = int(0);
            vals_i__ = context__.vals_i("H");
            pos__ = 0;
            H = vals_i__[pos__++];
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(n,H));
            validate_non_negative_index("X", "n", n);
            validate_non_negative_index("X", "H", H);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(n),static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = n;
            size_t X_n_mat_lim__ = H;
            for (size_t n_mat__ = 0; n_mat__ < X_n_mat_lim__; ++n_mat__) {
                for (size_t m_mat__ = 0; m_mat__ < X_m_mat_lim__; ++m_mat__) {
                    X(m_mat__,n_mat__) = vals_r__[pos__++];
                }
            }
            validate_non_negative_index("mu_beta", "H", H);
            context__.validate_dims("data initialization", "mu_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("mu_beta", "H", H);
            mu_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("mu_beta");
            pos__ = 0;
            size_t mu_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < mu_beta_i_vec_lim__; ++i_vec__) {
                mu_beta[i_vec__] = vals_r__[pos__++];
            }
            validate_non_negative_index("sigma_beta", "H", H);
            context__.validate_dims("data initialization", "sigma_beta", "vector_d", context__.to_vec(H));
            validate_non_negative_index("sigma_beta", "H", H);
            sigma_beta = vector_d(static_cast<Eigen::VectorXd::Index>(H));
            vals_r__ = context__.vals_r("sigma_beta");
            pos__ = 0;
            size_t sigma_beta_i_vec_lim__ = H;
            for (size_t i_vec__ = 0; i_vec__ < sigma_beta_i_vec_lim__; ++i_vec__) {
                sigma_beta[i_vec__] = vals_r__[pos__++];
            }
            context__.validate_dims("data initialization", "a_alpha", "double", context__.to_vec());
            a_alpha = double(0);
            vals_r__ = context__.vals_r("a_alpha");
            pos__ = 0;
            a_alpha = vals_r__[pos__++];
            context__.validate_dims("data initialization", "b_alpha", "double", context__.to_vec());
            b_alpha = double(0);
            vals_r__ = context__.vals_r("b_alpha");
            pos__ = 0;
            b_alpha = vals_r__[pos__++];

            // validate, data variables
            check_greater_or_equal(function__,"sigma_beta",sigma_beta,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            validate_non_negative_index("beta", "H", H);
            num_params_r__ += H;
            ++num_params_r__;
        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    ~model_logNormal() { }


    void transform_inits(const stan::io::var_context& context__,
                         std::vector<int>& params_i__,
                         std::vector<double>& params_r__,
                         std::ostream* pstream__) const {
        stan::io::writer<double> writer__(params_r__,params_i__);
        size_t pos__;
        (void) pos__; // dummy call to supress warning
        std::vector<double> vals_r__;
        std::vector<int> vals_i__;

        if (!(context__.contains_r("beta")))
            throw std::runtime_error("variable beta missing");
        vals_r__ = context__.vals_r("beta");
        pos__ = 0U;
        validate_non_negative_index("beta", "H", H);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(H));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(H));
        for (int j1__ = 0U; j1__ < H; ++j1__)
            beta(j1__) = vals_r__[pos__++];
        try {
            writer__.vector_unconstrain(beta);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable beta: ") + e.what());
        }

        if (!(context__.contains_r("alpha")))
            throw std::runtime_error("variable alpha missing");
        vals_r__ = context__.vals_r("alpha");
        pos__ = 0U;
        context__.validate_dims("initialization", "alpha", "double", context__.to_vec());
        double alpha(0);
        alpha = vals_r__[pos__++];
        try {
            writer__.scalar_lb_unconstrain(0,alpha);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable alpha: ") + e.what());
        }

        params_r__ = writer__.data_r();
        params_i__ = writer__.data_i();
    }

    void transform_inits(const stan::io::var_context& context,
                         Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                         std::ostream* pstream__) const {
      std::vector<double> params_r_vec;
      std::vector<int> params_i_vec;
      transform_inits(context, params_i_vec, params_r_vec, pstream__);
      params_r.resize(params_r_vec.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r(i) = params_r_vec[i];
    }


    template <bool propto__, bool jacobian__, typename T__>
    T__ log_prob(vector<T__>& params_r__,
                 vector<int>& params_i__,
                 std::ostream* pstream__ = 0) const {

        typedef T__ local_scalar_t__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        T__ lp__(0.0);
        stan::math::accumulator<T__> lp_accum__;

        try {
            // model parameters
            stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  beta;
            (void) beta;  // dummy to suppress unused var warning
            if (jacobian__)
                beta = in__.vector_constrain(H,lp__);
            else
                beta = in__.vector_constrain(H);

            local_scalar_t__ alpha;
            (void) alpha;  // dummy to suppress unused var warning
            if (jacobian__)
                alpha = in__.scalar_lb_constrain(0,lp__);
            else
                alpha = in__.scalar_lb_constrain(0);


            // transformed parameters



            // validate transformed parameters

            const char* function__ = "validate transformed params";
            (void) function__;  // dummy to suppress unused var warning

            // model body

            lp_accum__.add(uniform_log<propto__>(alpha, a_alpha, b_alpha));
            lp_accum__.add(normal_log<propto__>(beta, mu_beta, sigma_beta));
            lp_accum__.add(surv_lognormal_lpdf<propto__>(t, d, multiply(X,beta), alpha, pstream__));

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }

        lp_accum__.add(lp__);
        return lp_accum__.sum();

    } // log_prob()

    template <bool propto, bool jacobian, typename T_>
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
               std::ostream* pstream = 0) const {
      std::vector<T_> vec_params_r;
      vec_params_r.reserve(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        vec_params_r.push_back(params_r(i));
      std::vector<int> vec_params_i;
      return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);
    }


    void get_param_names(std::vector<std::string>& names__) const {
        names__.resize(0);
        names__.push_back("beta");
        names__.push_back("alpha");
        names__.push_back("meanlog");
    }


    void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
        dimss__.resize(0);
        std::vector<size_t> dims__;
        dims__.resize(0);
        dims__.push_back(H);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
    }

    template <typename RNG>
    void write_array(RNG& base_rng__,
                     std::vector<double>& params_r__,
                     std::vector<int>& params_i__,
                     std::vector<double>& vars__,
                     bool include_tparams__ = true,
                     bool include_gqs__ = true,
                     std::ostream* pstream__ = 0) const {
        typedef double local_scalar_t__;

        vars__.resize(0);
        stan::io::reader<local_scalar_t__> in__(params_r__,params_i__);
        static const char* function__ = "model_logNormal_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d beta = in__.vector_constrain(H);
        double alpha = in__.scalar_lb_constrain(0);
            for (int k_0__ = 0; k_0__ < H; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
        vars__.push_back(alpha);

        // declare and define transformed parameters
        double lp__ = 0.0;
        (void) lp__;  // dummy to suppress unused var warning
        stan::math::accumulator<double> lp_accum__;

        local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        try {



            // validate transformed parameters

            // write transformed parameters
            if (include_tparams__) {
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            local_scalar_t__ meanlog;
            (void) meanlog;  // dummy to suppress unused var warning

            stan::math::initialize(meanlog, DUMMY_VAR__);
            stan::math::fill(meanlog,DUMMY_VAR__);


            stan::math::assign(meanlog, get_base1(beta,1,"beta",1));

            // validate generated quantities

            // write generated quantities
        vars__.push_back(meanlog);

        } catch (const std::exception& e) {
            stan::lang::rethrow_located(e, current_statement_begin__, prog_reader__());
            // Next line prevents compiler griping about no return
            throw std::runtime_error("*** IF YOU SEE THIS, PLEASE REPORT A BUG ***");
        }
    }

    template <typename RNG>
    void write_array(RNG& base_rng,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& params_r,
                     Eigen::Matrix<double,Eigen::Dynamic,1>& vars,
                     bool include_tparams = true,
                     bool include_gqs = true,
                     std::ostream* pstream = 0) const {
      std::vector<double> params_r_vec(params_r.size());
      for (int i = 0; i < params_r.size(); ++i)
        params_r_vec[i] = params_r(i);
      std::vector<double> vars_vec;
      std::vector<int> params_i_vec;
      write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);
      vars.resize(vars_vec.size());
      for (int i = 0; i < vars.size(); ++i)
        vars(i) = vars_vec[i];
    }

    static std::string model_name() {
        return "model_logNormal";
    }


    void constrained_param_names(std::vector<std::string>& param_names__,
                                 bool include_tparams__ = true,
                                 bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "meanlog";
        param_names__.push_back(param_name_stream__.str());
    }


    void unconstrained_param_names(std::vector<std::string>& param_names__,
                                   bool include_tparams__ = true,
                                   bool include_gqs__ = true) const {
        std::stringstream param_name_stream__;
        for (int k_0__ = 1; k_0__ <= H; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "beta" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "alpha";
        param_names__.push_back(param_name_stream__.str());

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
        }


        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "meanlog";
        param_names__.push_back(param_name_stream__.str());
    }

}; // model

}




#endif
