// 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_FCGDINA_namespace {
using stan::model::model_base_crtp;
using namespace stan::math;
stan::math::profile_map profiles__;
static constexpr std::array<const char*, 210> locations_array__ =
  {" (found before start of program)",
  " (in 'string', line 168, column 2 to column 38)",
  " (in 'string', line 169, column 2 to column 16)",
  " (in 'string', line 172, column 2 to column 59)",
  " (in 'string', line 178, column 2 to column 47)",
  " (in 'string', line 218, column 2 to column 32)",
  " (in 'string', line 219, column 2 to column 26)",
  " (in 'string', line 180, column 4 to column 16)",
  " (in 'string', line 182, column 6 to column 29)",
  " (in 'string', line 183, column 13 to column 24)",
  " (in 'string', line 183, column 6 to line 192, column 8)",
  " (in 'string', line 193, column 6 to column 63)",
  " (in 'string', line 194, column 6 to column 25)",
  " (in 'string', line 181, column 19 to line 195, column 5)",
  " (in 'string', line 181, column 4 to line 195, column 5)",
  " (in 'string', line 179, column 2 to line 196, column 3)",
  " (in 'string', line 221, column 11 to column 12)",
  " (in 'string', line 221, column 4 to column 31)",
  " (in 'string', line 223, column 13 to column 14)",
  " (in 'string', line 223, column 6 to column 30)",
  " (in 'string', line 225, column 8 to column 31)",
  " (in 'string', line 226, column 8 to column 30)",
  " (in 'string', line 227, column 8 to column 34)",
  " (in 'string', line 229, column 10 to column 76)",
  " (in 'string', line 228, column 25 to line 230, column 9)",
  " (in 'string', line 228, column 8 to line 230, column 9)",
  " (in 'string', line 224, column 21 to line 231, column 7)",
  " (in 'string', line 224, column 6 to line 231, column 7)",
  " (in 'string', line 233, column 15 to column 16)",
  " (in 'string', line 233, column 8 to column 41)",
  " (in 'string', line 234, column 8 to column 45)",
  " (in 'string', line 236, column 10 to column 49)",
  " (in 'string', line 235, column 25 to line 237, column 9)",
  " (in 'string', line 235, column 8 to line 237, column 9)",
  " (in 'string', line 232, column 6 to line 238, column 7)",
  " (in 'string', line 222, column 19 to line 239, column 5)",
  " (in 'string', line 222, column 4 to line 239, column 5)",
  " (in 'string', line 220, column 2 to line 240, column 3)",
  " (in 'string', line 199, column 2 to column 57)",
  " (in 'string', line 200, column 2 to column 48)",
  " (in 'string', line 202, column 11 to column 12)",
  " (in 'string', line 202, column 4 to column 31)",
  " (in 'string', line 204, column 13 to column 14)",
  " (in 'string', line 204, column 6 to column 34)",
  " (in 'string', line 206, column 8 to column 31)",
  " (in 'string', line 207, column 8 to column 30)",
  " (in 'string', line 208, column 8 to column 34)",
  " (in 'string', line 210, column 10 to column 80)",
  " (in 'string', line 209, column 25 to line 211, column 9)",
  " (in 'string', line 209, column 8 to line 211, column 9)",
  " (in 'string', line 205, column 21 to line 212, column 7)",
  " (in 'string', line 205, column 6 to line 212, column 7)",
  " (in 'string', line 213, column 6 to column 51)",
  " (in 'string', line 203, column 19 to line 214, column 5)",
  " (in 'string', line 203, column 4 to line 214, column 5)",
  " (in 'string', line 201, column 2 to line 215, column 3)",
  " (in 'string', line 120, column 2 to column 17)",
  " (in 'string', line 121, column 2 to column 17)",
  " (in 'string', line 122, column 2 to column 17)",
  " (in 'string', line 123, column 2 to column 17)",
  " (in 'string', line 124, column 2 to column 17)",
  " (in 'string', line 125, column 2 to column 17)",
  " (in 'string', line 126, column 8 to column 9)",
  " (in 'string', line 126, column 11 to column 12)",
  " (in 'string', line 126, column 2 to column 36)",
  " (in 'string', line 127, column 8 to column 9)",
  " (in 'string', line 127, column 2 to column 32)",
  " (in 'string', line 128, column 8 to column 9)",
  " (in 'string', line 128, column 11 to column 12)",
  " (in 'string', line 128, column 2 to column 51)",
  " (in 'string', line 129, column 2 to column 36)",
  " (in 'string', line 130, column 8 to column 28)",
  " (in 'string', line 130, column 2 to column 47)",
  " (in 'string', line 131, column 8 to column 9)",
  " (in 'string', line 131, column 2 to column 36)",
  " (in 'string', line 132, column 8 to column 9)",
  " (in 'string', line 132, column 2 to column 36)",
  " (in 'string', line 133, column 8 to column 9)",
  " (in 'string', line 133, column 2 to column 38)",
  " (in 'string', line 134, column 2 to column 31)",
  " (in 'string', line 135, column 2 to column 32)",
  " (in 'string', line 136, column 9 to column 24)",
  " (in 'string', line 136, column 26 to column 42)",
  " (in 'string', line 136, column 2 to column 56)",
  " (in 'string', line 137, column 8 to column 9)",
  " (in 'string', line 137, column 2 to column 37)",
  " (in 'string', line 138, column 8 to column 9)",
  " (in 'string', line 138, column 11 to column 12)",
  " (in 'string', line 138, column 2 to column 37)",
  " (in 'string', line 139, column 8 to column 9)",
  " (in 'string', line 139, column 2 to column 32)",
  " (in 'string', line 140, column 2 to column 33)",
  " (in 'string', line 141, column 8 to column 25)",
  " (in 'string', line 141, column 2 to column 61)",
  " (in 'string', line 142, column 8 to column 13)",
  " (in 'string', line 142, column 2 to column 39)",
  " (in 'string', line 143, column 8 to column 9)",
  " (in 'string', line 143, column 2 to column 32)",
  " (in 'string', line 144, column 2 to column 33)",
  " (in 'string', line 145, column 8 to column 25)",
  " (in 'string', line 145, column 2 to column 55)",
  " (in 'string', line 146, column 8 to column 13)",
  " (in 'string', line 146, column 2 to column 40)",
  " (in 'string', line 147, column 8 to column 9)",
  " (in 'string', line 147, column 2 to column 30)",
  " (in 'string', line 148, column 2 to column 34)",
  " (in 'string', line 149, column 8 to column 13)",
  " (in 'string', line 149, column 2 to column 46)",
  " (in 'string', line 150, column 2 to column 36)",
  " (in 'string', line 151, column 8 to column 30)",
  " (in 'string', line 151, column 2 to column 60)",
  " (in 'string', line 152, column 8 to column 28)",
  " (in 'string', line 152, column 2 to column 58)",
  " (in 'string', line 153, column 9 to column 25)",
  " (in 'string', line 153, column 2 to column 42)",
  " (in 'string', line 154, column 2 to column 34)",
  " (in 'string', line 155, column 2 to column 31)",
  " (in 'string', line 158, column 8 to column 9)",
  " (in 'string', line 158, column 2 to column 32)",
  " (in 'string', line 160, column 4 to column 16)",
  " (in 'string', line 162, column 6 to column 23)",
  " (in 'string', line 163, column 6 to column 26)",
  " (in 'string', line 161, column 19 to line 164, column 5)",
  " (in 'string', line 161, column 4 to line 164, column 5)",
  " (in 'string', line 159, column 2 to line 165, column 3)",
  " (in 'string', line 168, column 9 to column 25)",
  " (in 'string', line 169, column 10 to column 11)",
  " (in 'string', line 172, column 9 to column 24)",
  " (in 'string', line 178, column 9 to column 31)",
  " (in 'string', line 218, column 9 to column 10)",
  " (in 'string', line 218, column 12 to column 13)",
  " (in 'string', line 219, column 9 to column 10)",
  " (in 'string', line 17, column 4 to column 36)",
  " (in 'string', line 18, column 4 to column 35)",
  " (in 'string', line 19, column 4 to column 33)",
  " (in 'string', line 20, column 4 to column 33)",
  " (in 'string', line 21, column 4 to column 35)",
  " (in 'string', line 22, column 4 to column 19)",
  " (in 'string', line 24, column 6 to column 74)",
  " (in 'string', line 23, column 22 to line 25, column 5)",
  " (in 'string', line 23, column 4 to line 25, column 5)",
  " (in 'string', line 26, column 4 to column 15)",
  " (in 'string', line 16, column 4 to line 27, column 3)",
  " (in 'string', line 49, column 11 to column 22)",
  " (in 'string', line 49, column 4 to column 31)",
  " (in 'string', line 53, column 11 to column 12)",
  " (in 'string', line 53, column 14 to column 15)",
  " (in 'string', line 53, column 4 to column 25)",
  " (in 'string', line 56, column 8 to column 55)",
  " (in 'string', line 57, column 8 to line 60, column 10)",
  " (in 'string', line 61, column 8 to column 30)",
  " (in 'string', line 55, column 21 to line 62, column 7)",
  " (in 'string', line 55, column 6 to line 62, column 7)",
  " (in 'string', line 54, column 21 to line 63, column 5)",
  " (in 'string', line 54, column 4 to line 63, column 5)",
  " (in 'string', line 65, column 11 to column 12)",
  " (in 'string', line 65, column 14 to column 19)",
  " (in 'string', line 65, column 4 to column 30)",
  " (in 'string', line 96, column 10 to column 31)",
  " (in 'string', line 95, column 27 to line 97, column 9)",
  " (in 'string', line 95, column 8 to line 97, column 9)",
  " (in 'string', line 94, column 23 to line 98, column 7)",
  " (in 'string', line 94, column 6 to line 98, column 7)",
  " (in 'string', line 92, column 11 to line 99, column 5)",
  " (in 'string', line 68, column 15 to column 20)",
  " (in 'string', line 68, column 8 to column 29)",
  " (in 'string', line 70, column 10 to column 22)",
  " (in 'string', line 72, column 12 to column 38)",
  " (in 'string', line 73, column 19 to column 20)",
  " (in 'string', line 73, column 12 to column 30)",
  " (in 'string', line 74, column 12 to column 31)",
  " (in 'string', line 76, column 14 to column 38)",
  " (in 'string', line 77, column 14 to column 76)",
  " (in 'string', line 78, column 14 to column 50)",
  " (in 'string', line 79, column 14 to column 36)",
  " (in 'string', line 81, column 16 to column 33)",
  " (in 'string', line 80, column 30 to line 82, column 15)",
  " (in 'string', line 80, column 14 to line 82, column 15)",
  " (in 'string', line 75, column 37 to line 83, column 13)",
  " (in 'string', line 75, column 12 to line 83, column 13)",
  " (in 'string', line 84, column 12 to column 62)",
  " (in 'string', line 71, column 33 to line 85, column 11)",
  " (in 'string', line 71, column 10 to line 85, column 11)",
  " (in 'string', line 86, column 10 to column 25)",
  " (in 'string', line 69, column 27 to line 87, column 9)",
  " (in 'string', line 69, column 8 to line 87, column 9)",
  " (in 'string', line 89, column 10 to column 39)",
  " (in 'string', line 88, column 27 to line 90, column 9)",
  " (in 'string', line 88, column 8 to line 90, column 9)",
  " (in 'string', line 67, column 23 to line 91, column 7)",
  " (in 'string', line 67, column 6 to line 91, column 7)",
  " (in 'string', line 66, column 15 to line 92, column 5)",
  " (in 'string', line 66, column 4 to line 99, column 5)",
  " (in 'string', line 103, column 8 to column 44)",
  " (in 'string', line 104, column 8 to column 49)",
  " (in 'string', line 105, column 8 to column 56)",
  " (in 'string', line 106, column 8 to column 20)",
  " (in 'string', line 107, column 8 to column 59)",
  " (in 'string', line 110, column 12 to column 75)",
  " (in 'string', line 109, column 48 to line 111, column 11)",
  " (in 'string', line 109, column 10 to line 111, column 11)",
  " (in 'string', line 108, column 36 to line 112, column 9)",
  " (in 'string', line 108, column 8 to line 112, column 9)",
  " (in 'string', line 113, column 8 to column 49)",
  " (in 'string', line 102, column 27 to line 114, column 7)",
  " (in 'string', line 102, column 6 to line 114, column 7)",
  " (in 'string', line 101, column 21 to line 115, column 5)",
  " (in 'string', line 101, column 4 to line 115, column 5)",
  " (in 'string', line 116, column 4 to column 18)",
  " (in 'string', line 48, column 4 to line 117, column 3)"};
