// Code generated by Stan version 2.18.0

#include <stan/model/model_header.hpp>

namespace model95fa31c99b80_glmm_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", "model95fa31c99b80_glmm");
    reader.add_event(50, 48, "end", "model95fa31c99b80_glmm");
    return reader;
}

class model95fa31c99b80_glmm : public prob_grad {
private:
    int N;
    int P;
    int J;
    vector<int> donor;
    vector<row_vector_d> X;
    vector<int> treatment;
    double eta;
public:
    model95fa31c99b80_glmm(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model95fa31c99b80_glmm(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__ = "model95fa31c99b80_glmm_namespace::model95fa31c99b80_glmm";
        (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 {
            current_statement_begin__ = 6;
            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__++];
            current_statement_begin__ = 7;
            context__.validate_dims("data initialization", "P", "int", context__.to_vec());
            P = int(0);
            vals_i__ = context__.vals_i("P");
            pos__ = 0;
            P = vals_i__[pos__++];
            current_statement_begin__ = 8;
            context__.validate_dims("data initialization", "J", "int", context__.to_vec());
            J = int(0);
            vals_i__ = context__.vals_i("J");
            pos__ = 0;
            J = vals_i__[pos__++];
            current_statement_begin__ = 9;
            validate_non_negative_index("donor", "N", N);
            context__.validate_dims("data initialization", "donor", "int", context__.to_vec(N));
            validate_non_negative_index("donor", "N", N);
            donor = std::vector<int>(N,int(0));
            vals_i__ = context__.vals_i("donor");
            pos__ = 0;
            size_t donor_limit_0__ = N;
            for (size_t i_0__ = 0; i_0__ < donor_limit_0__; ++i_0__) {
                donor[i_0__] = vals_i__[pos__++];
            }
            current_statement_begin__ = 10;
            validate_non_negative_index("X", "N", N);
            validate_non_negative_index("X", "P", P);
            context__.validate_dims("data initialization", "X", "row_vector_d", context__.to_vec(N,P));
            validate_non_negative_index("X", "N", N);
            validate_non_negative_index("X", "P", P);
            X = std::vector<row_vector_d>(N,row_vector_d(static_cast<Eigen::VectorXd::Index>(P)));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_i_vec_lim__ = P;
            for (size_t i_vec__ = 0; i_vec__ < X_i_vec_lim__; ++i_vec__) {
                size_t X_limit_0__ = N;
                for (size_t i_0__ = 0; i_0__ < X_limit_0__; ++i_0__) {
                    X[i_0__][i_vec__] = vals_r__[pos__++];
            }
            }
            current_statement_begin__ = 11;
            validate_non_negative_index("treatment", "N", N);
            context__.validate_dims("data initialization", "treatment", "int", context__.to_vec(N));
            validate_non_negative_index("treatment", "N", N);
            treatment = std::vector<int>(N,int(0));
            vals_i__ = context__.vals_i("treatment");
            pos__ = 0;
            size_t treatment_limit_0__ = N;
            for (size_t i_0__ = 0; i_0__ < treatment_limit_0__; ++i_0__) {
                treatment[i_0__] = vals_i__[pos__++];
            }
            current_statement_begin__ = 12;
            context__.validate_dims("data initialization", "eta", "double", context__.to_vec());
            eta = double(0);
            vals_r__ = context__.vals_r("eta");
            pos__ = 0;
            eta = vals_r__[pos__++];

            // validate, data variables
            current_statement_begin__ = 6;
            check_greater_or_equal(function__,"N",N,0);
            current_statement_begin__ = 7;
            check_greater_or_equal(function__,"P",P,1);
            current_statement_begin__ = 8;
            check_greater_or_equal(function__,"J",J,1);
            current_statement_begin__ = 9;
            for (int k0__ = 0; k0__ < N; ++k0__) {
                check_greater_or_equal(function__,"donor[k0__]",donor[k0__],1);
                check_less_or_equal(function__,"donor[k0__]",donor[k0__],J);
            }
            current_statement_begin__ = 10;
            current_statement_begin__ = 11;
            for (int k0__ = 0; k0__ < N; ++k0__) {
                check_greater_or_equal(function__,"treatment[k0__]",treatment[k0__],0);
                check_less_or_equal(function__,"treatment[k0__]",treatment[k0__],1);
            }
            current_statement_begin__ = 12;
            check_greater_or_equal(function__,"eta",eta,0);
            // initialize data variables


            // validate transformed data

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            current_statement_begin__ = 15;
            validate_non_negative_index("beta", "P", P);
            num_params_r__ += P;
            current_statement_begin__ = 16;
            validate_non_negative_index("L_donor", "P", P);
            num_params_r__ += ((P * (P - 1)) / 2);
            current_statement_begin__ = 17;
            validate_non_negative_index("sigma_donor", "P", P);
            num_params_r__ += P;
            current_statement_begin__ = 18;
            validate_non_negative_index("z_donor", "P", P);
            validate_non_negative_index("z_donor", "J", J);
            num_params_r__ += P * J;
        } 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 ***");
        }
    }

