// Code generated by Stan version 2.17.0

#include <stan/model/model_header.hpp>

namespace model548e263d19c0_file548ebf7811b_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;

typedef Eigen::Matrix<double,Eigen::Dynamic,1> vector_d;
typedef Eigen::Matrix<double,1,Eigen::Dynamic> row_vector_d;
typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> matrix_d;

static int current_statement_begin__;

stan::io::program_reader prog_reader__() {
    stan::io::program_reader reader;
    reader.add_event(0, 0, "start", "model548e263d19c0_file548ebf7811b");
    reader.add_event(66, 66, "end", "model548e263d19c0_file548ebf7811b");
    return reader;
}

class model548e263d19c0_file548ebf7811b : public prob_grad {
private:
    int N;
    vector<int> Y;
    int K;
    matrix_d X;
    vector<int> J_1;
    int N_1;
    int M_1;
    vector_d Z_1_1;
    vector<int> J_2;
    int N_2;
    int M_2;
    vector_d Z_2_1;
    int prior_only;
    int Kc;
    matrix_d Xc;
    vector_d means_X;
public:
    model548e263d19c0_file548ebf7811b(stan::io::var_context& context__,
        std::ostream* pstream__ = 0)
        : prob_grad(0) {
        ctor_body(context__, 0, pstream__);
    }

    model548e263d19c0_file548ebf7811b(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__) {
        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__ = "model548e263d19c0_file548ebf7811b_namespace::model548e263d19c0_file548ebf7811b";
        (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__;
        double DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
        (void) DUMMY_VAR__;  // suppress unused var warning

        // initialize member variables
        try {
            current_statement_begin__ = 5;
            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__ = 6;
            validate_non_negative_index("Y", "N", N);
            context__.validate_dims("data initialization", "Y", "int", context__.to_vec(N));
            validate_non_negative_index("Y", "N", N);
            Y = std::vector<int>(N,int(0));
            vals_i__ = context__.vals_i("Y");
            pos__ = 0;
            size_t Y_limit_0__ = N;
            for (size_t i_0__ = 0; i_0__ < Y_limit_0__; ++i_0__) {
                Y[i_0__] = vals_i__[pos__++];
            }
            current_statement_begin__ = 7;
            context__.validate_dims("data initialization", "K", "int", context__.to_vec());
            K = int(0);
            vals_i__ = context__.vals_i("K");
            pos__ = 0;
            K = vals_i__[pos__++];
            current_statement_begin__ = 8;
            validate_non_negative_index("X", "N", N);
            validate_non_negative_index("X", "K", K);
            context__.validate_dims("data initialization", "X", "matrix_d", context__.to_vec(N,K));
            validate_non_negative_index("X", "N", N);
            validate_non_negative_index("X", "K", K);
            X = matrix_d(static_cast<Eigen::VectorXd::Index>(N),static_cast<Eigen::VectorXd::Index>(K));
            vals_r__ = context__.vals_r("X");
            pos__ = 0;
            size_t X_m_mat_lim__ = N;
            size_t X_n_mat_lim__ = K;
            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__++];
                }
            }
            current_statement_begin__ = 10;
            validate_non_negative_index("J_1", "N", N);
            context__.validate_dims("data initialization", "J_1", "int", context__.to_vec(N));
            validate_non_negative_index("J_1", "N", N);
            J_1 = std::vector<int>(N,int(0));
            vals_i__ = context__.vals_i("J_1");
            pos__ = 0;
            size_t J_1_limit_0__ = N;
            for (size_t i_0__ = 0; i_0__ < J_1_limit_0__; ++i_0__) {
                J_1[i_0__] = vals_i__[pos__++];
            }
            current_statement_begin__ = 11;
            context__.validate_dims("data initialization", "N_1", "int", context__.to_vec());
            N_1 = int(0);
            vals_i__ = context__.vals_i("N_1");
            pos__ = 0;
            N_1 = vals_i__[pos__++];
            current_statement_begin__ = 12;
            context__.validate_dims("data initialization", "M_1", "int", context__.to_vec());
            M_1 = int(0);
            vals_i__ = context__.vals_i("M_1");
            pos__ = 0;
            M_1 = vals_i__[pos__++];
            current_statement_begin__ = 13;
            validate_non_negative_index("Z_1_1", "N", N);
            context__.validate_dims("data initialization", "Z_1_1", "vector_d", context__.to_vec(N));
            validate_non_negative_index("Z_1_1", "N", N);
            Z_1_1 = vector_d(static_cast<Eigen::VectorXd::Index>(N));
            vals_r__ = context__.vals_r("Z_1_1");
            pos__ = 0;
            size_t Z_1_1_i_vec_lim__ = N;
            for (size_t i_vec__ = 0; i_vec__ < Z_1_1_i_vec_lim__; ++i_vec__) {
                Z_1_1[i_vec__] = vals_r__[pos__++];
            }
            current_statement_begin__ = 15;
            validate_non_negative_index("J_2", "N", N);
            context__.validate_dims("data initialization", "J_2", "int", context__.to_vec(N));
            validate_non_negative_index("J_2", "N", N);
            J_2 = std::vector<int>(N,int(0));
            vals_i__ = context__.vals_i("J_2");
            pos__ = 0;
            size_t J_2_limit_0__ = N;
            for (size_t i_0__ = 0; i_0__ < J_2_limit_0__; ++i_0__) {
                J_2[i_0__] = vals_i__[pos__++];
            }
            current_statement_begin__ = 16;
            context__.validate_dims("data initialization", "N_2", "int", context__.to_vec());
            N_2 = int(0);
            vals_i__ = context__.vals_i("N_2");
            pos__ = 0;
            N_2 = vals_i__[pos__++];
            current_statement_begin__ = 17;
            context__.validate_dims("data initialization", "M_2", "int", context__.to_vec());
            M_2 = int(0);
            vals_i__ = context__.vals_i("M_2");
            pos__ = 0;
            M_2 = vals_i__[pos__++];
            current_statement_begin__ = 18;
            validate_non_negative_index("Z_2_1", "N", N);
            context__.validate_dims("data initialization", "Z_2_1", "vector_d", context__.to_vec(N));
            validate_non_negative_index("Z_2_1", "N", N);
            Z_2_1 = vector_d(static_cast<Eigen::VectorXd::Index>(N));
            vals_r__ = context__.vals_r("Z_2_1");
            pos__ = 0;
            size_t Z_2_1_i_vec_lim__ = N;
            for (size_t i_vec__ = 0; i_vec__ < Z_2_1_i_vec_lim__; ++i_vec__) {
                Z_2_1[i_vec__] = vals_r__[pos__++];
            }
            current_statement_begin__ = 19;
            context__.validate_dims("data initialization", "prior_only", "int", context__.to_vec());
            prior_only = int(0);
            vals_i__ = context__.vals_i("prior_only");
            pos__ = 0;
            prior_only = vals_i__[pos__++];