template <typename T2__, typename T8__,
          stan::require_all_t<stan::is_stan_scalar<T2__>,
                              stan::is_col_vector<T8__>,
                              stan::is_vt_not_complex<T8__>>* = nullptr>
stan::promote_args_t<T2__, stan::base_type_t<T8__>>
fcgdina_item_eta(const int& cls, const int& item, const std::vector<T2__>&
                 flat_design, const std::vector<int>& design_rows,
                 const std::vector<int>& design_cols, const std::vector<int>&
                 design_offset, const std::vector<int>& delta_offset,
                 const std::vector<std::vector<int>>& class_map, const T8__&
                 delta_arg__, std::ostream* pstream__);
template <typename T7__, typename T13__,
          stan::require_all_t<stan::is_stan_scalar<T7__>,
                              stan::is_col_vector<T13__>,
                              stan::is_vt_not_complex<T13__>>* = nullptr>
Eigen::Matrix<stan::promote_args_t<T7__, stan::base_type_t<T13__>>,-1,1>
fcgdina_block_log_probs(const int& K, const int& n_tot, const int& t_start,
                        const int& n_obs_b, const int& obs_pat_start,
                        const int& blk_item_start, const int& C,
                        const std::vector<T7__>& flat_design,
                        const std::vector<int>& design_rows,
                        const std::vector<int>& design_cols,
                        const std::vector<int>& design_offset,
                        const std::vector<int>& delta_offset,
                        const std::vector<std::vector<int>>& class_map,
                        const T13__& delta_arg__, const std::vector<int>&
                        block_items, const std::vector<int>& patterns_total,
                        const std::vector<int>& obs_full_start,
                        const std::vector<int>& obs_full_index, std::ostream*
                        pstream__);
template <typename T2__, typename T8__,
          stan::require_all_t<stan::is_stan_scalar<T2__>,
                              stan::is_col_vector<T8__>,
                              stan::is_vt_not_complex<T8__>>*>