    ~model95fa31c99b80_glmm() { }


    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", "P", P);
        context__.validate_dims("initialization", "beta", "vector_d", context__.to_vec(P));
        vector_d beta(static_cast<Eigen::VectorXd::Index>(P));
        for (int j1__ = 0U; j1__ < P; ++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("L_donor")))
            throw std::runtime_error("variable L_donor missing");
        vals_r__ = context__.vals_r("L_donor");
        pos__ = 0U;
        validate_non_negative_index("L_donor", "P", P);
        validate_non_negative_index("L_donor", "P", P);
        context__.validate_dims("initialization", "L_donor", "matrix_d", context__.to_vec(P,P));
        matrix_d L_donor(static_cast<Eigen::VectorXd::Index>(P),static_cast<Eigen::VectorXd::Index>(P));
        for (int j2__ = 0U; j2__ < P; ++j2__)
            for (int j1__ = 0U; j1__ < P; ++j1__)
                L_donor(j1__,j2__) = vals_r__[pos__++];
        try {
            writer__.cholesky_corr_unconstrain(L_donor);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable L_donor: ") + e.what());
        }

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

        if (!(context__.contains_r("z_donor")))
            throw std::runtime_error("variable z_donor missing");
        vals_r__ = context__.vals_r("z_donor");
        pos__ = 0U;
        validate_non_negative_index("z_donor", "J", J);
        validate_non_negative_index("z_donor", "P", P);
        context__.validate_dims("initialization", "z_donor", "vector_d", context__.to_vec(J,P));
        std::vector<vector_d> z_donor(J,vector_d(static_cast<Eigen::VectorXd::Index>(P)));
        for (int j1__ = 0U; j1__ < P; ++j1__)
            for (int i0__ = 0U; i0__ < J; ++i0__)
                z_donor[i0__](j1__) = vals_r__[pos__++];
        for (int i0__ = 0U; i0__ < J; ++i0__)
            try {
            writer__.vector_unconstrain(z_donor[i0__]);
        } catch (const std::exception& e) { 
            throw std::runtime_error(std::string("Error transforming variable z_donor: ") + 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(P,lp__);
            else
                beta = in__.vector_constrain(P);

            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  L_donor;
            (void) L_donor;  // dummy to suppress unused var warning
            if (jacobian__)
                L_donor = in__.cholesky_corr_constrain(P,lp__);
            else
                L_donor = in__.cholesky_corr_constrain(P);

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

            vector<Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1> > z_donor;
            size_t dim_z_donor_0__ = J;
            z_donor.reserve(dim_z_donor_0__);
            for (size_t k_0__ = 0; k_0__ < dim_z_donor_0__; ++k_0__) {
                if (jacobian__)
                    z_donor.push_back(in__.vector_constrain(P,lp__));
                else
                    z_donor.push_back(in__.vector_constrain(P));
            }


            // transformed parameters
            current_statement_begin__ = 21;
            validate_non_negative_index("b_donor", "P", P);
            validate_non_negative_index("b_donor", "J", J);
            vector<Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1> > b_donor(J, (Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1> (static_cast<Eigen::VectorXd::Index>(P))));
            stan::math::initialize(b_donor, DUMMY_VAR__);
            stan::math::fill(b_donor,DUMMY_VAR__);


            {
            current_statement_begin__ = 23;
            validate_non_negative_index("Sigma", "P", P);
            validate_non_negative_index("Sigma", "P", P);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  Sigma(static_cast<Eigen::VectorXd::Index>(P),static_cast<Eigen::VectorXd::Index>(P));
            (void) Sigma;  // dummy to suppress unused var warning

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


            current_statement_begin__ = 24;
            stan::math::assign(Sigma, diag_pre_multiply(sigma_donor,L_donor));
            current_statement_begin__ = 25;
            for (int i = 1; i <= J; ++i) {
                current_statement_begin__ = 26;
                stan::model::assign(b_donor, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            multiply(Sigma,get_base1(z_donor,i,"z_donor",1)), 
                            "assigning variable b_donor");
            }
            }

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

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

            // model body

            current_statement_begin__ = 31;
            lp_accum__.add(normal_log<propto__>(beta, 0, 10));
            current_statement_begin__ = 32;
            lp_accum__.add(lkj_corr_cholesky_log<propto__>(L_donor, eta));
            current_statement_begin__ = 33;
            lp_accum__.add(cauchy_log<propto__>(sigma_donor, 0, 2.5));
            current_statement_begin__ = 34;
            for (int j = 1; j <= J; ++j) {
                current_statement_begin__ = 35;
                lp_accum__.add(normal_log<propto__>(get_base1(z_donor,j,"z_donor",1), 0, 1));
            }
            {
            current_statement_begin__ = 38;
            validate_non_negative_index("x_beta_b_donor", "N", N);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1>  x_beta_b_donor(static_cast<Eigen::VectorXd::Index>(N));
            (void) x_beta_b_donor;  // dummy to suppress unused var warning

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


            current_statement_begin__ = 39;
            for (int i = 1; i <= N; ++i) {
                current_statement_begin__ = 40;
                stan::model::assign(x_beta_b_donor, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            (multiply(get_base1(X,i,"X",1),beta) + multiply(get_base1(X,i,"X",1),get_base1(b_donor,get_base1(donor,i,"donor",1),"b_donor",1))), 
                            "assigning variable x_beta_b_donor");
            }
            current_statement_begin__ = 41;
            lp_accum__.add(bernoulli_logit_log<propto__>(treatment, x_beta_b_donor));
            }

        } 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("L_donor");
        names__.push_back("sigma_donor");
        names__.push_back("z_donor");
        names__.push_back("b_donor");
        names__.push_back("Cor_donor");
    }


    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(P);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(P);
        dims__.push_back(P);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(P);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(J);
        dims__.push_back(P);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(J);
        dims__.push_back(P);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(P);
        dims__.push_back(P);
        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__ = "model95fa31c99b80_glmm_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d beta = in__.vector_constrain(P);
        matrix_d L_donor = in__.cholesky_corr_constrain(P);
        vector_d sigma_donor = in__.vector_lb_constrain(0,P);
        vector<vector_d> z_donor;
        size_t dim_z_donor_0__ = J;
        for (size_t k_0__ = 0; k_0__ < dim_z_donor_0__; ++k_0__) {
            z_donor.push_back(in__.vector_constrain(P));
        }
            for (int k_0__ = 0; k_0__ < P; ++k_0__) {
            vars__.push_back(beta[k_0__]);
            }
            for (int k_1__ = 0; k_1__ < P; ++k_1__) {
                for (int k_0__ = 0; k_0__ < P; ++k_0__) {
                vars__.push_back(L_donor(k_0__, k_1__));
                }
            }
            for (int k_0__ = 0; k_0__ < P; ++k_0__) {
            vars__.push_back(sigma_donor[k_0__]);
            }
            for (int k_1__ = 0; k_1__ < P; ++k_1__) {
                for (int k_0__ = 0; k_0__ < J; ++k_0__) {
                vars__.push_back(z_donor[k_0__][k_1__]);
                }
            }

        // 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 {
            current_statement_begin__ = 21;
            validate_non_negative_index("b_donor", "P", P);
            validate_non_negative_index("b_donor", "J", J);
            vector<Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1> > b_donor(J, (Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,1> (static_cast<Eigen::VectorXd::Index>(P))));
            stan::math::initialize(b_donor, DUMMY_VAR__);
            stan::math::fill(b_donor,DUMMY_VAR__);


            {
            current_statement_begin__ = 23;
            validate_non_negative_index("Sigma", "P", P);
            validate_non_negative_index("Sigma", "P", P);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  Sigma(static_cast<Eigen::VectorXd::Index>(P),static_cast<Eigen::VectorXd::Index>(P));
            (void) Sigma;  // dummy to suppress unused var warning

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


            current_statement_begin__ = 24;
            stan::math::assign(Sigma, diag_pre_multiply(sigma_donor,L_donor));
            current_statement_begin__ = 25;
            for (int i = 1; i <= J; ++i) {
                current_statement_begin__ = 26;
                stan::model::assign(b_donor, 
                            stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list()), 
                            multiply(Sigma,get_base1(z_donor,i,"z_donor",1)), 
                            "assigning variable b_donor");
            }
            }

            // validate transformed parameters
            current_statement_begin__ = 21;

            // write transformed parameters
            if (include_tparams__) {
            for (int k_1__ = 0; k_1__ < P; ++k_1__) {
                for (int k_0__ = 0; k_0__ < J; ++k_0__) {
                vars__.push_back(b_donor[k_0__][k_1__]);
                }
            }
            }
            if (!include_gqs__) return;
            // declare and define generated quantities
            current_statement_begin__ = 46;
            validate_non_negative_index("Cor_donor", "P", P);
            validate_non_negative_index("Cor_donor", "P", P);
            Eigen::Matrix<local_scalar_t__,Eigen::Dynamic,Eigen::Dynamic>  Cor_donor(static_cast<Eigen::VectorXd::Index>(P),static_cast<Eigen::VectorXd::Index>(P));
            (void) Cor_donor;  // dummy to suppress unused var warning

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


            current_statement_begin__ = 47;
            stan::math::assign(Cor_donor, multiply(L_donor,transpose(L_donor)));

            // validate generated quantities
            current_statement_begin__ = 46;

            // write generated quantities
            for (int k_1__ = 0; k_1__ < P; ++k_1__) {
                for (int k_0__ = 0; k_0__ < P; ++k_0__) {
                vars__.push_back(Cor_donor(k_0__, k_1__));
                }
            }

        } 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 "model95fa31c99b80_glmm";
    }


    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__ <= P; ++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_1__ = 1; k_1__ <= P; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= P; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "L_donor" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }
        for (int k_0__ = 1; k_0__ <= P; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "sigma_donor" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_1__ = 1; k_1__ <= P; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= J; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "z_donor" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_1__ = 1; k_1__ <= P; ++k_1__) {
                for (int k_0__ = 1; k_0__ <= J; ++k_0__) {
                    param_name_stream__.str(std::string());
                    param_name_stream__ << "b_donor" << '.' << k_0__ << '.' << k_1__;
                    param_names__.push_back(param_name_stream__.str());
                }
            }
        }


        if (!include_gqs__) return;
        for (int k_1__ = 1; k_1__ <= P; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= P; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "Cor_donor" << '.' << k_0__ << '.' << k_1__;
                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__ <= P; ++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__ <= ((P * (P - 1)) / 2); ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "L_donor" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= P; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "sigma_donor" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_1__ = 1; k_1__ <= P; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= J; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "z_donor" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }

        if (!include_gqs__ && !include_tparams__) return;

        if (include_tparams__) {
            for (int k_1__ = 1; k_1__ <= P; ++k_1__) {
                for (int k_0__ = 1; k_0__ <= J; ++k_0__) {
                    param_name_stream__.str(std::string());
                    param_name_stream__ << "b_donor" << '.' << k_0__ << '.' << k_1__;
                    param_names__.push_back(param_name_stream__.str());
                }
            }
        }


        if (!include_gqs__) return;
        for (int k_1__ = 1; k_1__ <= P; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= P; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "Cor_donor" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }
    }

}; // model

}

typedef model95fa31c99b80_glmm_namespace::model95fa31c99b80_glmm stan_model;