// Generated by rstantools.  Do not edit by hand.

/*
    ForceChoice is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ForceChoice is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ForceChoice.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MODELS_HPP
#define MODELS_HPP
#define STAN__SERVICES__COMMAND_HPP
#ifndef USE_STANC3
#define USE_STANC3
#endif
#include <rstan/rstaninc.hpp>
// Code generated by stanc v2.32.2
#include <stan/model/model_header.hpp>
namespace model_FCDCM_namespace {
using stan::model::model_base_crtp;
using namespace stan::math;
stan::math::profile_map profiles__;
static constexpr std::array<const char*, 154> locations_array__ =
  {" (found before start of program)",
  " (in 'string', line 105, column 2 to column 18)",
  " (in 'string', line 106, column 2 to column 28)",
  " (in 'string', line 107, column 2 to column 19)",
  " (in 'string', line 108, column 2 to column 37)",
  " (in 'string', line 109, column 2 to column 38)",
  " (in 'string', line 130, column 2 to column 20)",
  " (in 'string', line 132, column 11 to column 12)",
  " (in 'string', line 132, column 14 to column 15)",
  " (in 'string', line 132, column 4 to line 134, column 72)",
  " (in 'string', line 136, column 13 to column 14)",
  " (in 'string', line 136, column 6 to column 67)",
  " (in 'string', line 137, column 13 to column 14)",
  " (in 'string', line 137, column 6 to column 49)",
  " (in 'string', line 138, column 13 to column 14)",
  " (in 'string', line 138, column 6 to column 53)",
  " (in 'string', line 139, column 13 to column 14)",
  " (in 'string', line 139, column 6 to line 140, column 41)",
  " (in 'string', line 141, column 6 to column 68)",
  " (in 'string', line 135, column 19 to line 142, column 5)",
  " (in 'string', line 135, column 4 to line 142, column 5)",
  " (in 'string', line 131, column 2 to line 143, column 3)",
  " (in 'string', line 112, column 9 to column 10)",
  " (in 'string', line 112, column 12 to column 13)",
  " (in 'string', line 112, column 2 to line 114, column 70)",
  " (in 'string', line 115, column 2 to column 23)",
  " (in 'string', line 116, column 2 to column 46)",
  " (in 'string', line 117, column 2 to column 43)",
  " (in 'string', line 118, column 2 to column 37)",
  " (in 'string', line 119, column 2 to column 40)",
  " (in 'string', line 121, column 11 to column 12)",
  " (in 'string', line 121, column 4 to column 65)",
  " (in 'string', line 122, column 11 to column 12)",
  " (in 'string', line 122, column 4 to column 47)",
  " (in 'string', line 123, column 11 to column 12)",
  " (in 'string', line 123, column 4 to column 51)",
  " (in 'string', line 124, column 11 to column 12)",
  " (in 'string', line 124, column 4 to line 125, column 39)",
  " (in 'string', line 126, column 4 to column 63)",
  " (in 'string', line 120, column 17 to line 127, column 3)",
  " (in 'string', line 120, column 2 to line 127, column 3)",
  " (in 'string', line 58, column 2 to column 17)",
  " (in 'string', line 59, column 2 to column 17)",
  " (in 'string', line 60, column 2 to column 17)",
  " (in 'string', line 61, column 2 to column 17)",
  " (in 'string', line 62, column 2 to column 17)",
  " (in 'string', line 63, column 8 to column 13)",
  " (in 'string', line 63, column 2 to column 39)",
  " (in 'string', line 64, column 8 to column 13)",
  " (in 'string', line 64, column 2 to column 52)",
  " (in 'string', line 65, column 8 to column 13)",
  " (in 'string', line 65, column 2 to column 51)",
  " (in 'string', line 66, column 8 to column 13)",
  " (in 'string', line 66, column 2 to column 46)",
  " (in 'string', line 67, column 2 to column 17)",
  " (in 'string', line 68, column 2 to column 29)",
  " (in 'string', line 69, column 2 to column 17)",
  " (in 'string', line 70, column 2 to column 29)",
  " (in 'string', line 71, column 2 to column 24)",
  " (in 'string', line 72, column 2 to column 27)",
  " (in 'string', line 73, column 2 to column 25)",
  " (in 'string', line 74, column 2 to column 28)",
  " (in 'string', line 77, column 8 to column 13)",
  " (in 'string', line 77, column 2 to column 48)",
  " (in 'string', line 78, column 9 to column 10)",
  " (in 'string', line 78, column 12 to column 13)",
  " (in 'string', line 78, column 2 to column 28)",
  " (in 'string', line 79, column 9 to column 10)",
  " (in 'string', line 79, column 12 to column 13)",
  " (in 'string', line 79, column 2 to column 31)",
  " (in 'string', line 81, column 4 to column 37)",
  " (in 'string', line 82, column 4 to column 37)",
  " (in 'string', line 84, column 6 to column 63)",
  " (in 'string', line 85, column 6 to column 57)",
  " (in 'string', line 83, column 19 to line 86, column 5)",
  " (in 'string', line 83, column 4 to line 86, column 5)",
  " (in 'string', line 88, column 6 to column 45)",
  " (in 'string', line 89, column 6 to column 45)",
  " (in 'string', line 90, column 6 to column 56)",
  " (in 'string', line 91, column 6 to column 56)",
  " (in 'string', line 99, column 8 to column 41)",
  " (in 'string', line 98, column 13 to line 100, column 7)",
  " (in 'string', line 97, column 8 to column 41)",
  " (in 'string', line 96, column 30 to line 98, column 7)",
  " (in 'string', line 96, column 13 to line 100, column 7)",
  " (in 'string', line 95, column 8 to column 41)",
  " (in 'string', line 94, column 34 to line 96, column 7)",
  " (in 'string', line 94, column 13 to line 100, column 7)",
  " (in 'string', line 93, column 8 to column 41)",
  " (in 'string', line 92, column 27 to line 94, column 7)",
  " (in 'string', line 92, column 6 to line 100, column 7)",
  " (in 'string', line 87, column 19 to line 101, column 5)",
  " (in 'string', line 87, column 4 to line 101, column 5)",
  " (in 'string', line 80, column 19 to line 102, column 3)",
  " (in 'string', line 80, column 2 to line 102, column 3)",
  " (in 'string', line 105, column 9 to column 10)",
  " (in 'string', line 106, column 18 to column 19)",
  " (in 'string', line 107, column 9 to column 10)",
  " (in 'string', line 108, column 29 to column 30)",
  " (in 'string', line 109, column 29 to column 30)",
  " (in 'string', line 130, column 9 to column 10)",
  " (in 'string', line 7, column 11 to column 12)",
  " (in 'string', line 7, column 14 to column 15)",
  " (in 'string', line 7, column 4 to column 49)",
  " (in 'string', line 8, column 11 to column 12)",
  " (in 'string', line 8, column 4 to column 23)",
  " (in 'string', line 9, column 11 to column 12)",
  " (in 'string', line 9, column 4 to column 27)",
  " (in 'string', line 10, column 11 to column 12)",
  " (in 'string', line 10, column 4 to column 27)",
  " (in 'string', line 11, column 11 to column 12)",
  " (in 'string', line 11, column 4 to column 31)",
  " (in 'string', line 12, column 4 to column 29)",
  " (in 'string', line 14, column 6 to column 63)",
  " (in 'string', line 15, column 6 to column 74)",
  " (in 'string', line 16, column 6 to column 35)",
  " (in 'string', line 17, column 6 to column 43)",
  " (in 'string', line 18, column 6 to column 41)",
  " (in 'string', line 19, column 6 to column 49)",
  " (in 'string', line 13, column 19 to line 20, column 5)",
  " (in 'string', line 13, column 4 to line 20, column 5)",
  " (in 'string', line 22, column 6 to column 39)",
  " (in 'string', line 24, column 8 to column 51)",
  " (in 'string', line 25, column 8 to column 35)",
  " (in 'string', line 26, column 8 to column 24)",
  " (in 'string', line 27, column 8 to column 24)",
  " (in 'string', line 42, column 10 to column 32)",
  " (in 'string', line 43, column 10 to column 32)",
  " (in 'string', line 40, column 15 to line 44, column 9)",
  " (in 'string', line 38, column 10 to column 43)",
  " (in 'string', line 39, column 10 to column 39)",
  " (in 'string', line 36, column 33 to line 40, column 9)",
  " (in 'string', line 36, column 15 to line 44, column 9)",
  " (in 'string', line 34, column 10 to column 32)",
  " (in 'string', line 35, column 10 to column 32)",
  " (in 'string', line 32, column 33 to line 36, column 9)",
  " (in 'string', line 32, column 15 to line 44, column 9)",
  " (in 'string', line 30, column 10 to column 39)",
  " (in 'string', line 31, column 10 to column 35)",
  " (in 'string', line 28, column 26 to line 32, column 9)",
  " (in 'string', line 28, column 8 to line 44, column 9)",
  " (in 'string', line 49, column 12 to column 42)",
  " (in 'string', line 48, column 17 to line 50, column 11)",
  " (in 'string', line 47, column 12 to column 42)",
  " (in 'string', line 46, column 36 to line 48, column 11)",
  " (in 'string', line 46, column 10 to line 50, column 11)",
  " (in 'string', line 45, column 23 to line 51, column 9)",
  " (in 'string', line 45, column 8 to line 51, column 9)",
  " (in 'string', line 23, column 21 to line 52, column 7)",
  " (in 'string', line 23, column 6 to line 52, column 7)",
  " (in 'string', line 21, column 21 to line 53, column 5)",
  " (in 'string', line 21, column 4 to line 53, column 5)",
  " (in 'string', line 54, column 4 to column 19)",
  " (in 'string', line 6, column 74 to line 55, column 3)"};
template <typename T5__, typename T6__,
          stan::require_all_t<stan::is_col_vector<T5__>,
                              stan::is_vt_not_complex<T5__>,
                              stan::is_col_vector<T6__>,
                              stan::is_vt_not_complex<T6__>>* = nullptr>
Eigen::Matrix<stan::promote_args_t<stan::base_type_t<T5__>,
                stan::base_type_t<T6__>>,-1,-1>
fcdcm_response_logprob(const int& C, const int& N, const int& B,
                       const std::vector<int>& block_case,
                       const std::vector<int>& y, const T5__& eta0_arg__,
                       const T6__& etaAB_arg__, std::ostream* pstream__);
template <typename T5__, typename T6__,
          stan::require_all_t<stan::is_col_vector<T5__>,
                              stan::is_vt_not_complex<T5__>,
                              stan::is_col_vector<T6__>,
                              stan::is_vt_not_complex<T6__>>*>
Eigen::Matrix<stan::promote_args_t<stan::base_type_t<T5__>,
                stan::base_type_t<T6__>>,-1,-1>
fcdcm_response_logprob(const int& C, const int& N, const int& B,
                       const std::vector<int>& block_case,
                       const std::vector<int>& y, const T5__& eta0_arg__,
                       const T6__& etaAB_arg__, std::ostream* pstream__) {
  using local_scalar_t__ = stan::promote_args_t<stan::base_type_t<T5__>,
                             stan::base_type_t<T6__>>;
  int current_statement__ = 0;
  const auto& eta0 = stan::math::to_ref(eta0_arg__);
  const auto& etaAB = stan::math::to_ref(etaAB_arg__);
  static constexpr bool propto__ = true;
  // suppress unused var warning
  (void) propto__;
  local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
  // suppress unused var warning
  (void) DUMMY_VAR__;
  try {
    current_statement__ = 101;
    stan::math::validate_non_negative_index("logprob", "C", C);
    current_statement__ = 102;
    stan::math::validate_non_negative_index("logprob", "N", N);
    Eigen::Matrix<local_scalar_t__,-1,-1> logprob =
      Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(C, N, DUMMY_VAR__);
    current_statement__ = 103;
    stan::model::assign(logprob, stan::math::rep_matrix(0.0, C, N),
      "assigning variable logprob");
    current_statement__ = 104;
    stan::math::validate_non_negative_index("log_eta0", "B", B);
    Eigen::Matrix<local_scalar_t__,-1,1> log_eta0 =
      Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
    current_statement__ = 106;
    stan::math::validate_non_negative_index("log_eta_high", "B", B);
    Eigen::Matrix<local_scalar_t__,-1,1> log_eta_high =
      Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
    current_statement__ = 108;
    stan::math::validate_non_negative_index("log_not_eta0", "B", B);
    Eigen::Matrix<local_scalar_t__,-1,1> log_not_eta0 =
      Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
    current_statement__ = 110;
    stan::math::validate_non_negative_index("log_not_eta_high", "B", B);
    Eigen::Matrix<local_scalar_t__,-1,1> log_not_eta_high =
      Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
    local_scalar_t__ log_half = DUMMY_VAR__;
    current_statement__ = 112;
    log_half = stan::math::log(0.5);
    current_statement__ = 120;
    for (int b = 1; b <= B; ++b) {
      local_scalar_t__ eta0_safe = DUMMY_VAR__;
      current_statement__ = 113;
      eta0_safe = stan::math::fmin((0.5 - 1e-12),
                    stan::math::fmax(1e-12,
                      stan::model::rvalue(eta0, "eta0",
                        stan::model::index_uni(b))));
      local_scalar_t__ eta_high_safe = DUMMY_VAR__;
      current_statement__ = 114;
      eta_high_safe = stan::math::fmin((1.0 - 1e-12),
                        stan::math::fmax(1e-12, (0.5 +
                          stan::model::rvalue(etaAB, "etaAB",
                            stan::model::index_uni(b)))));
      current_statement__ = 115;
      stan::model::assign(log_eta0, stan::math::log(eta0_safe),
        "assigning variable log_eta0", stan::model::index_uni(b));
      current_statement__ = 116;
      stan::model::assign(log_eta_high, stan::math::log(eta_high_safe),
        "assigning variable log_eta_high", stan::model::index_uni(b));
      current_statement__ = 117;
      stan::model::assign(log_not_eta0, stan::math::log1m(eta0_safe),
        "assigning variable log_not_eta0", stan::model::index_uni(b));
      current_statement__ = 118;
      stan::model::assign(log_not_eta_high, stan::math::log1m(eta_high_safe),
        "assigning variable log_not_eta_high", stan::model::index_uni(b));
    }
    current_statement__ = 151;
    for (int cls = 1; cls <= C; ++cls) {
      int class_offset = std::numeric_limits<int>::min();
      current_statement__ = 121;
      class_offset = ((cls - 1) * B);
      current_statement__ = 149;
      for (int b = 1; b <= B; ++b) {
        int case_id = std::numeric_limits<int>::min();
        current_statement__ = 122;
        case_id = stan::model::rvalue(block_case, "block_case",
                    stan::model::index_uni((class_offset + b)));
        int y_offset = std::numeric_limits<int>::min();
        current_statement__ = 123;
        y_offset = ((b - 1) * N);
        local_scalar_t__ logprob_y0 = DUMMY_VAR__;
        local_scalar_t__ logprob_y1 = DUMMY_VAR__;
        current_statement__ = 140;
        if (stan::math::logical_eq(case_id, 0)) {
          current_statement__ = 137;
          logprob_y0 = stan::model::rvalue(log_not_eta0, "log_not_eta0",
                         stan::model::index_uni(b));
          current_statement__ = 138;
          logprob_y1 = stan::model::rvalue(log_eta0, "log_eta0",
                         stan::model::index_uni(b));
        } else {
          current_statement__ = 136;
          if (stan::math::logical_eq(case_id, 1)) {
            current_statement__ = 133;
            logprob_y0 = log_half;
            current_statement__ = 134;
            logprob_y1 = log_half;
          } else {
            current_statement__ = 132;
            if (stan::math::logical_eq(case_id, 2)) {
              current_statement__ = 129;
              logprob_y0 = stan::model::rvalue(log_not_eta_high,
                             "log_not_eta_high", stan::model::index_uni(b));
              current_statement__ = 130;
              logprob_y1 = stan::model::rvalue(log_eta_high, "log_eta_high",
                             stan::model::index_uni(b));
            } else {
              current_statement__ = 126;
              logprob_y0 = log_half;
              current_statement__ = 127;
              logprob_y1 = log_half;
            }
          }
        }
        current_statement__ = 147;
        for (int n = 1; n <= N; ++n) {
          current_statement__ = 145;
          if (stan::math::logical_eq(
                stan::model::rvalue(y, "y",
                  stan::model::index_uni((y_offset + n))), 1)) {
            current_statement__ = 143;
            stan::model::assign(logprob,
              (stan::model::rvalue(logprob, "logprob",
                 stan::model::index_uni(cls), stan::model::index_uni(n)) +
              logprob_y1), "assigning variable logprob",
              stan::model::index_uni(cls), stan::model::index_uni(n));
          } else {
            current_statement__ = 141;
            stan::model::assign(logprob,
              (stan::model::rvalue(logprob, "logprob",
                 stan::model::index_uni(cls), stan::model::index_uni(n)) +
              logprob_y0), "assigning variable logprob",
              stan::model::index_uni(cls), stan::model::index_uni(n));
          }
        }
      }
    }
    current_statement__ = 152;
    return logprob;
  } catch (const std::exception& e) {
    stan::lang::rethrow_located(e, locations_array__[current_statement__]);
  }
}
#include <stan_meta_header.hpp>
class model_FCDCM final : public model_base_crtp<model_FCDCM> {
private:
  int N;
  int B;
  int I;
  int D;
  int C;
  std::vector<int> y;
  std::vector<int> alpha_patterns;
  std::vector<int> zeta_patterns;
  std::vector<int> patterns;
  double delta1_mu;
  double delta1_sigma;
  double delta0_mu;
  double delta0_sigma;
  double eta0_mu;
  double eta0_sigma;
  double etaAB_mu;
  double etaAB_sigma;
  std::vector<int> block_case;
  Eigen::Matrix<double,-1,-1> alpha_matrix_data__;
  Eigen::Matrix<double,-1,-1> alpha_nonmatrix_data__;
  Eigen::Map<Eigen::Matrix<double,-1,-1>> alpha_matrix{nullptr, 0, 0};
  Eigen::Map<Eigen::Matrix<double,-1,-1>> alpha_nonmatrix{nullptr, 0, 0};
public:
  ~model_FCDCM() {}
  model_FCDCM(stan::io::var_context& context__, unsigned int
              random_seed__ = 0, std::ostream* pstream__ = nullptr)
      : model_base_crtp(0) {
    int current_statement__ = 0;
    using local_scalar_t__ = double;
    boost::ecuyer1988 base_rng__ =
      stan::services::util::create_rng(random_seed__, 0);
    // suppress unused var warning
    (void) base_rng__;
    static constexpr const char* function__ =
      "model_FCDCM_namespace::model_FCDCM";
    // suppress unused var warning
    (void) function__;
    local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
    // suppress unused var warning
    (void) DUMMY_VAR__;
    try {
      int pos__ = std::numeric_limits<int>::min();
      pos__ = 1;
      current_statement__ = 41;
      context__.validate_dims("data initialization", "N", "int",
        std::vector<size_t>{});
      N = std::numeric_limits<int>::min();
      current_statement__ = 41;
      N = context__.vals_i("N")[(1 - 1)];
      current_statement__ = 41;
      stan::math::check_greater_or_equal(function__, "N", N, 1);
      current_statement__ = 42;
      context__.validate_dims("data initialization", "B", "int",
        std::vector<size_t>{});
      B = std::numeric_limits<int>::min();
      current_statement__ = 42;
      B = context__.vals_i("B")[(1 - 1)];
      current_statement__ = 42;
      stan::math::check_greater_or_equal(function__, "B", B, 1);
      current_statement__ = 43;
      context__.validate_dims("data initialization", "I", "int",
        std::vector<size_t>{});
      I = std::numeric_limits<int>::min();
      current_statement__ = 43;
      I = context__.vals_i("I")[(1 - 1)];
      current_statement__ = 43;
      stan::math::check_greater_or_equal(function__, "I", I, 1);
      current_statement__ = 44;
      context__.validate_dims("data initialization", "D", "int",
        std::vector<size_t>{});
      D = std::numeric_limits<int>::min();
      current_statement__ = 44;
      D = context__.vals_i("D")[(1 - 1)];
      current_statement__ = 44;
      stan::math::check_greater_or_equal(function__, "D", D, 1);
      current_statement__ = 45;
      context__.validate_dims("data initialization", "C", "int",
        std::vector<size_t>{});
      C = std::numeric_limits<int>::min();
      current_statement__ = 45;
      C = context__.vals_i("C")[(1 - 1)];
      current_statement__ = 45;
      stan::math::check_greater_or_equal(function__, "C", C, 1);
      current_statement__ = 46;
      stan::math::validate_non_negative_index("y", "N * B", (N * B));
      current_statement__ = 47;
      context__.validate_dims("data initialization", "y", "int",
        std::vector<size_t>{static_cast<size_t>((N * B))});
      y = std::vector<int>((N * B), std::numeric_limits<int>::min());
      current_statement__ = 47;
      y = context__.vals_i("y");
      current_statement__ = 47;
      stan::math::check_greater_or_equal(function__, "y", y, 0);
      current_statement__ = 47;
      stan::math::check_less_or_equal(function__, "y", y, 1);
      current_statement__ = 48;
      stan::math::validate_non_negative_index("alpha_patterns", "C * D", (C *
        D));
      current_statement__ = 49;
      context__.validate_dims("data initialization", "alpha_patterns", "int",
        std::vector<size_t>{static_cast<size_t>((C * D))});
      alpha_patterns = std::vector<int>((C * D),
                         std::numeric_limits<int>::min());
      current_statement__ = 49;
      alpha_patterns = context__.vals_i("alpha_patterns");
      current_statement__ = 49;
      stan::math::check_greater_or_equal(function__, "alpha_patterns",
        alpha_patterns, 0);
      current_statement__ = 49;
      stan::math::check_less_or_equal(function__, "alpha_patterns",
        alpha_patterns, 1);
      current_statement__ = 50;
      stan::math::validate_non_negative_index("zeta_patterns", "C * I", (C *
        I));
      current_statement__ = 51;
      context__.validate_dims("data initialization", "zeta_patterns", "int",
        std::vector<size_t>{static_cast<size_t>((C * I))});
      zeta_patterns = std::vector<int>((C * I),
                        std::numeric_limits<int>::min());
      current_statement__ = 51;
      zeta_patterns = context__.vals_i("zeta_patterns");
      current_statement__ = 51;
      stan::math::check_greater_or_equal(function__, "zeta_patterns",
        zeta_patterns, 0);
      current_statement__ = 51;
      stan::math::check_less_or_equal(function__, "zeta_patterns",
        zeta_patterns, 1);
      current_statement__ = 52;
      stan::math::validate_non_negative_index("patterns", "B * 2", (B * 2));
      current_statement__ = 53;
      context__.validate_dims("data initialization", "patterns", "int",
        std::vector<size_t>{static_cast<size_t>((B * 2))});
      patterns = std::vector<int>((B * 2), std::numeric_limits<int>::min());
      current_statement__ = 53;
      patterns = context__.vals_i("patterns");
      current_statement__ = 53;
      stan::math::check_greater_or_equal(function__, "patterns", patterns, 1);
      current_statement__ = 53;
      stan::math::check_less_or_equal(function__, "patterns", patterns, I);
      current_statement__ = 54;
      context__.validate_dims("data initialization", "delta1_mu", "double",
        std::vector<size_t>{});
      delta1_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 54;
      delta1_mu = context__.vals_r("delta1_mu")[(1 - 1)];
      current_statement__ = 55;
      context__.validate_dims("data initialization", "delta1_sigma",
        "double", std::vector<size_t>{});
      delta1_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 55;
      delta1_sigma = context__.vals_r("delta1_sigma")[(1 - 1)];
      current_statement__ = 55;
      stan::math::check_greater_or_equal(function__, "delta1_sigma",
        delta1_sigma, 0);
      current_statement__ = 56;
      context__.validate_dims("data initialization", "delta0_mu", "double",
        std::vector<size_t>{});
      delta0_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 56;
      delta0_mu = context__.vals_r("delta0_mu")[(1 - 1)];
      current_statement__ = 57;
      context__.validate_dims("data initialization", "delta0_sigma",
        "double", std::vector<size_t>{});
      delta0_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 57;
      delta0_sigma = context__.vals_r("delta0_sigma")[(1 - 1)];
      current_statement__ = 57;
      stan::math::check_greater_or_equal(function__, "delta0_sigma",
        delta0_sigma, 0);
      current_statement__ = 58;
      context__.validate_dims("data initialization", "eta0_mu", "double",
        std::vector<size_t>{});
      eta0_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 58;
      eta0_mu = context__.vals_r("eta0_mu")[(1 - 1)];
      current_statement__ = 58;
      stan::math::check_greater_or_equal(function__, "eta0_mu", eta0_mu, 0);
      current_statement__ = 59;
      context__.validate_dims("data initialization", "eta0_sigma", "double",
        std::vector<size_t>{});
      eta0_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 59;
      eta0_sigma = context__.vals_r("eta0_sigma")[(1 - 1)];
      current_statement__ = 59;
      stan::math::check_greater_or_equal(function__, "eta0_sigma",
        eta0_sigma, 0);
      current_statement__ = 60;
      context__.validate_dims("data initialization", "etaAB_mu", "double",
        std::vector<size_t>{});
      etaAB_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 60;
      etaAB_mu = context__.vals_r("etaAB_mu")[(1 - 1)];
      current_statement__ = 60;
      stan::math::check_greater_or_equal(function__, "etaAB_mu", etaAB_mu, 0);
      current_statement__ = 61;
      context__.validate_dims("data initialization", "etaAB_sigma", "double",
        std::vector<size_t>{});
      etaAB_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 61;
      etaAB_sigma = context__.vals_r("etaAB_sigma")[(1 - 1)];
      current_statement__ = 61;
      stan::math::check_greater_or_equal(function__, "etaAB_sigma",
        etaAB_sigma, 0);
      current_statement__ = 62;
      stan::math::validate_non_negative_index("block_case", "C * B", (C * B));
      current_statement__ = 63;
      block_case = std::vector<int>((C * B), std::numeric_limits<int>::min());
      current_statement__ = 64;
      stan::math::validate_non_negative_index("alpha_matrix", "C", C);
      current_statement__ = 65;
      stan::math::validate_non_negative_index("alpha_matrix", "D", D);
      current_statement__ = 66;
      alpha_matrix_data__ = Eigen::Matrix<double,-1,-1>::Constant(C, D,
                              std::numeric_limits<double>::quiet_NaN());
      new (&alpha_matrix)
        Eigen::Map<Eigen::Matrix<double,-1,-1>>(alpha_matrix_data__.data(),
        C, D);
      current_statement__ = 67;
      stan::math::validate_non_negative_index("alpha_nonmatrix", "C", C);
      current_statement__ = 68;
      stan::math::validate_non_negative_index("alpha_nonmatrix", "D", D);
      current_statement__ = 69;
      alpha_nonmatrix_data__ = Eigen::Matrix<double,-1,-1>::Constant(C, D,
                                 std::numeric_limits<double>::quiet_NaN());
      new (&alpha_nonmatrix)
        Eigen::Map<Eigen::Matrix<double,-1,-1>>(alpha_nonmatrix_data__.data(),
        C, D);
      current_statement__ = 94;
      for (int cls = 1; cls <= C; ++cls) {
        int class_offset = std::numeric_limits<int>::min();
        current_statement__ = 70;
        class_offset = ((cls - 1) * I);
        int block_offset = std::numeric_limits<int>::min();
        current_statement__ = 71;
        block_offset = ((cls - 1) * B);
        current_statement__ = 75;
        for (int d = 1; d <= D; ++d) {
          current_statement__ = 72;
          stan::model::assign(alpha_matrix,
            stan::model::rvalue(alpha_patterns, "alpha_patterns",
              stan::model::index_uni((((cls - 1) * D) + d))),
            "assigning variable alpha_matrix", stan::model::index_uni(cls),
            stan::model::index_uni(d));
          current_statement__ = 73;
          stan::model::assign(alpha_nonmatrix, (1 -
            stan::model::rvalue(alpha_matrix, "alpha_matrix",
              stan::model::index_uni(cls), stan::model::index_uni(d))),
            "assigning variable alpha_nonmatrix",
            stan::model::index_uni(cls), stan::model::index_uni(d));
        }
        current_statement__ = 92;
        for (int b = 1; b <= B; ++b) {
          int item_a = std::numeric_limits<int>::min();
          current_statement__ = 76;
          item_a = stan::model::rvalue(patterns, "patterns",
                     stan::model::index_uni((((b - 1) * 2) + 1)));
          int item_b = std::numeric_limits<int>::min();
          current_statement__ = 77;
          item_b = stan::model::rvalue(patterns, "patterns",
                     stan::model::index_uni((((b - 1) * 2) + 2)));
          int zeta_a = std::numeric_limits<int>::min();
          current_statement__ = 78;
          zeta_a = stan::model::rvalue(zeta_patterns, "zeta_patterns",
                     stan::model::index_uni((class_offset + item_a)));
          int zeta_b = std::numeric_limits<int>::min();
          current_statement__ = 79;
          zeta_b = stan::model::rvalue(zeta_patterns, "zeta_patterns",
                     stan::model::index_uni((class_offset + item_b)));
          current_statement__ = 90;
          if (stan::math::logical_lt(zeta_a, zeta_b)) {
            current_statement__ = 88;
            stan::model::assign(block_case, 0,
              "assigning variable block_case",
              stan::model::index_uni((block_offset + b)));
          } else {
            current_statement__ = 87;
            if (stan::math::logical_gt(zeta_a, zeta_b)) {
              current_statement__ = 85;
              stan::model::assign(block_case, 2,
                "assigning variable block_case",
                stan::model::index_uni((block_offset + b)));
            } else {
              current_statement__ = 84;
              if (stan::math::logical_eq(zeta_a, 0)) {
                current_statement__ = 82;
                stan::model::assign(block_case, 1,
                  "assigning variable block_case",
                  stan::model::index_uni((block_offset + b)));
              } else {
                current_statement__ = 80;
                stan::model::assign(block_case, 3,
                  "assigning variable block_case",
                  stan::model::index_uni((block_offset + b)));
              }
            }
          }
        }
      }
      current_statement__ = 63;
      stan::math::check_greater_or_equal(function__, "block_case",
        block_case, 0);
      current_statement__ = 63;
      stan::math::check_less_or_equal(function__, "block_case", block_case, 3);
      current_statement__ = 95;
      stan::math::validate_non_negative_index("theta", "N", N);
      current_statement__ = 96;
      stan::math::validate_non_negative_index("delta1", "D", D);
      current_statement__ = 97;
      stan::math::validate_non_negative_index("delta0", "D", D);
      current_statement__ = 98;
      stan::math::validate_non_negative_index("eta0", "B", B);
      current_statement__ = 99;
      stan::math::validate_non_negative_index("etaAB", "B", B);
      current_statement__ = 100;
      stan::math::validate_non_negative_index("log_lik", "N", N);
    } catch (const std::exception& e) {
      stan::lang::rethrow_located(e, locations_array__[current_statement__]);
    }
    num_params_r__ = N + D + D + B + B;
  }
  inline std::string model_name() const final {
    return "model_FCDCM";
  }
  inline std::vector<std::string> model_compile_info() const noexcept {
    return std::vector<std::string>{"stanc_version = stanc3 v2.32.2",
             "stancflags = --allow-undefined"};
  }
  template <bool propto__, bool jacobian__, typename VecR, typename VecI,
            stan::require_vector_like_t<VecR>* = nullptr,
            stan::require_vector_like_vt<std::is_integral, VecI>* = nullptr>
  inline stan::scalar_type_t<VecR>
  log_prob_impl(VecR& params_r__, VecI& params_i__, std::ostream*
                pstream__ = nullptr) const {
    using T__ = stan::scalar_type_t<VecR>;
    using local_scalar_t__ = T__;
    T__ lp__(0.0);
    stan::math::accumulator<T__> lp_accum__;
    stan::io::deserializer<local_scalar_t__> in__(params_r__, params_i__);
    int current_statement__ = 0;
    local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
    // suppress unused var warning
    (void) DUMMY_VAR__;
    static constexpr const char* function__ =
      "model_FCDCM_namespace::log_prob";
    // suppress unused var warning
    (void) function__;
    try {
      Eigen::Matrix<local_scalar_t__,-1,1> theta =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(N, DUMMY_VAR__);
      current_statement__ = 1;
      theta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(N);
      Eigen::Matrix<local_scalar_t__,-1,1> delta1 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
      current_statement__ = 2;
      delta1 = in__.template read_constrain_lb<
                 Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, lp__,
                 D);
      Eigen::Matrix<local_scalar_t__,-1,1> delta0 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
      current_statement__ = 3;
      delta0 = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(D);
      Eigen::Matrix<local_scalar_t__,-1,1> eta0 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
      current_statement__ = 4;
      eta0 = in__.template read_constrain_lub<
               Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, 0.5,
               lp__, B);
      Eigen::Matrix<local_scalar_t__,-1,1> etaAB =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
      current_statement__ = 5;
      etaAB = in__.template read_constrain_lub<
                Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, 0.5,
                lp__, B);
      {
        current_statement__ = 22;
        stan::math::validate_non_negative_index("response_logprob", "C", C);
        current_statement__ = 23;
        stan::math::validate_non_negative_index("response_logprob", "N", N);
        Eigen::Matrix<local_scalar_t__,-1,-1> response_logprob =
          Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(C, N, DUMMY_VAR__);
        current_statement__ = 24;
        stan::model::assign(response_logprob,
          fcdcm_response_logprob(C, N, B, block_case, y, eta0, etaAB,
            pstream__), "assigning variable response_logprob");
        current_statement__ = 25;
        lp_accum__.add(stan::math::std_normal_lpdf<propto__>(theta));
        current_statement__ = 26;
        lp_accum__.add(stan::math::lognormal_lpdf<propto__>(delta1,
                         delta1_mu, delta1_sigma));
        current_statement__ = 27;
        lp_accum__.add(stan::math::normal_lpdf<propto__>(delta0, delta0_mu,
                         delta0_sigma));
        current_statement__ = 28;
        lp_accum__.add(stan::math::normal_lpdf<propto__>(eta0, eta0_mu,
                         eta0_sigma));
        current_statement__ = 29;
        lp_accum__.add(stan::math::normal_lpdf<propto__>(etaAB, etaAB_mu,
                         etaAB_sigma));
        current_statement__ = 40;
        for (int n = 1; n <= N; ++n) {
          current_statement__ = 30;
          stan::math::validate_non_negative_index("eta", "D", D);
          Eigen::Matrix<local_scalar_t__,-1,1> eta =
            Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
          current_statement__ = 31;
          stan::model::assign(eta,
            stan::math::elt_multiply(delta1,
              stan::math::subtract(
                stan::math::rep_vector(
                  stan::model::rvalue(theta, "theta",
                    stan::model::index_uni(n)), D), delta0)),
            "assigning variable eta");
          current_statement__ = 32;
          stan::math::validate_non_negative_index("log_mastery", "D", D);
          Eigen::Matrix<local_scalar_t__,-1,1> log_mastery =
            Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
          current_statement__ = 33;
          stan::model::assign(log_mastery, stan::math::log_inv_logit(eta),
            "assigning variable log_mastery");
          current_statement__ = 34;
          stan::math::validate_non_negative_index("log_nonmastery", "D", D);
          Eigen::Matrix<local_scalar_t__,-1,1> log_nonmastery =
            Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
          current_statement__ = 35;
          stan::model::assign(log_nonmastery,
            stan::math::log_inv_logit(stan::math::minus(eta)),
            "assigning variable log_nonmastery");
          current_statement__ = 36;
          stan::math::validate_non_negative_index("alpha_lp", "C", C);
          Eigen::Matrix<local_scalar_t__,-1,1> alpha_lp =
            Eigen::Matrix<local_scalar_t__,-1,1>::Constant(C, DUMMY_VAR__);
          current_statement__ = 37;
          stan::model::assign(alpha_lp,
            stan::math::add(stan::math::multiply(alpha_matrix, log_mastery),
              stan::math::multiply(alpha_nonmatrix, log_nonmastery)),
            "assigning variable alpha_lp");
          current_statement__ = 38;
          lp_accum__.add(stan::math::log_sum_exp(
                           stan::math::add(alpha_lp,
                             stan::math::col(response_logprob, n))));
        }
      }
    } catch (const std::exception& e) {
      stan::lang::rethrow_located(e, locations_array__[current_statement__]);
    }
    lp_accum__.add(lp__);
    return lp_accum__.sum();
  }
  template <typename RNG, typename VecR, typename VecI, typename VecVar,
            stan::require_vector_like_vt<std::is_floating_point,
            VecR>* = nullptr, stan::require_vector_like_vt<std::is_integral,
            VecI>* = nullptr, stan::require_vector_vt<std::is_floating_point,
            VecVar>* = nullptr>
  inline void
  write_array_impl(RNG& base_rng__, VecR& params_r__, VecI& params_i__,
                   VecVar& vars__, const bool
                   emit_transformed_parameters__ = true, const bool
                   emit_generated_quantities__ = true, std::ostream*
                   pstream__ = nullptr) const {
    using local_scalar_t__ = double;
    stan::io::deserializer<local_scalar_t__> in__(params_r__, params_i__);
    stan::io::serializer<local_scalar_t__> out__(vars__);
    static constexpr bool propto__ = true;
    // suppress unused var warning
    (void) propto__;
    double lp__ = 0.0;
    // suppress unused var warning
    (void) lp__;
    int current_statement__ = 0;
    stan::math::accumulator<double> lp_accum__;
    local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
    // suppress unused var warning
    (void) DUMMY_VAR__;
    constexpr bool jacobian__ = false;
    static constexpr const char* function__ =
      "model_FCDCM_namespace::write_array";
    // suppress unused var warning
    (void) function__;
    try {
      Eigen::Matrix<double,-1,1> theta =
        Eigen::Matrix<double,-1,1>::Constant(N,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 1;
      theta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(N);
      Eigen::Matrix<double,-1,1> delta1 =
        Eigen::Matrix<double,-1,1>::Constant(D,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 2;
      delta1 = in__.template read_constrain_lb<
                 Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, lp__,
                 D);
      Eigen::Matrix<double,-1,1> delta0 =
        Eigen::Matrix<double,-1,1>::Constant(D,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 3;
      delta0 = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(D);
      Eigen::Matrix<double,-1,1> eta0 =
        Eigen::Matrix<double,-1,1>::Constant(B,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 4;
      eta0 = in__.template read_constrain_lub<
               Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, 0.5,
               lp__, B);
      Eigen::Matrix<double,-1,1> etaAB =
        Eigen::Matrix<double,-1,1>::Constant(B,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 5;
      etaAB = in__.template read_constrain_lub<
                Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, 0.5,
                lp__, B);
      out__.write(theta);
      out__.write(delta1);
      out__.write(delta0);
      out__.write(eta0);
      out__.write(etaAB);
      if (stan::math::logical_negation(
            (stan::math::primitive_value(emit_transformed_parameters__) ||
            stan::math::primitive_value(emit_generated_quantities__)))) {
        return ;
      }
      if (stan::math::logical_negation(emit_generated_quantities__)) {
        return ;
      }
      Eigen::Matrix<double,-1,1> log_lik =
        Eigen::Matrix<double,-1,1>::Constant(N,
          std::numeric_limits<double>::quiet_NaN());
      {
        current_statement__ = 7;
        stan::math::validate_non_negative_index("response_logprob", "C", C);
        current_statement__ = 8;
        stan::math::validate_non_negative_index("response_logprob", "N", N);
        Eigen::Matrix<double,-1,-1> response_logprob =
          Eigen::Matrix<double,-1,-1>::Constant(C, N,
            std::numeric_limits<double>::quiet_NaN());
        current_statement__ = 9;
        stan::model::assign(response_logprob,
          fcdcm_response_logprob(C, N, B, block_case, y, eta0, etaAB,
            pstream__), "assigning variable response_logprob");
        current_statement__ = 20;
        for (int n = 1; n <= N; ++n) {
          current_statement__ = 10;
          stan::math::validate_non_negative_index("eta", "D", D);
          Eigen::Matrix<double,-1,1> eta =
            Eigen::Matrix<double,-1,1>::Constant(D,
              std::numeric_limits<double>::quiet_NaN());
          current_statement__ = 11;
          stan::model::assign(eta,
            stan::math::elt_multiply(delta1,
              stan::math::subtract(
                stan::math::rep_vector(
                  stan::model::rvalue(theta, "theta",
                    stan::model::index_uni(n)), D), delta0)),
            "assigning variable eta");
          current_statement__ = 12;
          stan::math::validate_non_negative_index("log_mastery", "D", D);
          Eigen::Matrix<double,-1,1> log_mastery =
            Eigen::Matrix<double,-1,1>::Constant(D,
              std::numeric_limits<double>::quiet_NaN());
          current_statement__ = 13;
          stan::model::assign(log_mastery, stan::math::log_inv_logit(eta),
            "assigning variable log_mastery");
          current_statement__ = 14;
          stan::math::validate_non_negative_index("log_nonmastery", "D", D);
          Eigen::Matrix<double,-1,1> log_nonmastery =
            Eigen::Matrix<double,-1,1>::Constant(D,
              std::numeric_limits<double>::quiet_NaN());
          current_statement__ = 15;
          stan::model::assign(log_nonmastery,
            stan::math::log_inv_logit(stan::math::minus(eta)),
            "assigning variable log_nonmastery");
          current_statement__ = 16;
          stan::math::validate_non_negative_index("alpha_lp", "C", C);
          Eigen::Matrix<double,-1,1> alpha_lp =
            Eigen::Matrix<double,-1,1>::Constant(C,
              std::numeric_limits<double>::quiet_NaN());
          current_statement__ = 17;
          stan::model::assign(alpha_lp,
            stan::math::add(stan::math::multiply(alpha_matrix, log_mastery),
              stan::math::multiply(alpha_nonmatrix, log_nonmastery)),
            "assigning variable alpha_lp");
          current_statement__ = 18;
          stan::model::assign(log_lik,
            stan::math::log_sum_exp(
              stan::math::add(alpha_lp, stan::math::col(response_logprob, n))),
            "assigning variable log_lik", stan::model::index_uni(n));
        }
      }
      out__.write(log_lik);
    } catch (const std::exception& e) {
      stan::lang::rethrow_located(e, locations_array__[current_statement__]);
    }
  }
  template <typename VecVar, typename VecI,
            stan::require_vector_t<VecVar>* = nullptr,
            stan::require_vector_like_vt<std::is_integral, VecI>* = nullptr>
  inline void
  unconstrain_array_impl(const VecVar& params_r__, const VecI& params_i__,
                         VecVar& vars__, std::ostream* pstream__ = nullptr) const {
    using local_scalar_t__ = double;
    stan::io::deserializer<local_scalar_t__> in__(params_r__, params_i__);
    stan::io::serializer<local_scalar_t__> out__(vars__);
    int current_statement__ = 0;
    local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
    // suppress unused var warning
    (void) DUMMY_VAR__;
    try {
      int pos__ = std::numeric_limits<int>::min();
      pos__ = 1;
      Eigen::Matrix<local_scalar_t__,-1,1> theta =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(N, DUMMY_VAR__);
      current_statement__ = 1;
      stan::model::assign(theta,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(N),
        "assigning variable theta");
      out__.write(theta);
      Eigen::Matrix<local_scalar_t__,-1,1> delta1 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
      current_statement__ = 2;
      stan::model::assign(delta1,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(D),
        "assigning variable delta1");
      out__.write_free_lb(0, delta1);
      Eigen::Matrix<local_scalar_t__,-1,1> delta0 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
      current_statement__ = 3;
      stan::model::assign(delta0,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(D),
        "assigning variable delta0");
      out__.write(delta0);
      Eigen::Matrix<local_scalar_t__,-1,1> eta0 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
      current_statement__ = 4;
      stan::model::assign(eta0,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(B),
        "assigning variable eta0");
      out__.write_free_lub(0, 0.5, eta0);
      Eigen::Matrix<local_scalar_t__,-1,1> etaAB =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
      current_statement__ = 5;
      stan::model::assign(etaAB,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(B),
        "assigning variable etaAB");
      out__.write_free_lub(0, 0.5, etaAB);
    } catch (const std::exception& e) {
      stan::lang::rethrow_located(e, locations_array__[current_statement__]);
    }
  }
  template <typename VecVar, stan::require_vector_t<VecVar>* = nullptr>
  inline void
  transform_inits_impl(const stan::io::var_context& context__, VecVar&
                       vars__, std::ostream* pstream__ = nullptr) const {
    using local_scalar_t__ = double;
    stan::io::serializer<local_scalar_t__> out__(vars__);
    int current_statement__ = 0;
    local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
    // suppress unused var warning
    (void) DUMMY_VAR__;
    try {
      current_statement__ = 1;
      context__.validate_dims("parameter initialization", "theta", "double",
        std::vector<size_t>{static_cast<size_t>(N)});
      current_statement__ = 2;
      context__.validate_dims("parameter initialization", "delta1", "double",
        std::vector<size_t>{static_cast<size_t>(D)});
      current_statement__ = 3;
      context__.validate_dims("parameter initialization", "delta0", "double",
        std::vector<size_t>{static_cast<size_t>(D)});
      current_statement__ = 4;
      context__.validate_dims("parameter initialization", "eta0", "double",
        std::vector<size_t>{static_cast<size_t>(B)});
      current_statement__ = 5;
      context__.validate_dims("parameter initialization", "etaAB", "double",
        std::vector<size_t>{static_cast<size_t>(B)});
      int pos__ = std::numeric_limits<int>::min();
      pos__ = 1;
      Eigen::Matrix<local_scalar_t__,-1,1> theta =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(N, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> theta_flat__;
        current_statement__ = 1;
        theta_flat__ = context__.vals_r("theta");
        current_statement__ = 1;
        pos__ = 1;
        current_statement__ = 1;
        for (int sym1__ = 1; sym1__ <= N; ++sym1__) {
          current_statement__ = 1;
          stan::model::assign(theta, theta_flat__[(pos__ - 1)],
            "assigning variable theta", stan::model::index_uni(sym1__));
          current_statement__ = 1;
          pos__ = (pos__ + 1);
        }
      }
      out__.write(theta);
      Eigen::Matrix<local_scalar_t__,-1,1> delta1 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> delta1_flat__;
        current_statement__ = 2;
        delta1_flat__ = context__.vals_r("delta1");
        current_statement__ = 2;
        pos__ = 1;
        current_statement__ = 2;
        for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
          current_statement__ = 2;
          stan::model::assign(delta1, delta1_flat__[(pos__ - 1)],
            "assigning variable delta1", stan::model::index_uni(sym1__));
          current_statement__ = 2;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_lb(0, delta1);
      Eigen::Matrix<local_scalar_t__,-1,1> delta0 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> delta0_flat__;
        current_statement__ = 3;
        delta0_flat__ = context__.vals_r("delta0");
        current_statement__ = 3;
        pos__ = 1;
        current_statement__ = 3;
        for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
          current_statement__ = 3;
          stan::model::assign(delta0, delta0_flat__[(pos__ - 1)],
            "assigning variable delta0", stan::model::index_uni(sym1__));
          current_statement__ = 3;
          pos__ = (pos__ + 1);
        }
      }
      out__.write(delta0);
      Eigen::Matrix<local_scalar_t__,-1,1> eta0 =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> eta0_flat__;
        current_statement__ = 4;
        eta0_flat__ = context__.vals_r("eta0");
        current_statement__ = 4;
        pos__ = 1;
        current_statement__ = 4;
        for (int sym1__ = 1; sym1__ <= B; ++sym1__) {
          current_statement__ = 4;
          stan::model::assign(eta0, eta0_flat__[(pos__ - 1)],
            "assigning variable eta0", stan::model::index_uni(sym1__));
          current_statement__ = 4;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_lub(0, 0.5, eta0);
      Eigen::Matrix<local_scalar_t__,-1,1> etaAB =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(B, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> etaAB_flat__;
        current_statement__ = 5;
        etaAB_flat__ = context__.vals_r("etaAB");
        current_statement__ = 5;
        pos__ = 1;
        current_statement__ = 5;
        for (int sym1__ = 1; sym1__ <= B; ++sym1__) {
          current_statement__ = 5;
          stan::model::assign(etaAB, etaAB_flat__[(pos__ - 1)],
            "assigning variable etaAB", stan::model::index_uni(sym1__));
          current_statement__ = 5;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_lub(0, 0.5, etaAB);
    } catch (const std::exception& e) {
      stan::lang::rethrow_located(e, locations_array__[current_statement__]);
    }
  }
  inline void
  get_param_names(std::vector<std::string>& names__, const bool
                  emit_transformed_parameters__ = true, const bool
                  emit_generated_quantities__ = true) const {
    names__ = std::vector<std::string>{"theta", "delta1", "delta0", "eta0",
                "etaAB"};
    if (emit_transformed_parameters__) {}
    if (emit_generated_quantities__) {
      std::vector<std::string> temp{"log_lik"};
      names__.reserve(names__.size() + temp.size());
      names__.insert(names__.end(), temp.begin(), temp.end());
    }
  }
  inline void
  get_dims(std::vector<std::vector<size_t>>& dimss__, const bool
           emit_transformed_parameters__ = true, const bool
           emit_generated_quantities__ = true) const {
    dimss__ = std::vector<std::vector<size_t>>{std::vector<size_t>{static_cast<
                                                                    size_t>(N)},
                std::vector<size_t>{static_cast<size_t>(D)},
                std::vector<size_t>{static_cast<size_t>(D)},
                std::vector<size_t>{static_cast<size_t>(B)},
                std::vector<size_t>{static_cast<size_t>(B)}};
    if (emit_transformed_parameters__) {}
    if (emit_generated_quantities__) {
      std::vector<std::vector<size_t>>
        temp{std::vector<size_t>{static_cast<size_t>(N)}};
      dimss__.reserve(dimss__.size() + temp.size());
      dimss__.insert(dimss__.end(), temp.begin(), temp.end());
    }
  }
  inline void
  constrained_param_names(std::vector<std::string>& param_names__, bool
                          emit_transformed_parameters__ = true, bool
                          emit_generated_quantities__ = true) const final {
    for (int sym1__ = 1; sym1__ <= N; ++sym1__) {
      param_names__.emplace_back(std::string() + "theta" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta1" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta0" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= B; ++sym1__) {
      param_names__.emplace_back(std::string() + "eta0" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= B; ++sym1__) {
      param_names__.emplace_back(std::string() + "etaAB" + '.' +
        std::to_string(sym1__));
    }
    if (emit_transformed_parameters__) {}
    if (emit_generated_quantities__) {
      for (int sym1__ = 1; sym1__ <= N; ++sym1__) {
        param_names__.emplace_back(std::string() + "log_lik" + '.' +
          std::to_string(sym1__));
      }
    }
  }
  inline void
  unconstrained_param_names(std::vector<std::string>& param_names__, bool
                            emit_transformed_parameters__ = true, bool
                            emit_generated_quantities__ = true) const final {
    for (int sym1__ = 1; sym1__ <= N; ++sym1__) {
      param_names__.emplace_back(std::string() + "theta" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta1" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta0" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= B; ++sym1__) {
      param_names__.emplace_back(std::string() + "eta0" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= B; ++sym1__) {
      param_names__.emplace_back(std::string() + "etaAB" + '.' +
        std::to_string(sym1__));
    }
    if (emit_transformed_parameters__) {}
    if (emit_generated_quantities__) {
      for (int sym1__ = 1; sym1__ <= N; ++sym1__) {
        param_names__.emplace_back(std::string() + "log_lik" + '.' +
          std::to_string(sym1__));
      }
    }
  }
  inline std::string get_constrained_sizedtypes() const {
    return std::string("[{\"name\":\"theta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(N) + "},\"block\":\"parameters\"},{\"name\":\"delta1\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(D) + "},\"block\":\"parameters\"},{\"name\":\"delta0\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(D) + "},\"block\":\"parameters\"},{\"name\":\"eta0\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(B) + "},\"block\":\"parameters\"},{\"name\":\"etaAB\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(B) + "},\"block\":\"parameters\"},{\"name\":\"log_lik\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(N) + "},\"block\":\"generated_quantities\"}]");
  }
  inline std::string get_unconstrained_sizedtypes() const {
    return std::string("[{\"name\":\"theta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(N) + "},\"block\":\"parameters\"},{\"name\":\"delta1\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(D) + "},\"block\":\"parameters\"},{\"name\":\"delta0\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(D) + "},\"block\":\"parameters\"},{\"name\":\"eta0\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(B) + "},\"block\":\"parameters\"},{\"name\":\"etaAB\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(B) + "},\"block\":\"parameters\"},{\"name\":\"log_lik\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(N) + "},\"block\":\"generated_quantities\"}]");
  }
  // Begin method overload boilerplate
  template <typename RNG> inline void
  write_array(RNG& base_rng, Eigen::Matrix<double,-1,1>& params_r,
              Eigen::Matrix<double,-1,1>& vars, const bool
              emit_transformed_parameters = true, const bool
              emit_generated_quantities = true, std::ostream*
              pstream = nullptr) const {
    const size_t num_params__ = ((((N + D) + D) + B) + B);
    const size_t num_transformed = emit_transformed_parameters * (0);
    const size_t num_gen_quantities = emit_generated_quantities * (N);
    const size_t num_to_write = num_params__ + num_transformed +
      num_gen_quantities;
    std::vector<int> params_i;
    vars = Eigen::Matrix<double,-1,1>::Constant(num_to_write,
             std::numeric_limits<double>::quiet_NaN());
    write_array_impl(base_rng, params_r, params_i, vars,
      emit_transformed_parameters, emit_generated_quantities, pstream);
  }
  template <typename RNG> inline void
  write_array(RNG& base_rng, std::vector<double>& params_r, std::vector<int>&
              params_i, std::vector<double>& vars, bool
              emit_transformed_parameters = true, bool
              emit_generated_quantities = true, std::ostream*
              pstream = nullptr) const {
    const size_t num_params__ = ((((N + D) + D) + B) + B);
    const size_t num_transformed = emit_transformed_parameters * (0);
    const size_t num_gen_quantities = emit_generated_quantities * (N);
    const size_t num_to_write = num_params__ + num_transformed +
      num_gen_quantities;
    vars = std::vector<double>(num_to_write,
             std::numeric_limits<double>::quiet_NaN());
    write_array_impl(base_rng, params_r, params_i, vars,
      emit_transformed_parameters, emit_generated_quantities, pstream);
  }
  template <bool propto__, bool jacobian__, typename T_> inline T_
  log_prob(Eigen::Matrix<T_,-1,1>& params_r, std::ostream* pstream = nullptr) const {
    Eigen::Matrix<int,-1,1> params_i;
    return log_prob_impl<propto__, jacobian__>(params_r, params_i, pstream);
  }
  template <bool propto__, bool jacobian__, typename T_> inline T_
  log_prob(std::vector<T_>& params_r, std::vector<int>& params_i,
           std::ostream* pstream = nullptr) const {
    return log_prob_impl<propto__, jacobian__>(params_r, params_i, pstream);
  }
  inline void
  transform_inits(const stan::io::var_context& context,
                  Eigen::Matrix<double,-1,1>& params_r, std::ostream*
                  pstream = nullptr) const final {
    std::vector<double> params_r_vec(params_r.size());
    std::vector<int> params_i;
    transform_inits(context, params_i, params_r_vec, pstream);
    params_r = Eigen::Map<Eigen::Matrix<double,-1,1>>(params_r_vec.data(),
                 params_r_vec.size());
  }
  inline void
  transform_inits(const stan::io::var_context& context, std::vector<int>&
                  params_i, std::vector<double>& vars, std::ostream*
                  pstream__ = nullptr) const {
    vars.resize(num_params_r__);
    transform_inits_impl(context, vars, pstream__);
  }
  inline void
  unconstrain_array(const std::vector<double>& params_constrained,
                    std::vector<double>& params_unconstrained, std::ostream*
                    pstream = nullptr) const {
    const std::vector<int> params_i;
    params_unconstrained = std::vector<double>(num_params_r__,
                             std::numeric_limits<double>::quiet_NaN());
    unconstrain_array_impl(params_constrained, params_i,
      params_unconstrained, pstream);
  }
  inline void
  unconstrain_array(const Eigen::Matrix<double,-1,1>& params_constrained,
                    Eigen::Matrix<double,-1,1>& params_unconstrained,
                    std::ostream* pstream = nullptr) const {
    const std::vector<int> params_i;
    params_unconstrained = Eigen::Matrix<double,-1,1>::Constant(num_params_r__,
                             std::numeric_limits<double>::quiet_NaN());
    unconstrain_array_impl(params_constrained, params_i,
      params_unconstrained, pstream);
  }
};
}
using stan_model = model_FCDCM_namespace::model_FCDCM;
#ifndef USING_R
// Boilerplate
stan::model::model_base&
new_model(stan::io::var_context& data_context, unsigned int seed,
          std::ostream* msg_stream) {
  stan_model* m = new stan_model(data_context, seed, msg_stream);
  return *m;
}
stan::math::profile_map& get_stan_profile_data() {
  return model_FCDCM_namespace::profiles__;
}
#endif
#endif