stan::promote_args_t<T2__, stan::base_type_t<T8__>>
fcgdina_item_eta(const int& cls, const int& item, const std::vector<T2__>&
                 flat_design, const std::vector<int>& design_rows,
                 const std::vector<int>& design_cols, const std::vector<int>&
                 design_offset, const std::vector<int>& delta_offset,
                 const std::vector<std::vector<int>>& class_map, const T8__&
                 delta_arg__, std::ostream* pstream__) {
  using local_scalar_t__ = stan::promote_args_t<T2__,
                             stan::base_type_t<T8__>>;
  int current_statement__ = 0;
  const auto& delta = stan::math::to_ref(delta_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 {
    int off_x = std::numeric_limits<int>::min();
    current_statement__ = 132;
    off_x = stan::model::rvalue(design_offset, "design_offset",
              stan::model::index_uni(item));
    int off_d = std::numeric_limits<int>::min();
    current_statement__ = 133;
    off_d = stan::model::rvalue(delta_offset, "delta_offset",
              stan::model::index_uni(item));
    int nrow = std::numeric_limits<int>::min();
    current_statement__ = 134;
    nrow = stan::model::rvalue(design_rows, "design_rows",
             stan::model::index_uni(item));
    int ncol = std::numeric_limits<int>::min();
    current_statement__ = 135;
    ncol = stan::model::rvalue(design_cols, "design_cols",
             stan::model::index_uni(item));
    int row = std::numeric_limits<int>::min();
    current_statement__ = 136;
    row = stan::model::rvalue(class_map, "class_map",
            stan::model::index_uni(item), stan::model::index_uni(cls));
    local_scalar_t__ eta = DUMMY_VAR__;
    current_statement__ = 137;
    eta = 0.0;
    current_statement__ = 140;
    for (int c = 1; c <= ncol; ++c) {
      current_statement__ = 138;
      eta = (eta +
        (stan::model::rvalue(flat_design, "flat_design",
           stan::model::index_uni(((off_x + ((row - 1) * ncol)) + c)))
        *
        stan::model::rvalue(delta, "delta",
          stan::model::index_uni((off_d + c)))));
    }
    current_statement__ = 141;
    return eta;
  } catch (const std::exception& e) {
    stan::lang::rethrow_located(e, locations_array__[current_statement__]);
  }
}
template <typename T7__, typename T13__,
          stan::require_all_t<stan::is_stan_scalar<T7__>,
                              stan::is_col_vector<T13__>,
                              stan::is_vt_not_complex<T13__>>*>
Eigen::Matrix<stan::promote_args_t<T7__, stan::base_type_t<T13__>>,-1,1>
fcgdina_block_log_probs(const int& K, const int& n_tot, const int& t_start,
                        const int& n_obs_b, const int& obs_pat_start,
                        const int& blk_item_start, const int& C,
                        const std::vector<T7__>& flat_design,
                        const std::vector<int>& design_rows,
                        const std::vector<int>& design_cols,
                        const std::vector<int>& design_offset,
                        const std::vector<int>& delta_offset,
                        const std::vector<std::vector<int>>& class_map,
                        const T13__& delta_arg__, const std::vector<int>&
                        block_items, const std::vector<int>& patterns_total,
                        const std::vector<int>& obs_full_start,
                        const std::vector<int>& obs_full_index, std::ostream*
                        pstream__) {
  using local_scalar_t__ = stan::promote_args_t<T7__,
                             stan::base_type_t<T13__>>;
  int current_statement__ = 0;
  const auto& delta = stan::math::to_ref(delta_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__ = 143;
    stan::math::validate_non_negative_index("result", "C * n_obs_b", (C *
      n_obs_b));
    Eigen::Matrix<local_scalar_t__,-1,1> result =
      Eigen::Matrix<local_scalar_t__,-1,1>::Constant((C * n_obs_b),
        DUMMY_VAR__);
    current_statement__ = 145;
    stan::math::validate_non_negative_index("eta_mat", "C", C);
    current_statement__ = 146;
    stan::math::validate_non_negative_index("eta_mat", "K", K);
    Eigen::Matrix<local_scalar_t__,-1,-1> eta_mat =
      Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(C, K, DUMMY_VAR__);
    current_statement__ = 154;
    for (int cls = 1; cls <= C; ++cls) {
      current_statement__ = 152;
      for (int k = 1; k <= K; ++k) {
        int item = std::numeric_limits<int>::min();
        current_statement__ = 148;
        item = stan::model::rvalue(block_items, "block_items",
                 stan::model::index_uni(((blk_item_start + k) - 1)));
        local_scalar_t__ eta = DUMMY_VAR__;
        current_statement__ = 149;
        eta = fcgdina_item_eta(cls, item, flat_design, design_rows,
                design_cols, design_offset, delta_offset, class_map, delta,
                pstream__);
        current_statement__ = 150;
        stan::model::assign(eta_mat, eta, "assigning variable eta_mat",
          stan::model::index_uni(cls), stan::model::index_uni(k));
      }
    }
    current_statement__ = 155;
    stan::math::validate_non_negative_index("lp_total", "C", C);
    current_statement__ = 156;
    stan::math::validate_non_negative_index("lp_total", "n_tot", n_tot);
    Eigen::Matrix<local_scalar_t__,-1,-1> lp_total =
      Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(C, n_tot, DUMMY_VAR__);
    current_statement__ = 192;
    if (stan::math::logical_gt(K, 1)) {
      current_statement__ = 190;
      for (int cls = 1; cls <= C; ++cls) {
        current_statement__ = 164;
        stan::math::validate_non_negative_index("lp_cls", "n_tot", n_tot);
        Eigen::Matrix<local_scalar_t__,-1,1> lp_cls =
          Eigen::Matrix<local_scalar_t__,-1,1>::Constant(n_tot, DUMMY_VAR__);
        current_statement__ = 185;
        for (int t = 1; t <= n_tot; ++t) {
          local_scalar_t__ lp = DUMMY_VAR__;
          current_statement__ = 166;
          lp = 0;
          current_statement__ = 182;
          for (int pos = 1; pos <= (K - 1); ++pos) {
            int rem_len = std::numeric_limits<int>::min();
            current_statement__ = 167;
            rem_len = ((K - pos) + 1);
            current_statement__ = 168;
            stan::math::validate_non_negative_index("pick_lp", "K", K);
            Eigen::Matrix<local_scalar_t__,-1,1> pick_lp =
              Eigen::Matrix<local_scalar_t__,-1,1>::Constant(K, DUMMY_VAR__);
            local_scalar_t__ chosen_lp = DUMMY_VAR__;
            current_statement__ = 170;
            chosen_lp = 0;
            current_statement__ = 179;
            for (int h_pos = 1; h_pos <= rem_len; ++h_pos) {
              int h = std::numeric_limits<int>::min();
              current_statement__ = 171;
              h = ((pos + h_pos) - 1);
              int candidate = std::numeric_limits<int>::min();
              current_statement__ = 172;
              candidate = stan::model::rvalue(patterns_total,
                            "patterns_total",
                            stan::model::index_uni((((t_start + ((t - 1) *
                              K)) + h) - 1)));
              local_scalar_t__ term = DUMMY_VAR__;
              current_statement__ = 173;
              term = stan::model::rvalue(eta_mat, "eta_mat",
                       stan::model::index_uni(cls),
                       stan::model::index_uni(candidate));
              current_statement__ = 174;
              stan::model::assign(pick_lp, term,
                "assigning variable pick_lp", stan::model::index_uni(h_pos));
              current_statement__ = 177;
              if (stan::math::logical_eq(h_pos, 1)) {
                current_statement__ = 175;
                chosen_lp = term;
              }
            }
            current_statement__ = 180;
            lp = (lp + (chosen_lp -
              stan::math::log_sum_exp(
                stan::model::rvalue(pick_lp, "pick_lp",
                  stan::model::index_min_max(1, rem_len)))));
          }
          current_statement__ = 183;
          stan::model::assign(lp_cls, lp, "assigning variable lp_cls",
            stan::model::index_uni(t));
        }
        current_statement__ = 188;
        for (int t = 1; t <= n_tot; ++t) {
          current_statement__ = 186;
          stan::model::assign(lp_total,
            stan::model::rvalue(lp_cls, "lp_cls", stan::model::index_uni(t)),
            "assigning variable lp_total", stan::model::index_uni(cls),
            stan::model::index_uni(t));
        }
      }
    } else {
      current_statement__ = 162;
      for (int cls = 1; cls <= C; ++cls) {
        current_statement__ = 160;
        for (int t = 1; t <= n_tot; ++t) {
          current_statement__ = 158;
          stan::model::assign(lp_total, 0, "assigning variable lp_total",
            stan::model::index_uni(cls), stan::model::index_uni(t));
        }
      }
    }
    current_statement__ = 207;
    for (int cls = 1; cls <= C; ++cls) {
      current_statement__ = 205;
      for (int t = 1; t <= n_obs_b; ++t) {
        int obs_idx = std::numeric_limits<int>::min();
        current_statement__ = 193;
        obs_idx = ((obs_pat_start + t) - 1);
        int first_link = std::numeric_limits<int>::min();
        current_statement__ = 194;
        first_link = stan::model::rvalue(obs_full_start, "obs_full_start",
                       stan::model::index_uni(obs_idx));
        int last_link = std::numeric_limits<int>::min();
        current_statement__ = 195;
        last_link = (stan::model::rvalue(obs_full_start, "obs_full_start",
                       stan::model::index_uni((obs_idx + 1)))
          - 1);
        local_scalar_t__ lp_obs = DUMMY_VAR__;
        current_statement__ = 197;
        lp_obs = stan::model::rvalue(lp_total, "lp_total",
                   stan::model::index_uni(cls),
                   stan::model::index_uni(
                     stan::model::rvalue(obs_full_index, "obs_full_index",
                       stan::model::index_uni(first_link))));
        current_statement__ = 202;
        if (stan::math::logical_gt(last_link, first_link)) {
          current_statement__ = 200;
          for (int j = (first_link + 1); j <= last_link; ++j) {
            current_statement__ = 198;
            lp_obs = stan::math::log_sum_exp(lp_obs,
                       stan::model::rvalue(lp_total, "lp_total",
                         stan::model::index_uni(cls),
                         stan::model::index_uni(
                           stan::model::rvalue(obs_full_index,
                             "obs_full_index", stan::model::index_uni(j)))));
          }
        }
        current_statement__ = 203;
        stan::model::assign(result, lp_obs, "assigning variable result",
          stan::model::index_uni((((cls - 1) * n_obs_b) + t)));
      }
    }
    current_statement__ = 208;
    return result;
  } catch (const std::exception& e) {
    stan::lang::rethrow_located(e, locations_array__[current_statement__]);
  }
}
#include <stan_meta_header.hpp>
class model_FCGDINA final : public model_base_crtp<model_FCGDINA> {
private:
  int N;
  int B;
  int I;
  int D;
  int C;
  int G;
  std::vector<std::vector<int>> y_unique;
  std::vector<int> y_count;
  std::vector<std::vector<int>> alpha_patterns;
  int total_design_entries;
  std::vector<double> flat_design;
  std::vector<int> design_rows;
  std::vector<int> design_cols;
  std::vector<int> design_offset;
  int total_delta_len;
  int total_delta_free;
  Eigen::Matrix<double,-1,-1> delta_basis_data__;
  std::vector<int> delta_offset;
  std::vector<std::vector<int>> class_map;
  std::vector<int> n_items;
  int total_block_items;
  std::vector<int> block_items;
  std::vector<int> item_start;
  std::vector<int> n_total;
  int total_cells_total;
  std::vector<int> patterns_total;
  std::vector<int> total_start;
  std::vector<int> n_obs;
  int total_obs_patterns;
  std::vector<int> obs_pattern_start;
  int total_obs_full_links;
  std::vector<int> obs_full_start;
  std::vector<int> obs_full_index;
  Eigen::Matrix<double,-1,1> delta_prior_mu_data__;
  double delta_prior_sigma;
  double pi_prior_alpha;
  std::vector<int> blk_off;
  int log_prob_flat_1dim__;
  Eigen::Map<Eigen::Matrix<double,-1,-1>> delta_basis{nullptr, 0, 0};
  Eigen::Map<Eigen::Matrix<double,-1,1>> delta_prior_mu{nullptr, 0};
public:
  ~model_FCGDINA() {}
  model_FCGDINA(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_FCGDINA_namespace::model_FCGDINA";
    // 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__ = 56;
      context__.validate_dims("data initialization", "N", "int",
        std::vector<size_t>{});
      N = std::numeric_limits<int>::min();
      current_statement__ = 56;
      N = context__.vals_i("N")[(1 - 1)];
      current_statement__ = 56;
      stan::math::check_greater_or_equal(function__, "N", N, 1);
      current_statement__ = 57;
      context__.validate_dims("data initialization", "B", "int",
        std::vector<size_t>{});
      B = std::numeric_limits<int>::min();
      current_statement__ = 57;
      B = context__.vals_i("B")[(1 - 1)];
      current_statement__ = 57;
      stan::math::check_greater_or_equal(function__, "B", B, 1);
      current_statement__ = 58;
      context__.validate_dims("data initialization", "I", "int",
        std::vector<size_t>{});
      I = std::numeric_limits<int>::min();
      current_statement__ = 58;
      I = context__.vals_i("I")[(1 - 1)];
      current_statement__ = 58;
      stan::math::check_greater_or_equal(function__, "I", I, 1);
      current_statement__ = 59;
      context__.validate_dims("data initialization", "D", "int",
        std::vector<size_t>{});
      D = std::numeric_limits<int>::min();
      current_statement__ = 59;
      D = context__.vals_i("D")[(1 - 1)];
      current_statement__ = 59;
      stan::math::check_greater_or_equal(function__, "D", D, 1);
      current_statement__ = 60;
      context__.validate_dims("data initialization", "C", "int",
        std::vector<size_t>{});
      C = std::numeric_limits<int>::min();
      current_statement__ = 60;
      C = context__.vals_i("C")[(1 - 1)];
      current_statement__ = 60;
      stan::math::check_greater_or_equal(function__, "C", C, 1);
      current_statement__ = 61;
      context__.validate_dims("data initialization", "G", "int",
        std::vector<size_t>{});
      G = std::numeric_limits<int>::min();
      current_statement__ = 61;
      G = context__.vals_i("G")[(1 - 1)];
      current_statement__ = 61;
      stan::math::check_greater_or_equal(function__, "G", G, 1);
      current_statement__ = 62;
      stan::math::validate_non_negative_index("y_unique", "G", G);
      current_statement__ = 63;
      stan::math::validate_non_negative_index("y_unique", "B", B);
      current_statement__ = 64;
      context__.validate_dims("data initialization", "y_unique", "int",
        std::vector<size_t>{static_cast<size_t>(G), static_cast<size_t>(B)});
      y_unique = std::vector<std::vector<int>>(G,
                   std::vector<int>(B, std::numeric_limits<int>::min()));
      {
        std::vector<int> y_unique_flat__;
        current_statement__ = 64;
        y_unique_flat__ = context__.vals_i("y_unique");
        current_statement__ = 64;
        pos__ = 1;
        current_statement__ = 64;
        for (int sym1__ = 1; sym1__ <= B; ++sym1__) {
          current_statement__ = 64;
          for (int sym2__ = 1; sym2__ <= G; ++sym2__) {
            current_statement__ = 64;
            stan::model::assign(y_unique, y_unique_flat__[(pos__ - 1)],
              "assigning variable y_unique", stan::model::index_uni(sym2__),
              stan::model::index_uni(sym1__));
            current_statement__ = 64;
            pos__ = (pos__ + 1);
          }
        }
      }
      current_statement__ = 64;
      stan::math::check_greater_or_equal(function__, "y_unique", y_unique, 1);
      current_statement__ = 65;
      stan::math::validate_non_negative_index("y_count", "G", G);
      current_statement__ = 66;
      context__.validate_dims("data initialization", "y_count", "int",
        std::vector<size_t>{static_cast<size_t>(G)});
      y_count = std::vector<int>(G, std::numeric_limits<int>::min());
      current_statement__ = 66;
      y_count = context__.vals_i("y_count");
      current_statement__ = 66;
      stan::math::check_greater_or_equal(function__, "y_count", y_count, 1);
      current_statement__ = 67;
      stan::math::validate_non_negative_index("alpha_patterns", "C", C);
      current_statement__ = 68;
      stan::math::validate_non_negative_index("alpha_patterns", "D", D);
      current_statement__ = 69;
      context__.validate_dims("data initialization", "alpha_patterns", "int",
        std::vector<size_t>{static_cast<size_t>(C), static_cast<size_t>(D)});
      alpha_patterns = std::vector<std::vector<int>>(C,
                         std::vector<int>(D, std::numeric_limits<int>::min()));
      {
        std::vector<int> alpha_patterns_flat__;
        current_statement__ = 69;
        alpha_patterns_flat__ = context__.vals_i("alpha_patterns");
        current_statement__ = 69;
        pos__ = 1;
        current_statement__ = 69;
        for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
          current_statement__ = 69;
          for (int sym2__ = 1; sym2__ <= C; ++sym2__) {
            current_statement__ = 69;
            stan::model::assign(alpha_patterns, alpha_patterns_flat__[(pos__
              - 1)], "assigning variable alpha_patterns",
              stan::model::index_uni(sym2__), stan::model::index_uni(sym1__));
            current_statement__ = 69;
            pos__ = (pos__ + 1);
          }
        }
      }
      current_statement__ = 69;
      stan::math::check_greater_or_equal(function__, "alpha_patterns",
        alpha_patterns, 0);
      current_statement__ = 69;
      stan::math::check_less_or_equal(function__, "alpha_patterns",
        alpha_patterns, 1);
      current_statement__ = 70;
      context__.validate_dims("data initialization", "total_design_entries",
        "int", std::vector<size_t>{});
      total_design_entries = std::numeric_limits<int>::min();
      current_statement__ = 70;
      total_design_entries = context__.vals_i("total_design_entries")[(1 -
        1)];
      current_statement__ = 70;
      stan::math::check_greater_or_equal(function__, "total_design_entries",
        total_design_entries, 1);
      current_statement__ = 71;
      stan::math::validate_non_negative_index("flat_design",
        "total_design_entries", total_design_entries);
      current_statement__ = 72;
      context__.validate_dims("data initialization", "flat_design", "double",
        std::vector<size_t>{static_cast<size_t>(total_design_entries)});
      flat_design = std::vector<double>(total_design_entries,
                      std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 72;
      flat_design = context__.vals_r("flat_design");
      current_statement__ = 73;
      stan::math::validate_non_negative_index("design_rows", "I", I);
      current_statement__ = 74;
      context__.validate_dims("data initialization", "design_rows", "int",
        std::vector<size_t>{static_cast<size_t>(I)});
      design_rows = std::vector<int>(I, std::numeric_limits<int>::min());
      current_statement__ = 74;
      design_rows = context__.vals_i("design_rows");
      current_statement__ = 74;
      stan::math::check_greater_or_equal(function__, "design_rows",
        design_rows, 1);
      current_statement__ = 75;
      stan::math::validate_non_negative_index("design_cols", "I", I);
      current_statement__ = 76;
      context__.validate_dims("data initialization", "design_cols", "int",
        std::vector<size_t>{static_cast<size_t>(I)});
      design_cols = std::vector<int>(I, std::numeric_limits<int>::min());
      current_statement__ = 76;
      design_cols = context__.vals_i("design_cols");
      current_statement__ = 76;
      stan::math::check_greater_or_equal(function__, "design_cols",
        design_cols, 1);
      current_statement__ = 77;
      stan::math::validate_non_negative_index("design_offset", "I", I);
      current_statement__ = 78;
      context__.validate_dims("data initialization", "design_offset", "int",
        std::vector<size_t>{static_cast<size_t>(I)});
      design_offset = std::vector<int>(I, std::numeric_limits<int>::min());
      current_statement__ = 78;
      design_offset = context__.vals_i("design_offset");
      current_statement__ = 78;
      stan::math::check_greater_or_equal(function__, "design_offset",
        design_offset, 0);
      current_statement__ = 79;
      context__.validate_dims("data initialization", "total_delta_len",
        "int", std::vector<size_t>{});
      total_delta_len = std::numeric_limits<int>::min();
      current_statement__ = 79;
      total_delta_len = context__.vals_i("total_delta_len")[(1 - 1)];
      current_statement__ = 79;
      stan::math::check_greater_or_equal(function__, "total_delta_len",
        total_delta_len, 1);
      current_statement__ = 80;
      context__.validate_dims("data initialization", "total_delta_free",
        "int", std::vector<size_t>{});
      total_delta_free = std::numeric_limits<int>::min();
      current_statement__ = 80;
      total_delta_free = context__.vals_i("total_delta_free")[(1 - 1)];
      current_statement__ = 80;
      stan::math::check_greater_or_equal(function__, "total_delta_free",
        total_delta_free, 1);
      current_statement__ = 81;
      stan::math::validate_non_negative_index("delta_basis",
        "total_delta_len", total_delta_len);
      current_statement__ = 82;
      stan::math::validate_non_negative_index("delta_basis",
        "total_delta_free", total_delta_free);
      current_statement__ = 83;
      context__.validate_dims("data initialization", "delta_basis", "double",
        std::vector<size_t>{static_cast<size_t>(total_delta_len),
          static_cast<size_t>(total_delta_free)});
      delta_basis_data__ = Eigen::Matrix<double,-1,-1>::Constant(total_delta_len,
                             total_delta_free,
                             std::numeric_limits<double>::quiet_NaN());
      new (&delta_basis)
        Eigen::Map<Eigen::Matrix<double,-1,-1>>(delta_basis_data__.data(),
        total_delta_len, total_delta_free);
      {
        std::vector<local_scalar_t__> delta_basis_flat__;
        current_statement__ = 83;
        delta_basis_flat__ = context__.vals_r("delta_basis");
        current_statement__ = 83;
        pos__ = 1;
        current_statement__ = 83;
        for (int sym1__ = 1; sym1__ <= total_delta_free; ++sym1__) {
          current_statement__ = 83;
          for (int sym2__ = 1; sym2__ <= total_delta_len; ++sym2__) {
            current_statement__ = 83;
            stan::model::assign(delta_basis, delta_basis_flat__[(pos__ - 1)],
              "assigning variable delta_basis",
              stan::model::index_uni(sym2__), stan::model::index_uni(sym1__));
            current_statement__ = 83;
            pos__ = (pos__ + 1);
          }
        }
      }
      current_statement__ = 84;
      stan::math::validate_non_negative_index("delta_offset", "I", I);
      current_statement__ = 85;
      context__.validate_dims("data initialization", "delta_offset", "int",
        std::vector<size_t>{static_cast<size_t>(I)});
      delta_offset = std::vector<int>(I, std::numeric_limits<int>::min());
      current_statement__ = 85;
      delta_offset = context__.vals_i("delta_offset");
      current_statement__ = 85;
      stan::math::check_greater_or_equal(function__, "delta_offset",
        delta_offset, 0);
      current_statement__ = 86;
      stan::math::validate_non_negative_index("class_map", "I", I);
      current_statement__ = 87;
      stan::math::validate_non_negative_index("class_map", "C", C);
      current_statement__ = 88;
      context__.validate_dims("data initialization", "class_map", "int",
        std::vector<size_t>{static_cast<size_t>(I), static_cast<size_t>(C)});
      class_map = std::vector<std::vector<int>>(I,
                    std::vector<int>(C, std::numeric_limits<int>::min()));
      {
        std::vector<int> class_map_flat__;
        current_statement__ = 88;
        class_map_flat__ = context__.vals_i("class_map");
        current_statement__ = 88;
        pos__ = 1;
        current_statement__ = 88;
        for (int sym1__ = 1; sym1__ <= C; ++sym1__) {
          current_statement__ = 88;
          for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
            current_statement__ = 88;
            stan::model::assign(class_map, class_map_flat__[(pos__ - 1)],
              "assigning variable class_map", stan::model::index_uni(sym2__),
              stan::model::index_uni(sym1__));
            current_statement__ = 88;
            pos__ = (pos__ + 1);
          }
        }
      }
      current_statement__ = 88;
      stan::math::check_greater_or_equal(function__, "class_map", class_map,
        1);
      current_statement__ = 89;
      stan::math::validate_non_negative_index("n_items", "B", B);
      current_statement__ = 90;
      context__.validate_dims("data initialization", "n_items", "int",
        std::vector<size_t>{static_cast<size_t>(B)});
      n_items = std::vector<int>(B, std::numeric_limits<int>::min());
      current_statement__ = 90;
      n_items = context__.vals_i("n_items");
      current_statement__ = 90;
      stan::math::check_greater_or_equal(function__, "n_items", n_items, 2);
      current_statement__ = 91;
      context__.validate_dims("data initialization", "total_block_items",
        "int", std::vector<size_t>{});
      total_block_items = std::numeric_limits<int>::min();
      current_statement__ = 91;
      total_block_items = context__.vals_i("total_block_items")[(1 - 1)];
      current_statement__ = 91;
      stan::math::check_greater_or_equal(function__, "total_block_items",
        total_block_items, 1);
      current_statement__ = 92;
      stan::math::validate_non_negative_index("block_items",
        "total_block_items", total_block_items);
      current_statement__ = 93;
      context__.validate_dims("data initialization", "block_items", "int",
        std::vector<size_t>{static_cast<size_t>(total_block_items)});
      block_items = std::vector<int>(total_block_items,
                      std::numeric_limits<int>::min());
      current_statement__ = 93;
      block_items = context__.vals_i("block_items");
      current_statement__ = 93;
      stan::math::check_greater_or_equal(function__, "block_items",
        block_items, 1);
      current_statement__ = 93;
      stan::math::check_less_or_equal(function__, "block_items", block_items,
        I);
      current_statement__ = 94;
      stan::math::validate_non_negative_index("item_start", "B + 1", (B + 1));
      current_statement__ = 95;
      context__.validate_dims("data initialization", "item_start", "int",
        std::vector<size_t>{static_cast<size_t>((B + 1))});
      item_start = std::vector<int>((B + 1), std::numeric_limits<int>::min());
      current_statement__ = 95;
      item_start = context__.vals_i("item_start");
      current_statement__ = 95;
      stan::math::check_greater_or_equal(function__, "item_start",
        item_start, 1);
      current_statement__ = 96;
      stan::math::validate_non_negative_index("n_total", "B", B);
      current_statement__ = 97;
      context__.validate_dims("data initialization", "n_total", "int",
        std::vector<size_t>{static_cast<size_t>(B)});
      n_total = std::vector<int>(B, std::numeric_limits<int>::min());
      current_statement__ = 97;
      n_total = context__.vals_i("n_total");
      current_statement__ = 97;
      stan::math::check_greater_or_equal(function__, "n_total", n_total, 1);
      current_statement__ = 98;
      context__.validate_dims("data initialization", "total_cells_total",
        "int", std::vector<size_t>{});
      total_cells_total = std::numeric_limits<int>::min();
      current_statement__ = 98;
      total_cells_total = context__.vals_i("total_cells_total")[(1 - 1)];
      current_statement__ = 98;
      stan::math::check_greater_or_equal(function__, "total_cells_total",
        total_cells_total, 1);
      current_statement__ = 99;
      stan::math::validate_non_negative_index("patterns_total",
        "total_cells_total", total_cells_total);
      current_statement__ = 100;
      context__.validate_dims("data initialization", "patterns_total", "int",
        std::vector<size_t>{static_cast<size_t>(total_cells_total)});
      patterns_total = std::vector<int>(total_cells_total,
                         std::numeric_limits<int>::min());
      current_statement__ = 100;
      patterns_total = context__.vals_i("patterns_total");
      current_statement__ = 100;
      stan::math::check_greater_or_equal(function__, "patterns_total",
        patterns_total, 1);
      current_statement__ = 101;
      stan::math::validate_non_negative_index("total_start", "B + 1", (B + 1));
      current_statement__ = 102;
      context__.validate_dims("data initialization", "total_start", "int",
        std::vector<size_t>{static_cast<size_t>((B + 1))});
      total_start = std::vector<int>((B + 1),
                      std::numeric_limits<int>::min());
      current_statement__ = 102;
      total_start = context__.vals_i("total_start");
      current_statement__ = 102;
      stan::math::check_greater_or_equal(function__, "total_start",
        total_start, 1);
      current_statement__ = 103;
      stan::math::validate_non_negative_index("n_obs", "B", B);
      current_statement__ = 104;
      context__.validate_dims("data initialization", "n_obs", "int",
        std::vector<size_t>{static_cast<size_t>(B)});
      n_obs = std::vector<int>(B, std::numeric_limits<int>::min());
      current_statement__ = 104;
      n_obs = context__.vals_i("n_obs");
      current_statement__ = 104;
      stan::math::check_greater_or_equal(function__, "n_obs", n_obs, 1);
      current_statement__ = 105;
      context__.validate_dims("data initialization", "total_obs_patterns",
        "int", std::vector<size_t>{});
      total_obs_patterns = std::numeric_limits<int>::min();
      current_statement__ = 105;
      total_obs_patterns = context__.vals_i("total_obs_patterns")[(1 - 1)];
      current_statement__ = 105;
      stan::math::check_greater_or_equal(function__, "total_obs_patterns",
        total_obs_patterns, 1);
      current_statement__ = 106;
      stan::math::validate_non_negative_index("obs_pattern_start", "B + 1",
        (B + 1));
      current_statement__ = 107;
      context__.validate_dims("data initialization", "obs_pattern_start",
        "int", std::vector<size_t>{static_cast<size_t>((B + 1))});
      obs_pattern_start = std::vector<int>((B + 1),
                            std::numeric_limits<int>::min());
      current_statement__ = 107;
      obs_pattern_start = context__.vals_i("obs_pattern_start");
      current_statement__ = 107;
      stan::math::check_greater_or_equal(function__, "obs_pattern_start",
        obs_pattern_start, 1);
      current_statement__ = 108;
      context__.validate_dims("data initialization", "total_obs_full_links",
        "int", std::vector<size_t>{});
      total_obs_full_links = std::numeric_limits<int>::min();
      current_statement__ = 108;
      total_obs_full_links = context__.vals_i("total_obs_full_links")[(1 -
        1)];
      current_statement__ = 108;
      stan::math::check_greater_or_equal(function__, "total_obs_full_links",
        total_obs_full_links, 1);
      current_statement__ = 109;
      stan::math::validate_non_negative_index("obs_full_start",
        "total_obs_patterns + 1", (total_obs_patterns + 1));
      current_statement__ = 110;
      context__.validate_dims("data initialization", "obs_full_start", "int",
        std::vector<size_t>{static_cast<size_t>((total_obs_patterns + 1))});
      obs_full_start = std::vector<int>((total_obs_patterns + 1),
                         std::numeric_limits<int>::min());
      current_statement__ = 110;
      obs_full_start = context__.vals_i("obs_full_start");
      current_statement__ = 110;
      stan::math::check_greater_or_equal(function__, "obs_full_start",
        obs_full_start, 1);
      current_statement__ = 111;
      stan::math::validate_non_negative_index("obs_full_index",
        "total_obs_full_links", total_obs_full_links);
      current_statement__ = 112;
      context__.validate_dims("data initialization", "obs_full_index", "int",
        std::vector<size_t>{static_cast<size_t>(total_obs_full_links)});
      obs_full_index = std::vector<int>(total_obs_full_links,
                         std::numeric_limits<int>::min());
      current_statement__ = 112;
      obs_full_index = context__.vals_i("obs_full_index");
      current_statement__ = 112;
      stan::math::check_greater_or_equal(function__, "obs_full_index",
        obs_full_index, 1);
      current_statement__ = 113;
      stan::math::validate_non_negative_index("delta_prior_mu",
        "total_delta_free", total_delta_free);
      current_statement__ = 114;
      context__.validate_dims("data initialization", "delta_prior_mu",
        "double", std::vector<size_t>{static_cast<size_t>(total_delta_free)});
      delta_prior_mu_data__ = Eigen::Matrix<double,-1,1>::Constant(total_delta_free,
                                std::numeric_limits<double>::quiet_NaN());
      new (&delta_prior_mu)
        Eigen::Map<Eigen::Matrix<double,-1,1>>(delta_prior_mu_data__.data(),
        total_delta_free);
      {
        std::vector<local_scalar_t__> delta_prior_mu_flat__;
        current_statement__ = 114;
        delta_prior_mu_flat__ = context__.vals_r("delta_prior_mu");
        current_statement__ = 114;
        pos__ = 1;
        current_statement__ = 114;
        for (int sym1__ = 1; sym1__ <= total_delta_free; ++sym1__) {
          current_statement__ = 114;
          stan::model::assign(delta_prior_mu, delta_prior_mu_flat__[(pos__ -
            1)], "assigning variable delta_prior_mu",
            stan::model::index_uni(sym1__));
          current_statement__ = 114;
          pos__ = (pos__ + 1);
        }
      }
      current_statement__ = 115;
      context__.validate_dims("data initialization", "delta_prior_sigma",
        "double", std::vector<size_t>{});
      delta_prior_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 115;
      delta_prior_sigma = context__.vals_r("delta_prior_sigma")[(1 - 1)];
      current_statement__ = 115;
      stan::math::check_greater_or_equal(function__, "delta_prior_sigma",
        delta_prior_sigma, 0);
      current_statement__ = 116;
      context__.validate_dims("data initialization", "pi_prior_alpha",
        "double", std::vector<size_t>{});
      pi_prior_alpha = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 116;
      pi_prior_alpha = context__.vals_r("pi_prior_alpha")[(1 - 1)];
      current_statement__ = 116;
      stan::math::check_greater_or_equal(function__, "pi_prior_alpha",
        pi_prior_alpha, 0);
      current_statement__ = 117;
      stan::math::validate_non_negative_index("blk_off", "B", B);
      current_statement__ = 118;
      blk_off = std::vector<int>(B, std::numeric_limits<int>::min());
      {
        int cum = std::numeric_limits<int>::min();
        current_statement__ = 119;
        cum = 1;
        current_statement__ = 123;
        for (int b = 1; b <= B; ++b) {
          current_statement__ = 120;
          stan::model::assign(blk_off, cum, "assigning variable blk_off",
            stan::model::index_uni(b));
          current_statement__ = 121;
          cum = (cum + (C *
            stan::model::rvalue(n_obs, "n_obs", stan::model::index_uni(b))));
        }
      }
      current_statement__ = 118;
      stan::math::check_greater_or_equal(function__, "blk_off", blk_off, 1);
      current_statement__ = 125;
      stan::math::validate_non_negative_index("delta_free",
        "total_delta_free", total_delta_free);
      current_statement__ = 126;
      stan::math::validate_positive_index("pi", "C", C);
      current_statement__ = 127;
      stan::math::validate_non_negative_index("delta", "total_delta_len",
        total_delta_len);
      current_statement__ = 128;
      log_prob_flat_1dim__ = std::numeric_limits<int>::min();
      current_statement__ = 128;
      log_prob_flat_1dim__ = (C * total_obs_patterns);
      current_statement__ = 128;
      stan::math::validate_non_negative_index("log_prob_flat",
        "C * total_obs_patterns", log_prob_flat_1dim__);
      current_statement__ = 129;
      stan::math::validate_non_negative_index("class_prob_group", "C", C);
      current_statement__ = 130;
      stan::math::validate_non_negative_index("class_prob_group", "G", G);
      current_statement__ = 131;
      stan::math::validate_non_negative_index("log_lik_group", "G", G);
    } catch (const std::exception& e) {
      stan::lang::rethrow_located(e, locations_array__[current_statement__]);
    }
    num_params_r__ = total_delta_free + (C - 1);
  }
  inline std::string model_name() const final {
    return "model_FCGDINA";
  }
  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_FCGDINA_namespace::log_prob";
    // suppress unused var warning
    (void) function__;
    try {
      Eigen::Matrix<local_scalar_t__,-1,1> delta_free =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(total_delta_free,
          DUMMY_VAR__);
      current_statement__ = 1;
      delta_free = in__.template read<
                     Eigen::Matrix<local_scalar_t__,-1,1>>(total_delta_free);
      Eigen::Matrix<local_scalar_t__,-1,1> pi =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(C, DUMMY_VAR__);
      current_statement__ = 2;
      pi = in__.template read_constrain_simplex<
             Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(lp__, C);
      Eigen::Matrix<local_scalar_t__,-1,1> delta =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(total_delta_len,
          DUMMY_VAR__);
      current_statement__ = 3;
      stan::model::assign(delta,
        stan::math::multiply(delta_basis, delta_free),
        "assigning variable delta");
      Eigen::Matrix<local_scalar_t__,-1,1> log_prob_flat =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(log_prob_flat_1dim__,
          DUMMY_VAR__);
      {
        int pos = std::numeric_limits<int>::min();
        current_statement__ = 7;
        pos = 1;
        current_statement__ = 14;
        for (int b = 1; b <= B; ++b) {
          int n_obs_b = std::numeric_limits<int>::min();
          current_statement__ = 8;
          n_obs_b = stan::model::rvalue(n_obs, "n_obs",
                      stan::model::index_uni(b));
          current_statement__ = 9;
          stan::math::validate_non_negative_index("block_probs",
            "C * n_obs_b", (C * n_obs_b));
          Eigen::Matrix<local_scalar_t__,-1,1> block_probs =
            Eigen::Matrix<local_scalar_t__,-1,1>::Constant((C * n_obs_b),
              DUMMY_VAR__);
          current_statement__ = 10;
          stan::model::assign(block_probs,
            fcgdina_block_log_probs(
              stan::model::rvalue(n_items, "n_items",
                stan::model::index_uni(b)),
              stan::model::rvalue(n_total, "n_total",
                stan::model::index_uni(b)),
              stan::model::rvalue(total_start, "total_start",
                stan::model::index_uni(b)), n_obs_b,
              stan::model::rvalue(obs_pattern_start, "obs_pattern_start",
                stan::model::index_uni(b)),
              stan::model::rvalue(item_start, "item_start",
                stan::model::index_uni(b)), C, flat_design, design_rows,
              design_cols, design_offset, delta_offset, class_map, delta,
              block_items, patterns_total, obs_full_start, obs_full_index,
              pstream__), "assigning variable block_probs");
          current_statement__ = 11;
          stan::model::assign(log_prob_flat, block_probs,
            "assigning variable log_prob_flat",
            stan::model::index_min_max(pos, ((pos + (C * n_obs_b)) - 1)));
          current_statement__ = 12;
          pos = (pos + (C * n_obs_b));
        }
      }
      {
        current_statement__ = 38;
        lp_accum__.add(stan::math::normal_lpdf<propto__>(delta_free,
                         delta_prior_mu, delta_prior_sigma));
        current_statement__ = 39;
        lp_accum__.add(stan::math::dirichlet_lpdf<propto__>(pi,
                         stan::math::rep_vector(pi_prior_alpha, C)));
        {
          current_statement__ = 40;
          stan::math::validate_non_negative_index("log_pi", "C", C);
          Eigen::Matrix<local_scalar_t__,-1,1> log_pi =
            Eigen::Matrix<local_scalar_t__,-1,1>::Constant(C, DUMMY_VAR__);
          current_statement__ = 41;
          stan::model::assign(log_pi, stan::math::log(pi),
            "assigning variable log_pi");
          current_statement__ = 54;
          for (int g = 1; g <= G; ++g) {
            current_statement__ = 42;
            stan::math::validate_non_negative_index("class_lp", "C", C);
            Eigen::Matrix<local_scalar_t__,-1,1> class_lp =
              Eigen::Matrix<local_scalar_t__,-1,1>::Constant(C, DUMMY_VAR__);
            current_statement__ = 43;
            stan::model::assign(class_lp, log_pi,
              "assigning variable class_lp");
            current_statement__ = 51;
            for (int b = 1; b <= B; ++b) {
              int n_obs_b = std::numeric_limits<int>::min();
              current_statement__ = 44;
              n_obs_b = stan::model::rvalue(n_obs, "n_obs",
                          stan::model::index_uni(b));
              int base = std::numeric_limits<int>::min();
              current_statement__ = 45;
              base = stan::model::rvalue(blk_off, "blk_off",
                       stan::model::index_uni(b));
              int y_gb = std::numeric_limits<int>::min();
              current_statement__ = 46;
              y_gb = stan::model::rvalue(y_unique, "y_unique",
                       stan::model::index_uni(g), stan::model::index_uni(b));
              current_statement__ = 49;
              for (int cls = 1; cls <= C; ++cls) {
                current_statement__ = 47;
                stan::model::assign(class_lp,
                  (stan::model::rvalue(class_lp, "class_lp",
                     stan::model::index_uni(cls)) +
                  stan::model::rvalue(log_prob_flat, "log_prob_flat",
                    stan::model::index_uni((((base + ((cls - 1) * n_obs_b)) +
                      y_gb) - 1)))), "assigning variable class_lp",
                  stan::model::index_uni(cls));
              }
            }
            current_statement__ = 52;
            lp_accum__.add((stan::model::rvalue(y_count, "y_count",
                              stan::model::index_uni(g)) *
              stan::math::log_sum_exp(class_lp)));
          }
        }
      }
    } 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_FCGDINA_namespace::write_array";
    // suppress unused var warning
    (void) function__;
    try {
      Eigen::Matrix<double,-1,1> delta_free =
        Eigen::Matrix<double,-1,1>::Constant(total_delta_free,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 1;
      delta_free = in__.template read<
                     Eigen::Matrix<local_scalar_t__,-1,1>>(total_delta_free);
      Eigen::Matrix<double,-1,1> pi =
        Eigen::Matrix<double,-1,1>::Constant(C,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 2;
      pi = in__.template read_constrain_simplex<
             Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(lp__, C);
      Eigen::Matrix<double,-1,1> delta =
        Eigen::Matrix<double,-1,1>::Constant(total_delta_len,
          std::numeric_limits<double>::quiet_NaN());
      Eigen::Matrix<double,-1,1> log_prob_flat =
        Eigen::Matrix<double,-1,1>::Constant(log_prob_flat_1dim__,
          std::numeric_limits<double>::quiet_NaN());
      out__.write(delta_free);
      out__.write(pi);
      if (stan::math::logical_negation(
            (stan::math::primitive_value(emit_transformed_parameters__) ||
            stan::math::primitive_value(emit_generated_quantities__)))) {
        return ;
      }
      current_statement__ = 3;
      stan::model::assign(delta,
        stan::math::multiply(delta_basis, delta_free),
        "assigning variable delta");
      {
        int pos = std::numeric_limits<int>::min();
        current_statement__ = 7;
        pos = 1;
        current_statement__ = 14;
        for (int b = 1; b <= B; ++b) {
          int n_obs_b = std::numeric_limits<int>::min();
          current_statement__ = 8;
          n_obs_b = stan::model::rvalue(n_obs, "n_obs",
                      stan::model::index_uni(b));
          current_statement__ = 9;
          stan::math::validate_non_negative_index("block_probs",
            "C * n_obs_b", (C * n_obs_b));
          Eigen::Matrix<double,-1,1> block_probs =
            Eigen::Matrix<double,-1,1>::Constant((C * n_obs_b),
              std::numeric_limits<double>::quiet_NaN());
          current_statement__ = 10;
          stan::model::assign(block_probs,
            fcgdina_block_log_probs(
              stan::model::rvalue(n_items, "n_items",
                stan::model::index_uni(b)),
              stan::model::rvalue(n_total, "n_total",
                stan::model::index_uni(b)),
              stan::model::rvalue(total_start, "total_start",
                stan::model::index_uni(b)), n_obs_b,
              stan::model::rvalue(obs_pattern_start, "obs_pattern_start",
                stan::model::index_uni(b)),
              stan::model::rvalue(item_start, "item_start",
                stan::model::index_uni(b)), C, flat_design, design_rows,
              design_cols, design_offset, delta_offset, class_map, delta,
              block_items, patterns_total, obs_full_start, obs_full_index,
              pstream__), "assigning variable block_probs");
          current_statement__ = 11;
          stan::model::assign(log_prob_flat, block_probs,
            "assigning variable log_prob_flat",
            stan::model::index_min_max(pos, ((pos + (C * n_obs_b)) - 1)));
          current_statement__ = 12;
          pos = (pos + (C * n_obs_b));
        }
      }
      if (emit_transformed_parameters__) {
        out__.write(delta);
        out__.write(log_prob_flat);
      }
      if (stan::math::logical_negation(emit_generated_quantities__)) {
        return ;
      }
      Eigen::Matrix<double,-1,-1> class_prob_group =
        Eigen::Matrix<double,-1,-1>::Constant(C, G,
          std::numeric_limits<double>::quiet_NaN());
      Eigen::Matrix<double,-1,1> log_lik_group =
        Eigen::Matrix<double,-1,1>::Constant(G,
          std::numeric_limits<double>::quiet_NaN());
      {
        current_statement__ = 16;
        stan::math::validate_non_negative_index("log_pi", "C", C);
        Eigen::Matrix<double,-1,1> log_pi =
          Eigen::Matrix<double,-1,1>::Constant(C,
            std::numeric_limits<double>::quiet_NaN());
        current_statement__ = 17;
        stan::model::assign(log_pi, stan::math::log(pi),
          "assigning variable log_pi");
        current_statement__ = 36;
        for (int g = 1; g <= G; ++g) {
          current_statement__ = 18;
          stan::math::validate_non_negative_index("lp_g", "C", C);
          Eigen::Matrix<double,-1,1> lp_g =
            Eigen::Matrix<double,-1,1>::Constant(C,
              std::numeric_limits<double>::quiet_NaN());
          current_statement__ = 19;
          stan::model::assign(lp_g, log_pi, "assigning variable lp_g");
          current_statement__ = 27;
          for (int b = 1; b <= B; ++b) {
            int n_obs_b = std::numeric_limits<int>::min();
            current_statement__ = 20;
            n_obs_b = stan::model::rvalue(n_obs, "n_obs",
                        stan::model::index_uni(b));
            int base = std::numeric_limits<int>::min();
            current_statement__ = 21;
            base = stan::model::rvalue(blk_off, "blk_off",
                     stan::model::index_uni(b));
            int y_gb = std::numeric_limits<int>::min();
            current_statement__ = 22;
            y_gb = stan::model::rvalue(y_unique, "y_unique",
                     stan::model::index_uni(g), stan::model::index_uni(b));
            current_statement__ = 25;
            for (int cls = 1; cls <= C; ++cls) {
              current_statement__ = 23;
              stan::model::assign(lp_g,
                (stan::model::rvalue(lp_g, "lp_g",
                   stan::model::index_uni(cls)) +
                stan::model::rvalue(log_prob_flat, "log_prob_flat",
                  stan::model::index_uni((((base + ((cls - 1) * n_obs_b)) +
                    y_gb) - 1)))), "assigning variable lp_g",
                stan::model::index_uni(cls));
            }
          }
          {
            current_statement__ = 28;
            stan::math::validate_non_negative_index("prob_g", "C", C);
            Eigen::Matrix<double,-1,1> prob_g =
              Eigen::Matrix<double,-1,1>::Constant(C,
                std::numeric_limits<double>::quiet_NaN());
            current_statement__ = 29;
            stan::model::assign(prob_g, stan::math::softmax(lp_g),
              "assigning variable prob_g");
            current_statement__ = 30;
            stan::model::assign(log_lik_group, stan::math::log_sum_exp(lp_g),
              "assigning variable log_lik_group", stan::model::index_uni(g));
            current_statement__ = 33;
            for (int cls = 1; cls <= C; ++cls) {
              current_statement__ = 31;
              stan::model::assign(class_prob_group,
                stan::model::rvalue(prob_g, "prob_g",
                  stan::model::index_uni(cls)),
                "assigning variable class_prob_group",
                stan::model::index_uni(cls), stan::model::index_uni(g));
            }
          }
        }
      }
      out__.write(class_prob_group);
      out__.write(log_lik_group);
    } 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> delta_free =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(total_delta_free,
          DUMMY_VAR__);
      current_statement__ = 1;
      stan::model::assign(delta_free,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(total_delta_free),
        "assigning variable delta_free");
      out__.write(delta_free);
      Eigen::Matrix<local_scalar_t__,-1,1> pi =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(C, DUMMY_VAR__);
      current_statement__ = 2;
      stan::model::assign(pi,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(C),
        "assigning variable pi");
      out__.write_free_simplex(pi);
    } 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", "delta_free",
        "double", std::vector<size_t>{static_cast<size_t>(total_delta_free)});
      current_statement__ = 2;
      context__.validate_dims("parameter initialization", "pi", "double",
        std::vector<size_t>{static_cast<size_t>(C)});
      int pos__ = std::numeric_limits<int>::min();
      pos__ = 1;
      Eigen::Matrix<local_scalar_t__,-1,1> delta_free =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(total_delta_free,
          DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> delta_free_flat__;
        current_statement__ = 1;
        delta_free_flat__ = context__.vals_r("delta_free");
        current_statement__ = 1;
        pos__ = 1;
        current_statement__ = 1;
        for (int sym1__ = 1; sym1__ <= total_delta_free; ++sym1__) {
          current_statement__ = 1;
          stan::model::assign(delta_free, delta_free_flat__[(pos__ - 1)],
            "assigning variable delta_free", stan::model::index_uni(sym1__));
          current_statement__ = 1;
          pos__ = (pos__ + 1);
        }
      }
      out__.write(delta_free);
      Eigen::Matrix<local_scalar_t__,-1,1> pi =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(C, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> pi_flat__;
        current_statement__ = 2;
        pi_flat__ = context__.vals_r("pi");
        current_statement__ = 2;
        pos__ = 1;
        current_statement__ = 2;
        for (int sym1__ = 1; sym1__ <= C; ++sym1__) {
          current_statement__ = 2;
          stan::model::assign(pi, pi_flat__[(pos__ - 1)],
            "assigning variable pi", stan::model::index_uni(sym1__));
          current_statement__ = 2;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_simplex(pi);
    } 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>{"delta_free", "pi"};
    if (emit_transformed_parameters__) {
      std::vector<std::string> temp{"delta", "log_prob_flat"};
      names__.reserve(names__.size() + temp.size());
      names__.insert(names__.end(), temp.begin(), temp.end());
    }
    if (emit_generated_quantities__) {
      std::vector<std::string> temp{"class_prob_group", "log_lik_group"};
      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>(
                                                                    total_delta_free)},
                std::vector<size_t>{static_cast<size_t>(C)}};
    if (emit_transformed_parameters__) {
      std::vector<std::vector<size_t>>
        temp{std::vector<size_t>{static_cast<size_t>(total_delta_len)},
             std::vector<size_t>{static_cast<size_t>(log_prob_flat_1dim__)}};
      dimss__.reserve(dimss__.size() + temp.size());
      dimss__.insert(dimss__.end(), temp.begin(), temp.end());
    }
    if (emit_generated_quantities__) {
      std::vector<std::vector<size_t>>
        temp{std::vector<size_t>{static_cast<size_t>(C),
               static_cast<size_t>(G)},
             std::vector<size_t>{static_cast<size_t>(G)}};
      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__ <= total_delta_free; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta_free" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= C; ++sym1__) {
      param_names__.emplace_back(std::string() + "pi" + '.' +
        std::to_string(sym1__));
    }
    if (emit_transformed_parameters__) {
      for (int sym1__ = 1; sym1__ <= total_delta_len; ++sym1__) {
        param_names__.emplace_back(std::string() + "delta" + '.' +
          std::to_string(sym1__));
      }
      for (int sym1__ = 1; sym1__ <= log_prob_flat_1dim__; ++sym1__) {
        param_names__.emplace_back(std::string() + "log_prob_flat" + '.' +
          std::to_string(sym1__));
      }
    }
    if (emit_generated_quantities__) {
      for (int sym1__ = 1; sym1__ <= G; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= C; ++sym2__) {
          param_names__.emplace_back(std::string() + "class_prob_group" + '.'
            + std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= G; ++sym1__) {
        param_names__.emplace_back(std::string() + "log_lik_group" + '.' +
          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__ <= total_delta_free; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta_free" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= (C - 1); ++sym1__) {
      param_names__.emplace_back(std::string() + "pi" + '.' +
        std::to_string(sym1__));
    }
    if (emit_transformed_parameters__) {
      for (int sym1__ = 1; sym1__ <= total_delta_len; ++sym1__) {
        param_names__.emplace_back(std::string() + "delta" + '.' +
          std::to_string(sym1__));
      }
      for (int sym1__ = 1; sym1__ <= log_prob_flat_1dim__; ++sym1__) {
        param_names__.emplace_back(std::string() + "log_prob_flat" + '.' +
          std::to_string(sym1__));
      }
    }
    if (emit_generated_quantities__) {
      for (int sym1__ = 1; sym1__ <= G; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= C; ++sym2__) {
          param_names__.emplace_back(std::string() + "class_prob_group" + '.'
            + std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= G; ++sym1__) {
        param_names__.emplace_back(std::string() + "log_lik_group" + '.' +
          std::to_string(sym1__));
      }
    }
  }
  inline std::string get_constrained_sizedtypes() const {
    return std::string("[{\"name\":\"delta_free\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(total_delta_free) + "},\"block\":\"parameters\"},{\"name\":\"pi\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(C) + "},\"block\":\"parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(total_delta_len) + "},\"block\":\"transformed_parameters\"},{\"name\":\"log_prob_flat\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(log_prob_flat_1dim__) + "},\"block\":\"transformed_parameters\"},{\"name\":\"class_prob_group\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(C) + ",\"cols\":" + std::to_string(G) + "},\"block\":\"generated_quantities\"},{\"name\":\"log_lik_group\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(G) + "},\"block\":\"generated_quantities\"}]");
  }
  inline std::string get_unconstrained_sizedtypes() const {
    return std::string("[{\"name\":\"delta_free\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(total_delta_free) + "},\"block\":\"parameters\"},{\"name\":\"pi\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string((C -1)) + "},\"block\":\"parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(total_delta_len) + "},\"block\":\"transformed_parameters\"},{\"name\":\"log_prob_flat\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(log_prob_flat_1dim__) + "},\"block\":\"transformed_parameters\"},{\"name\":\"class_prob_group\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(C) + ",\"cols\":" + std::to_string(G) + "},\"block\":\"generated_quantities\"},{\"name\":\"log_lik_group\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(G) + "},\"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__ = (total_delta_free + C);
    const size_t num_transformed = emit_transformed_parameters *
      ((total_delta_len + log_prob_flat_1dim__));
    const size_t num_gen_quantities = emit_generated_quantities * (((C * G) +
      G));
    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__ = (total_delta_free + C);
    const size_t num_transformed = emit_transformed_parameters *
      ((total_delta_len + log_prob_flat_1dim__));
    const size_t num_gen_quantities = emit_generated_quantities * (((C * G) +
      G));
    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_FCGDINA_namespace::model_FCGDINA;
#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_FCGDINA_namespace::profiles__;
}
#endif
#endif