            // validate, data variables
            current_statement_begin__ = 5;
            check_greater_or_equal(function__,"N",N,1);
            current_statement_begin__ = 6;
            current_statement_begin__ = 7;
            check_greater_or_equal(function__,"K",K,1);
            current_statement_begin__ = 8;
            current_statement_begin__ = 10;
            for (int k0__ = 0; k0__ < N; ++k0__) {
                check_greater_or_equal(function__,"J_1[k0__]",J_1[k0__],1);
            }
            current_statement_begin__ = 11;
            check_greater_or_equal(function__,"N_1",N_1,1);
            current_statement_begin__ = 12;
            check_greater_or_equal(function__,"M_1",M_1,1);
            current_statement_begin__ = 13;
            current_statement_begin__ = 15;
            for (int k0__ = 0; k0__ < N; ++k0__) {
                check_greater_or_equal(function__,"J_2[k0__]",J_2[k0__],1);
            }
            current_statement_begin__ = 16;
            check_greater_or_equal(function__,"N_2",N_2,1);
            current_statement_begin__ = 17;
            check_greater_or_equal(function__,"M_2",M_2,1);
            current_statement_begin__ = 18;
            current_statement_begin__ = 19;
            // initialize data variables
            current_statement_begin__ = 22;
            Kc = int(0);
            stan::math::fill(Kc, std::numeric_limits<int>::min());
            stan::math::assign(Kc,(K - 1));
            current_statement_begin__ = 23;
            validate_non_negative_index("Xc", "N", N);
            validate_non_negative_index("Xc", "(K - 1)", (K - 1));
            Xc = matrix_d(static_cast<Eigen::VectorXd::Index>(N),static_cast<Eigen::VectorXd::Index>((K - 1)));
            stan::math::fill(Xc,DUMMY_VAR__);
            current_statement_begin__ = 24;
            validate_non_negative_index("means_X", "(K - 1)", (K - 1));
            means_X = vector_d(static_cast<Eigen::VectorXd::Index>((K - 1)));
            stan::math::fill(means_X,DUMMY_VAR__);

            current_statement_begin__ = 25;
            for (int i = 2; i <= K; ++i) {

                current_statement_begin__ = 26;
                stan::math::assign(get_base1_lhs(means_X,(i - 1),"means_X",1), mean(stan::model::rvalue(X, stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list())), "X")));
                current_statement_begin__ = 27;
                stan::model::assign(Xc, 
                            stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_uni((i - 1)), stan::model::nil_index_list())), 
                            subtract(stan::model::rvalue(X, stan::model::cons_list(stan::model::index_omni(), stan::model::cons_list(stan::model::index_uni(i), stan::model::nil_index_list())), "X"),get_base1(means_X,(i - 1),"means_X",1)), 
                            "assigning variable Xc");
            }

            // validate transformed data
            current_statement_begin__ = 22;
            current_statement_begin__ = 23;
            current_statement_begin__ = 24;

            // validate, set parameter ranges
            num_params_r__ = 0U;
            param_ranges_i__.clear();
            current_statement_begin__ = 31;
            validate_non_negative_index("b", "Kc", Kc);
            num_params_r__ += Kc;
            current_statement_begin__ = 32;
            ++num_params_r__;
            current_statement_begin__ = 33;
            validate_non_negative_index("sd_1", "M_1", M_1);
            num_params_r__ += M_1;
            current_statement_begin__ = 34;
            validate_non_negative_index("z_1", "N_1", N_1);
            validate_non_negative_index("z_1", "M_1", M_1);
            num_params_r__ += N_1 * M_1;
            current_statement_begin__ = 35;
            validate_non_negative_index("sd_2", "M_2", M_2);
            num_params_r__ += M_2;
            current_statement_begin__ = 36;
            validate_non_negative_index("z_2", "N_2", N_2);
            validate_non_negative_index("z_2", "M_2", M_2);
            num_params_r__ += N_2 * M_2;
        } 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 ***");
        }
    }

    ~model548e263d19c0_file548ebf7811b() { }


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

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

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

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

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

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

        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<T__> in__(params_r__,params_i__);

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

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

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

            vector<Eigen::Matrix<T__,Eigen::Dynamic,1> > z_1;
            size_t dim_z_1_0__ = M_1;
            z_1.reserve(dim_z_1_0__);
            for (size_t k_0__ = 0; k_0__ < dim_z_1_0__; ++k_0__) {
                if (jacobian__)
                    z_1.push_back(in__.vector_constrain(N_1,lp__));
                else
                    z_1.push_back(in__.vector_constrain(N_1));
            }

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

            vector<Eigen::Matrix<T__,Eigen::Dynamic,1> > z_2;
            size_t dim_z_2_0__ = M_2;
            z_2.reserve(dim_z_2_0__);
            for (size_t k_0__ = 0; k_0__ < dim_z_2_0__; ++k_0__) {
                if (jacobian__)
                    z_2.push_back(in__.vector_constrain(N_2,lp__));
                else
                    z_2.push_back(in__.vector_constrain(N_2));
            }


            // transformed parameters
            current_statement_begin__ = 40;
            validate_non_negative_index("r_1_1", "N_1", N_1);
            Eigen::Matrix<T__,Eigen::Dynamic,1>  r_1_1(static_cast<Eigen::VectorXd::Index>(N_1));
            (void) r_1_1;  // dummy to suppress unused var warning

            stan::math::initialize(r_1_1, DUMMY_VAR__);
            stan::math::fill(r_1_1,DUMMY_VAR__);
            stan::math::assign(r_1_1,multiply(get_base1(sd_1,1,"sd_1",1),get_base1(z_1,1,"z_1",1)));
            current_statement_begin__ = 42;
            validate_non_negative_index("r_2_1", "N_2", N_2);
            Eigen::Matrix<T__,Eigen::Dynamic,1>  r_2_1(static_cast<Eigen::VectorXd::Index>(N_2));
            (void) r_2_1;  // dummy to suppress unused var warning

            stan::math::initialize(r_2_1, DUMMY_VAR__);
            stan::math::fill(r_2_1,DUMMY_VAR__);
            stan::math::assign(r_2_1,multiply(get_base1(sd_2,1,"sd_2",1),get_base1(z_2,1,"z_2",1)));



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

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

            // model body
            {
            current_statement_begin__ = 45;
            validate_non_negative_index("mu", "N", N);
            Eigen::Matrix<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(mu,add(multiply(Xc,b),temp_Intercept));


            current_statement_begin__ = 46;
            for (int n = 1; n <= N; ++n) {

                current_statement_begin__ = 47;
                stan::math::assign(get_base1_lhs(mu,n,"mu",1), (get_base1(mu,n,"mu",1) + ((get_base1(r_1_1,get_base1(J_1,n,"J_1",1),"r_1_1",1) * get_base1(Z_1_1,n,"Z_1_1",1)) + (get_base1(r_2_1,get_base1(J_2,n,"J_2",1),"r_2_1",1) * get_base1(Z_2_1,n,"Z_2_1",1)))));
            }
            current_statement_begin__ = 50;
            lp_accum__.add(student_t_log(b,5,0,10));
            current_statement_begin__ = 51;
            lp_accum__.add(student_t_log(temp_Intercept,3,1,10));
            current_statement_begin__ = 52;
            lp_accum__.add((cauchy_log(sd_1,0,2) - (1 * cauchy_ccdf_log(0,0,2))));
            current_statement_begin__ = 54;
            lp_accum__.add(normal_log(get_base1(z_1,1,"z_1",1),0,1));
            current_statement_begin__ = 55;
            lp_accum__.add((cauchy_log(sd_2,0,2) - (1 * cauchy_ccdf_log(0,0,2))));
            current_statement_begin__ = 57;
            lp_accum__.add(normal_log(get_base1(z_2,1,"z_2",1),0,1));
            current_statement_begin__ = 59;
            if (as_bool(logical_negation(prior_only))) {

                current_statement_begin__ = 60;
                lp_accum__.add(poisson_log_log(Y,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 ***");
        }

        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("b");
        names__.push_back("temp_Intercept");
        names__.push_back("sd_1");
        names__.push_back("z_1");
        names__.push_back("sd_2");
        names__.push_back("z_2");
        names__.push_back("r_1_1");
        names__.push_back("r_2_1");
        names__.push_back("b_Intercept");
    }


    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(Kc);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(M_1);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(M_1);
        dims__.push_back(N_1);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(M_2);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(M_2);
        dims__.push_back(N_2);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(N_1);
        dimss__.push_back(dims__);
        dims__.resize(0);
        dims__.push_back(N_2);
        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 {
        vars__.resize(0);
        stan::io::reader<double> in__(params_r__,params_i__);
        static const char* function__ = "model548e263d19c0_file548ebf7811b_namespace::write_array";
        (void) function__;  // dummy to suppress unused var warning
        // read-transform, write parameters
        vector_d b = in__.vector_constrain(Kc);
        double temp_Intercept = in__.scalar_constrain();
        vector_d sd_1 = in__.vector_lb_constrain(0,M_1);
        vector<vector_d> z_1;
        size_t dim_z_1_0__ = M_1;
        for (size_t k_0__ = 0; k_0__ < dim_z_1_0__; ++k_0__) {
            z_1.push_back(in__.vector_constrain(N_1));
        }
        vector_d sd_2 = in__.vector_lb_constrain(0,M_2);
        vector<vector_d> z_2;
        size_t dim_z_2_0__ = M_2;
        for (size_t k_0__ = 0; k_0__ < dim_z_2_0__; ++k_0__) {
            z_2.push_back(in__.vector_constrain(N_2));
        }
            for (int k_0__ = 0; k_0__ < Kc; ++k_0__) {
            vars__.push_back(b[k_0__]);
            }
        vars__.push_back(temp_Intercept);
            for (int k_0__ = 0; k_0__ < M_1; ++k_0__) {
            vars__.push_back(sd_1[k_0__]);
            }
            for (int k_1__ = 0; k_1__ < N_1; ++k_1__) {
                for (int k_0__ = 0; k_0__ < M_1; ++k_0__) {
                vars__.push_back(z_1[k_0__][k_1__]);
                }
            }
            for (int k_0__ = 0; k_0__ < M_2; ++k_0__) {
            vars__.push_back(sd_2[k_0__]);
            }
            for (int k_1__ = 0; k_1__ < N_2; ++k_1__) {
                for (int k_0__ = 0; k_0__ < M_2; ++k_0__) {
                vars__.push_back(z_2[k_0__][k_1__]);
                }
            }

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

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

        try {
            current_statement_begin__ = 40;
            validate_non_negative_index("r_1_1", "N_1", N_1);
            vector_d r_1_1(static_cast<Eigen::VectorXd::Index>(N_1));
            (void) r_1_1;  // dummy to suppress unused var warning

            stan::math::initialize(r_1_1, std::numeric_limits<double>::quiet_NaN());
            stan::math::fill(r_1_1,DUMMY_VAR__);
            stan::math::assign(r_1_1,multiply(get_base1(sd_1,1,"sd_1",1),get_base1(z_1,1,"z_1",1)));
            current_statement_begin__ = 42;
            validate_non_negative_index("r_2_1", "N_2", N_2);
            vector_d r_2_1(static_cast<Eigen::VectorXd::Index>(N_2));
            (void) r_2_1;  // dummy to suppress unused var warning

            stan::math::initialize(r_2_1, std::numeric_limits<double>::quiet_NaN());
            stan::math::fill(r_2_1,DUMMY_VAR__);
            stan::math::assign(r_2_1,multiply(get_base1(sd_2,1,"sd_2",1),get_base1(z_2,1,"z_2",1)));



            // validate transformed parameters
            current_statement_begin__ = 40;
            current_statement_begin__ = 42;

            // write transformed parameters
            for (int k_0__ = 0; k_0__ < N_1; ++k_0__) {
            vars__.push_back(r_1_1[k_0__]);
            }
            for (int k_0__ = 0; k_0__ < N_2; ++k_0__) {
            vars__.push_back(r_2_1[k_0__]);
            }

            if (!include_gqs__) return;
            // declare and define generated quantities
            current_statement_begin__ = 65;
            double b_Intercept(0.0);
            (void) b_Intercept;  // dummy to suppress unused var warning

            stan::math::initialize(b_Intercept, std::numeric_limits<double>::quiet_NaN());
            stan::math::fill(b_Intercept,DUMMY_VAR__);
            stan::math::assign(b_Intercept,(temp_Intercept - dot_product(means_X,b)));



            // validate generated quantities
            current_statement_begin__ = 65;

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

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


    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__ <= Kc; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "b" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "temp_Intercept";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= M_1; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "sd_1" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_1__ = 1; k_1__ <= N_1; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= M_1; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "z_1" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }
        for (int k_0__ = 1; k_0__ <= M_2; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "sd_2" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_1__ = 1; k_1__ <= N_2; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= M_2; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "z_2" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }

        if (!include_gqs__ && !include_tparams__) return;
        for (int k_0__ = 1; k_0__ <= N_1; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "r_1_1" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= N_2; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "r_2_1" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

        if (!include_gqs__) return;
        param_name_stream__.str(std::string());
        param_name_stream__ << "b_Intercept";
        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__ <= Kc; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "b" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        param_name_stream__.str(std::string());
        param_name_stream__ << "temp_Intercept";
        param_names__.push_back(param_name_stream__.str());
        for (int k_0__ = 1; k_0__ <= M_1; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "sd_1" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_1__ = 1; k_1__ <= N_1; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= M_1; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "z_1" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }
        for (int k_0__ = 1; k_0__ <= M_2; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "sd_2" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_1__ = 1; k_1__ <= N_2; ++k_1__) {
            for (int k_0__ = 1; k_0__ <= M_2; ++k_0__) {
                param_name_stream__.str(std::string());
                param_name_stream__ << "z_2" << '.' << k_0__ << '.' << k_1__;
                param_names__.push_back(param_name_stream__.str());
            }
        }

        if (!include_gqs__ && !include_tparams__) return;
        for (int k_0__ = 1; k_0__ <= N_1; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "r_1_1" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }
        for (int k_0__ = 1; k_0__ <= N_2; ++k_0__) {
            param_name_stream__.str(std::string());
            param_name_stream__ << "r_2_1" << '.' << k_0__;
            param_names__.push_back(param_name_stream__.str());
        }

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

}; // model

}

typedef model548e263d19c0_file548ebf7811b_namespace::model548e263d19c0_file548ebf7811b stan_model;