// 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_FCGGUM_namespace {
using stan::model::model_base_crtp;
using namespace stan::math;
stan::math::profile_map profiles__;
static constexpr std::array<const char*, 241> locations_array__ =
  {" (found before start of program)",
  " (in 'string', line 193, column 2 to column 38)",
  " (in 'string', line 194, column 2 to column 44)",
  " (in 'string', line 195, column 2 to column 44)",
  " (in 'string', line 196, column 2 to column 29)",
  " (in 'string', line 197, column 2 to column 33)",
  " (in 'string', line 198, column 2 to column 31)",
  " (in 'string', line 201, column 2 to column 26)",
  " (in 'string', line 202, column 2 to column 21)",
  " (in 'string', line 203, column 2 to column 26)",
  " (in 'string', line 204, column 2 to column 21)",
  " (in 'string', line 282, column 2 to column 20)",
  " (in 'string', line 283, column 2 to column 24)",
  " (in 'string', line 207, column 4 to column 16)",
  " (in 'string', line 214, column 10 to column 24)",
  " (in 'string', line 213, column 15 to line 215, column 9)",
  " (in 'string', line 211, column 10 to column 32)",
  " (in 'string', line 212, column 10 to column 19)",
  " (in 'string', line 210, column 33 to line 213, column 9)",
  " (in 'string', line 210, column 8 to line 215, column 9)",
  " (in 'string', line 209, column 21 to line 216, column 7)",
  " (in 'string', line 209, column 6 to line 216, column 7)",
  " (in 'string', line 208, column 19 to line 217, column 5)",
  " (in 'string', line 208, column 4 to line 217, column 5)",
  " (in 'string', line 206, column 2 to line 218, column 3)",
  " (in 'string', line 221, column 4 to column 20)",
  " (in 'string', line 222, column 4 to column 20)",
  " (in 'string', line 232, column 10 to column 28)",
  " (in 'string', line 231, column 15 to line 233, column 9)",
  " (in 'string', line 229, column 10 to column 43)",
  " (in 'string', line 230, column 10 to column 23)",
  " (in 'string', line 228, column 41 to line 231, column 9)",
  " (in 'string', line 228, column 15 to line 233, column 9)",
  " (in 'string', line 226, column 10 to column 43)",
  " (in 'string', line 227, column 10 to column 23)",
  " (in 'string', line 225, column 33 to line 228, column 9)",
  " (in 'string', line 225, column 8 to line 233, column 9)",
  " (in 'string', line 224, column 21 to line 234, column 7)",
  " (in 'string', line 224, column 6 to line 234, column 7)",
  " (in 'string', line 223, column 19 to line 235, column 5)",
  " (in 'string', line 223, column 4 to line 235, column 5)",
  " (in 'string', line 220, column 2 to line 236, column 3)",
  " (in 'string', line 240, column 4 to column 20)",
  " (in 'string', line 241, column 4 to column 28)",
  " (in 'string', line 244, column 8 to column 24)",
  " (in 'string', line 243, column 6 to line 244, column 24)",
  " (in 'string', line 242, column 22 to line 245, column 5)",
  " (in 'string', line 242, column 4 to line 245, column 5)",
  " (in 'string', line 239, column 17 to line 246, column 3)",
  " (in 'string', line 239, column 2 to line 246, column 3)",
  " (in 'string', line 252, column 6 to column 50)",
  " (in 'string', line 250, column 6 to column 53)",
  " (in 'string', line 249, column 4 to line 252, column 50)",
  " (in 'string', line 248, column 17 to line 253, column 3)",
  " (in 'string', line 248, column 2 to line 253, column 3)",
  " (in 'string', line 287, column 4 to column 21)",
  " (in 'string', line 285, column 4 to column 53)",
  " (in 'string', line 284, column 2 to line 287, column 21)",
  " (in 'string', line 289, column 4 to line 298, column 6)",
  " (in 'string', line 288, column 23 to line 299, column 3)",
  " (in 'string', line 288, column 2 to line 299, column 3)",
  " (in 'string', line 257, column 2 to column 39)",
  " (in 'string', line 258, column 2 to column 52)",
  " (in 'string', line 259, column 2 to column 52)",
  " (in 'string', line 260, column 2 to column 43)",
  " (in 'string', line 262, column 4 to column 34)",
  " (in 'string', line 261, column 2 to line 262, column 34)",
  " (in 'string', line 264, column 4 to column 32)",
  " (in 'string', line 263, column 2 to line 264, column 32)",
  " (in 'string', line 269, column 4 to line 278, column 6)",
  " (in 'string', line 268, column 23 to line 279, column 3)",
  " (in 'string', line 268, column 2 to line 279, column 3)",
  " (in 'string', line 135, column 2 to column 21)",
  " (in 'string', line 136, column 2 to column 17)",
  " (in 'string', line 137, column 2 to column 17)",
  " (in 'string', line 138, column 2 to column 17)",
  " (in 'string', line 139, column 2 to column 17)",
  " (in 'string', line 140, column 2 to column 24)",
  " (in 'string', line 142, column 8 to column 13)",
  " (in 'string', line 142, column 2 to column 41)",
  " (in 'string', line 143, column 8 to column 13)",
  " (in 'string', line 143, column 2 to column 41)",
  " (in 'string', line 144, column 8 to column 13)",
  " (in 'string', line 144, column 2 to column 38)",
  " (in 'string', line 146, column 8 to column 9)",
  " (in 'string', line 146, column 2 to column 52)",
  " (in 'string', line 147, column 9 to column 10)",
  " (in 'string', line 147, column 12 to column 13)",
  " (in 'string', line 147, column 2 to column 24)",
  " (in 'string', line 149, column 8 to column 9)",
  " (in 'string', line 149, column 2 to column 36)",
  " (in 'string', line 150, column 8 to column 9)",
  " (in 'string', line 150, column 2 to column 41)",
  " (in 'string', line 151, column 2 to column 47)",
  " (in 'string', line 152, column 8 to column 25)",
  " (in 'string', line 152, column 2 to column 61)",
  " (in 'string', line 153, column 8 to column 13)",
  " (in 'string', line 153, column 2 to column 40)",
  " (in 'string', line 155, column 8 to column 9)",
  " (in 'string', line 155, column 2 to column 36)",
  " (in 'string', line 156, column 2 to column 47)",
  " (in 'string', line 157, column 8 to column 25)",
  " (in 'string', line 157, column 2 to column 55)",
  " (in 'string', line 158, column 8 to column 13)",
  " (in 'string', line 158, column 2 to column 41)",
  " (in 'string', line 160, column 8 to column 9)",
  " (in 'string', line 160, column 2 to column 34)",
  " (in 'string', line 161, column 2 to column 45)",
  " (in 'string', line 162, column 8 to column 23)",
  " (in 'string', line 162, column 2 to column 51)",
  " (in 'string', line 163, column 8 to column 13)",
  " (in 'string', line 163, column 2 to column 39)",
  " (in 'string', line 164, column 8 to column 9)",
  " (in 'string', line 164, column 2 to column 35)",
  " (in 'string', line 166, column 2 to column 12)",
  " (in 'string', line 167, column 2 to column 24)",
  " (in 'string', line 168, column 2 to column 20)",
  " (in 'string', line 169, column 2 to column 32)",
  " (in 'string', line 170, column 2 to column 20)",
  " (in 'string', line 171, column 2 to column 32)",
  " (in 'string', line 172, column 2 to column 14)",
  " (in 'string', line 173, column 2 to column 26)",
  " (in 'string', line 174, column 9 to column 10)",
  " (in 'string', line 174, column 2 to column 21)",
  " (in 'string', line 177, column 2 to column 22)",
  " (in 'string', line 178, column 2 to column 25)",
  " (in 'string', line 179, column 2 to column 25)",
  " (in 'string', line 183, column 8 to column 25)",
  " (in 'string', line 187, column 10 to column 30)",
  " (in 'string', line 185, column 10 to column 30)",
  " (in 'string', line 184, column 8 to line 187, column 30)",
  " (in 'string', line 182, column 31 to line 188, column 7)",
  " (in 'string', line 182, column 6 to line 188, column 7)",
  " (in 'string', line 181, column 19 to line 189, column 5)",
  " (in 'string', line 181, column 4 to line 189, column 5)",
  " (in 'string', line 180, column 17 to line 190, column 3)",
  " (in 'string', line 180, column 2 to line 190, column 3)",
  " (in 'string', line 193, column 18 to column 29)",
  " (in 'string', line 194, column 18 to column 32)",
  " (in 'string', line 195, column 18 to column 32)",
  " (in 'string', line 196, column 18 to column 19)",
  " (in 'string', line 197, column 23 to column 24)",
  " (in 'string', line 198, column 8 to column 9)",
  " (in 'string', line 198, column 18 to column 19)",
  " (in 'string', line 201, column 18 to column 19)",
  " (in 'string', line 201, column 21 to column 22)",
  " (in 'string', line 202, column 9 to column 10)",
  " (in 'string', line 202, column 12 to column 13)",
  " (in 'string', line 203, column 9 to column 10)",
  " (in 'string', line 203, column 12 to column 20)",
  " (in 'string', line 204, column 9 to column 10)",
  " (in 'string', line 204, column 12 to column 13)",
  " (in 'string', line 282, column 9 to column 10)",
  " (in 'string', line 282, column 12 to column 13)",
  " (in 'string', line 283, column 9 to column 14)",
  " (in 'string', line 31, column 4 to column 23)",
  " (in 'string', line 32, column 11 to column 12)",
  " (in 'string', line 32, column 4 to column 24)",
  " (in 'string', line 33, column 11 to column 12)",
  " (in 'string', line 33, column 4 to column 27)",
  " (in 'string', line 35, column 6 to column 50)",
  " (in 'string', line 36, column 6 to column 31)",
  " (in 'string', line 37, column 6 to column 26)",
  " (in 'string', line 38, column 6 to column 32)",
  " (in 'string', line 39, column 6 to column 20)",
  " (in 'string', line 41, column 8 to column 70)",
  " (in 'string', line 40, column 6 to line 41, column 70)",
  " (in 'string', line 42, column 6 to column 34)",
  " (in 'string', line 43, column 6 to column 23)",
  " (in 'string', line 44, column 13 to column 15)",
  " (in 'string', line 44, column 6 to column 24)",
  " (in 'string', line 46, column 8 to column 42)",
  " (in 'string', line 47, column 8 to line 50, column 10)",
  " (in 'string', line 45, column 24 to line 51, column 7)",
  " (in 'string', line 45, column 6 to line 51, column 7)",
  " (in 'string', line 53, column 8 to column 58)",
  " (in 'string', line 54, column 8 to column 61)",
  " (in 'string', line 55, column 8 to column 36)",
  " (in 'string', line 56, column 8 to column 41)",
  " (in 'string', line 52, column 6 to line 57, column 7)",
  " (in 'string', line 34, column 19 to line 58, column 5)",
  " (in 'string', line 34, column 4 to line 58, column 5)",
  " (in 'string', line 59, column 4 to column 27)",
  " (in 'string', line 60, column 11 to column 16)",
  " (in 'string', line 60, column 4 to column 27)",
  " (in 'string', line 61, column 4 to column 33)",
  " (in 'string', line 63, column 6 to column 18)",
  " (in 'string', line 66, column 10 to column 36)",
  " (in 'string', line 67, column 17 to column 18)",
  " (in 'string', line 67, column 10 to column 28)",
  " (in 'string', line 68, column 10 to column 29)",
  " (in 'string', line 70, column 12 to column 36)",
  " (in 'string', line 71, column 12 to column 74)",
  " (in 'string', line 72, column 12 to column 45)",
  " (in 'string', line 75, column 16 to column 74)",
  " (in 'string', line 76, column 16 to column 44)",
  " (in 'string', line 74, column 26 to line 77, column 15)",
  " (in 'string', line 74, column 14 to line 77, column 15)",
  " (in 'string', line 73, column 29 to line 78, column 13)",
  " (in 'string', line 73, column 12 to line 78, column 13)",
  " (in 'string', line 79, column 12 to column 34)",
  " (in 'string', line 81, column 14 to column 31)",
  " (in 'string', line 80, column 12 to line 81, column 31)",
  " (in 'string', line 69, column 35 to line 82, column 11)",
  " (in 'string', line 69, column 10 to line 82, column 11)",
  " (in 'string', line 83, column 10 to column 60)",
  " (in 'string', line 65, column 31 to line 84, column 9)",
  " (in 'string', line 65, column 8 to line 84, column 9)",
  " (in 'string', line 64, column 17 to line 85, column 7)",
  " (in 'string', line 64, column 6 to line 85, column 7)",
  " (in 'string', line 86, column 6 to column 23)",
  " (in 'string', line 62, column 23 to line 87, column 5)",
  " (in 'string', line 62, column 4 to line 87, column 5)",
  " (in 'string', line 88, column 4 to column 26)",
  " (in 'string', line 89, column 4 to column 31)",
  " (in 'string', line 90, column 4 to column 24)",
  " (in 'string', line 91, column 4 to column 38)",
  " (in 'string', line 96, column 8 to column 27)",
  " (in 'string', line 104, column 10 to column 62)",
  " (in 'string', line 105, column 10 to column 66)",
  " (in 'string', line 106, column 10 to column 44)",
  " (in 'string', line 103, column 15 to line 107, column 9)",
  " (in 'string', line 98, column 10 to column 62)",
  " (in 'string', line 99, column 10 to column 70)",
  " (in 'string', line 100, column 10 to column 66)",
  " (in 'string', line 101, column 10 to column 70)",
  " (in 'string', line 102, column 10 to column 66)",
  " (in 'string', line 97, column 23 to line 103, column 9)",
  " (in 'string', line 97, column 8 to line 107, column 9)",
  " (in 'string', line 109, column 10 to column 52)",
  " (in 'string', line 108, column 8 to line 109, column 52)",
  " (in 'string', line 95, column 25 to line 110, column 7)",
  " (in 'string', line 95, column 6 to line 110, column 7)",
  " (in 'string', line 111, column 6 to column 38)",
  " (in 'string', line 94, column 11 to line 112, column 5)",
  " (in 'string', line 93, column 6 to column 47)",
  " (in 'string', line 92, column 19 to line 94, column 5)",
  " (in 'string', line 92, column 4 to line 112, column 5)",
  " (in 'string', line 30, column 4 to line 113, column 3)",
  " (in 'string', line 125, column 4 to line 130, column 6)",
  " (in 'string', line 124, column 4 to line 131, column 3)"};
template <typename T3__, typename T4__, typename T5__, typename T6__,
          stan::require_all_t<stan::is_eigen_matrix_dynamic<T3__>,
                              stan::is_vt_not_complex<T3__>,
                              stan::is_eigen_matrix_dynamic<T4__>,
                              stan::is_vt_not_complex<T4__>,
                              stan::is_eigen_matrix_dynamic<T5__>,
                              stan::is_vt_not_complex<T5__>,
                              stan::is_eigen_matrix_dynamic<T6__>,
                              stan::is_vt_not_complex<T6__>>* = nullptr>
stan::promote_args_t<stan::base_type_t<T3__>, stan::base_type_t<T4__>,
  stan::base_type_t<T5__>, stan::base_type_t<T6__>>
fcggum_obs_ll(const int& p, const int& b, const int& y_obs, const T3__&
              theta_arg__, const T4__& a_arg__, const T5__& delta_arg__,
              const T6__& tau_arg__, const int& D, const std::vector<int>&
              n_items, const std::vector<int>& fc_type,
              const std::vector<int>& block_items, const std::vector<int>&
              item_start, const std::vector<int>& length_poly,
              const std::vector<int>& n_total, const std::vector<int>&
              patterns_total, const std::vector<int>& total_start,
              const std::vector<int>& patterns_obs, const std::vector<int>&
              obs_start, const std::vector<int>& fc_len, std::ostream*
              pstream__);
template <bool propto__, typename T3__, typename T4__, typename T5__,
          typename T6__, typename T_lp__, typename T_lp_accum__,
          stan::require_all_t<stan::is_eigen_matrix_dynamic<T3__>,
                              stan::is_vt_not_complex<T3__>,
                              stan::is_eigen_matrix_dynamic<T4__>,
                              stan::is_vt_not_complex<T4__>,
                              stan::is_eigen_matrix_dynamic<T5__>,
                              stan::is_vt_not_complex<T5__>,
                              stan::is_eigen_matrix_dynamic<T6__>,
                              stan::is_vt_not_complex<T6__>>* = nullptr>
void
fcggum_obs_lp(const int& p, const int& b, const int& y_obs, const T3__&
              theta_arg__, const T4__& a_arg__, const T5__& delta_arg__,
              const T6__& tau_arg__, const int& D, const std::vector<int>&
              n_items, const std::vector<int>& fc_type,
              const std::vector<int>& block_items, const std::vector<int>&
              item_start, const std::vector<int>& length_poly,
              const std::vector<int>& n_total, const std::vector<int>&
              patterns_total, const std::vector<int>& total_start,
              const std::vector<int>& patterns_obs, const std::vector<int>&
              obs_start, const std::vector<int>& fc_len, T_lp__& lp__,
              T_lp_accum__& lp_accum__, std::ostream* pstream__);
template <typename T3__, typename T4__, typename T5__, typename T6__,
          stan::require_all_t<stan::is_eigen_matrix_dynamic<T3__>,
                              stan::is_vt_not_complex<T3__>,
                              stan::is_eigen_matrix_dynamic<T4__>,
                              stan::is_vt_not_complex<T4__>,
                              stan::is_eigen_matrix_dynamic<T5__>,
                              stan::is_vt_not_complex<T5__>,
                              stan::is_eigen_matrix_dynamic<T6__>,
                              stan::is_vt_not_complex<T6__>>*>
stan::promote_args_t<stan::base_type_t<T3__>, stan::base_type_t<T4__>,
  stan::base_type_t<T5__>, stan::base_type_t<T6__>>
fcggum_obs_ll(const int& p, const int& b, const int& y_obs, const T3__&
              theta_arg__, const T4__& a_arg__, const T5__& delta_arg__,
              const T6__& tau_arg__, const int& D, const std::vector<int>&
              n_items, const std::vector<int>& fc_type,
              const std::vector<int>& block_items, const std::vector<int>&
              item_start, const std::vector<int>& length_poly,
              const std::vector<int>& n_total, const std::vector<int>&
              patterns_total, const std::vector<int>& total_start,
              const std::vector<int>& patterns_obs, const std::vector<int>&
              obs_start, const std::vector<int>& fc_len, std::ostream*
              pstream__) {
  using local_scalar_t__ = stan::promote_args_t<stan::base_type_t<T3__>,
                             stan::base_type_t<T4__>,
                             stan::base_type_t<T5__>,
                             stan::base_type_t<T6__>>;
  int current_statement__ = 0;
  const auto& theta = stan::math::to_ref(theta_arg__);
  const auto& a = stan::math::to_ref(a_arg__);
  const auto& delta = stan::math::to_ref(delta_arg__);
  const auto& tau = stan::math::to_ref(tau_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 K = std::numeric_limits<int>::min();
    current_statement__ = 155;
    K = stan::model::rvalue(n_items, "n_items", stan::model::index_uni(b));
    current_statement__ = 156;
    stan::math::validate_non_negative_index("log_agree", "K", K);
    Eigen::Matrix<local_scalar_t__,-1,1> log_agree =
      Eigen::Matrix<local_scalar_t__,-1,1>::Constant(K, DUMMY_VAR__);
    current_statement__ = 158;
    stan::math::validate_non_negative_index("log_disagree", "K", K);
    Eigen::Matrix<local_scalar_t__,-1,1> log_disagree =
      Eigen::Matrix<local_scalar_t__,-1,1>::Constant(K, DUMMY_VAR__);
    current_statement__ = 181;
    for (int k = 1; k <= K; ++k) {
      int gi = std::numeric_limits<int>::min();
      current_statement__ = 160;
      gi = stan::model::rvalue(block_items, "block_items",
             stan::model::index_uni(
               ((stan::model::rvalue(item_start, "item_start",
                   stan::model::index_uni(b)) + k) - 1)));
      int Ki = std::numeric_limits<int>::min();
      current_statement__ = 161;
      Ki = stan::model::rvalue(length_poly, "length_poly",
             stan::model::index_uni(gi));
      int Mi = std::numeric_limits<int>::min();
      current_statement__ = 162;
      Mi = ((2 * Ki) - 1);
      local_scalar_t__ sum_a_i = DUMMY_VAR__;
      current_statement__ = 163;
      sum_a_i = stan::math::sum(
                  stan::model::rvalue(a, "a", stan::model::index_uni(gi)));
      local_scalar_t__ r_sq = DUMMY_VAR__;
      current_statement__ = 164;
      r_sq = 0;
      current_statement__ = 166;
      for (int d = 1; d <= D; ++d) {
        current_statement__ = 165;
        r_sq = (r_sq +
          (stan::math::square(
             stan::model::rvalue(a, "a", stan::model::index_uni(gi),
               stan::model::index_uni(d)))
          *
          stan::math::square(
            (stan::model::rvalue(theta, "theta", stan::model::index_uni(p),
               stan::model::index_uni(d)) -
            stan::model::rvalue(delta, "delta", stan::model::index_uni(gi),
              stan::model::index_uni(d))))));
      }
      local_scalar_t__ r = DUMMY_VAR__;
      current_statement__ = 167;
      r = stan::math::sqrt((r_sq + 1e-12));
      local_scalar_t__ cum_psi = DUMMY_VAR__;
      current_statement__ = 168;
      cum_psi = 0;
      current_statement__ = 169;
      stan::math::validate_non_negative_index("lp_cat", "Ki", Ki);
      Eigen::Matrix<local_scalar_t__,-1,1> lp_cat =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(Ki, DUMMY_VAR__);
      current_statement__ = 174;
      for (int cat = 1; cat <= Ki; ++cat) {
        current_statement__ = 171;
        cum_psi = (cum_psi +
          (stan::model::rvalue(tau, "tau", stan::model::index_uni(gi),
             stan::model::index_uni(cat))
          * sum_a_i));
        current_statement__ = 172;
        stan::model::assign(lp_cat,
          stan::math::log_sum_exp((((cat - 1) * r) - cum_psi), ((((Mi - cat)
            + 1) * r) - cum_psi)), "assigning variable lp_cat",
          stan::model::index_uni(cat));
      }
      {
        local_scalar_t__ p_raw = DUMMY_VAR__;
        current_statement__ = 175;
        p_raw = stan::math::exp(
                  (stan::model::rvalue(lp_cat, "lp_cat",
                     stan::model::index_uni(2)) -
                  stan::math::log_sum_exp(lp_cat)));
        local_scalar_t__ p_agree = DUMMY_VAR__;
        current_statement__ = 176;
        p_agree = stan::math::fmin((1.0 - 1e-12),
                    stan::math::fmax(1e-12, p_raw));
        current_statement__ = 177;
        stan::model::assign(log_agree, stan::math::log(p_agree),
          "assigning variable log_agree", stan::model::index_uni(k));
        current_statement__ = 178;
        stan::model::assign(log_disagree, stan::math::log1m(p_agree),
          "assigning variable log_disagree", stan::model::index_uni(k));
      }
    }
    int n_tot = std::numeric_limits<int>::min();
    current_statement__ = 182;
    n_tot = stan::model::rvalue(n_total, "n_total", stan::model::index_uni(b));
    current_statement__ = 183;
    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(n_tot, DUMMY_VAR__);
    int t_start = std::numeric_limits<int>::min();
    current_statement__ = 185;
    t_start = stan::model::rvalue(total_start, "total_start",
                stan::model::index_uni(b));
    current_statement__ = 212;
    for (int t = 1; t <= n_tot; ++t) {
      local_scalar_t__ lp = DUMMY_VAR__;
      current_statement__ = 186;
      lp = 0;
      current_statement__ = 209;
      if (stan::math::logical_gt(K, 1)) {
        current_statement__ = 207;
        for (int pos = 1; pos <= (K - 1); ++pos) {
          int rem_len = std::numeric_limits<int>::min();
          current_statement__ = 187;
          rem_len = ((K - pos) + 1);
          current_statement__ = 188;
          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__ = 190;
          chosen_lp = 0;
          current_statement__ = 204;
          for (int h_pos = 1; h_pos <= rem_len; ++h_pos) {
            int h = std::numeric_limits<int>::min();
            current_statement__ = 191;
            h = ((pos + h_pos) - 1);
            int candidate = std::numeric_limits<int>::min();
            current_statement__ = 192;
            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__ = 193;
            term = stan::model::rvalue(log_agree, "log_agree",
                     stan::model::index_uni(candidate));
            current_statement__ = 199;
            for (int g = pos; g <= K; ++g) {
              current_statement__ = 197;
              if (stan::math::logical_neq(g, h)) {
                int other = std::numeric_limits<int>::min();
                current_statement__ = 194;
                other = stan::model::rvalue(patterns_total, "patterns_total",
                          stan::model::index_uni((((t_start + ((t - 1) * K))
                            + g) - 1)));
                current_statement__ = 195;
                term = (term +
                  stan::model::rvalue(log_disagree, "log_disagree",
                    stan::model::index_uni(other)));
              }
            }
            current_statement__ = 200;
            stan::model::assign(pick_lp, term, "assigning variable pick_lp",
              stan::model::index_uni(h_pos));
            current_statement__ = 202;
            if (stan::math::logical_eq(h_pos, 1)) {
              current_statement__ = 201;
              chosen_lp = term;
            }
          }
          current_statement__ = 205;
          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__ = 210;
      stan::model::assign(lp_total, lp, "assigning variable lp_total",
        stan::model::index_uni(t));
    }
    int fc_t = std::numeric_limits<int>::min();
    current_statement__ = 213;
    fc_t = stan::model::rvalue(fc_type, "fc_type", stan::model::index_uni(b));
    int o_start = std::numeric_limits<int>::min();
    current_statement__ = 214;
    o_start = stan::model::rvalue(obs_start, "obs_start",
                stan::model::index_uni(b));
    int fcl = std::numeric_limits<int>::min();
    current_statement__ = 215;
    fcl = stan::model::rvalue(fc_len, "fc_len", stan::model::index_uni(b));
    local_scalar_t__ lp_obs = DUMMY_VAR__;
    current_statement__ = 216;
    lp_obs = stan::math::negative_infinity();
    current_statement__ = 237;
    if (stan::math::logical_eq(fc_t, 1)) {
      current_statement__ = 235;
      return stan::math::fmax(
               stan::model::rvalue(lp_total, "lp_total",
                 stan::model::index_uni(y_obs)), stan::math::log(1e-16));
    } else {
      current_statement__ = 232;
      for (int t = 1; t <= n_tot; ++t) {
        int consistent = std::numeric_limits<int>::min();
        current_statement__ = 217;
        consistent = 0;
        current_statement__ = 228;
        if (stan::math::logical_eq(fc_t, 2)) {
          int first_t = std::numeric_limits<int>::min();
          current_statement__ = 222;
          first_t = stan::model::rvalue(patterns_total, "patterns_total",
                      stan::model::index_uni((t_start + ((t - 1) * K))));
          int last_t = std::numeric_limits<int>::min();
          current_statement__ = 223;
          last_t = stan::model::rvalue(patterns_total, "patterns_total",
                     stan::model::index_uni((((t_start + ((t - 1) * K)) + K)
                       - 1)));
          int first_o = std::numeric_limits<int>::min();
          current_statement__ = 224;
          first_o = stan::model::rvalue(patterns_obs, "patterns_obs",
                      stan::model::index_uni((o_start + ((y_obs - 1) * fcl))));
          int last_o = std::numeric_limits<int>::min();
          current_statement__ = 225;
          last_o = stan::model::rvalue(patterns_obs, "patterns_obs",
                     stan::model::index_uni(((o_start + ((y_obs - 1) * fcl))
                       + 1)));
          current_statement__ = 226;
          consistent = (stan::math::primitive_value(
                          stan::math::logical_eq(first_t, first_o))
            &&
            stan::math::primitive_value(
              stan::math::logical_eq(last_t, last_o)));
        } else {
          int first_t = std::numeric_limits<int>::min();
          current_statement__ = 218;
          first_t = stan::model::rvalue(patterns_total, "patterns_total",
                      stan::model::index_uni((t_start + ((t - 1) * K))));
          int first_o = std::numeric_limits<int>::min();
          current_statement__ = 219;
          first_o = stan::model::rvalue(patterns_obs, "patterns_obs",
                      stan::model::index_uni((o_start + ((y_obs - 1) * fcl))));
          current_statement__ = 220;
          consistent = stan::math::logical_eq(first_t, first_o);
        }
        current_statement__ = 230;
        if (consistent) {
          current_statement__ = 229;
          lp_obs = stan::math::log_sum_exp(lp_obs,
                     stan::model::rvalue(lp_total, "lp_total",
                       stan::model::index_uni(t)));
        }
      }
      current_statement__ = 233;
      return stan::math::fmax(lp_obs, stan::math::log(1e-16));
    }
  } catch (const std::exception& e) {
    stan::lang::rethrow_located(e, locations_array__[current_statement__]);
  }
}
template <bool propto__, typename T3__, typename T4__, typename T5__,
          typename T6__, typename T_lp__, typename T_lp_accum__,
          stan::require_all_t<stan::is_eigen_matrix_dynamic<T3__>,
                              stan::is_vt_not_complex<T3__>,
                              stan::is_eigen_matrix_dynamic<T4__>,
                              stan::is_vt_not_complex<T4__>,
                              stan::is_eigen_matrix_dynamic<T5__>,
                              stan::is_vt_not_complex<T5__>,
                              stan::is_eigen_matrix_dynamic<T6__>,
                              stan::is_vt_not_complex<T6__>>*>
void
fcggum_obs_lp(const int& p, const int& b, const int& y_obs, const T3__&
              theta_arg__, const T4__& a_arg__, const T5__& delta_arg__,
              const T6__& tau_arg__, const int& D, const std::vector<int>&
              n_items, const std::vector<int>& fc_type,
              const std::vector<int>& block_items, const std::vector<int>&
              item_start, const std::vector<int>& length_poly,
              const std::vector<int>& n_total, const std::vector<int>&
              patterns_total, const std::vector<int>& total_start,
              const std::vector<int>& patterns_obs, const std::vector<int>&
              obs_start, const std::vector<int>& fc_len, T_lp__& lp__,
              T_lp_accum__& lp_accum__, std::ostream* pstream__) {
  using local_scalar_t__ = stan::promote_args_t<stan::base_type_t<T3__>,
                             stan::base_type_t<T4__>,
                             stan::base_type_t<T5__>,
                             stan::base_type_t<T6__>>;
  int current_statement__ = 0;
  const auto& theta = stan::math::to_ref(theta_arg__);
  const auto& a = stan::math::to_ref(a_arg__);
  const auto& delta = stan::math::to_ref(delta_arg__);
  const auto& tau = stan::math::to_ref(tau_arg__);
  local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());
  // suppress unused var warning
  (void) DUMMY_VAR__;
  try {
    current_statement__ = 239;
    lp_accum__.add(fcggum_obs_ll(p, b, y_obs, theta, a, delta, tau, D,
                     n_items, fc_type, block_items, item_start, length_poly,
                     n_total, patterns_total, total_start, patterns_obs,
                     obs_start, fc_len, pstream__));
  } catch (const std::exception& e) {
    stan::lang::rethrow_located(e, locations_array__[current_statement__]);
  }
}
#include <stan_meta_header.hpp>
class model_FCGGUM final : public model_base_crtp<model_FCGGUM> {
private:
  int N_obs;
  int N;
  int B;
  int I;
  int D;
  int max_poly;
  std::vector<int> pid;
  std::vector<int> bid;
  std::vector<int> y;
  std::vector<int> length_poly;
  Eigen::Matrix<double,-1,-1> Q_matrix_data__;
  std::vector<int> n_items;
  std::vector<int> fc_type;
  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_cells_obs;
  std::vector<int> patterns_obs;
  std::vector<int> obs_start;
  std::vector<int> fc_len;
  double a_mu;
  double a_sigma;
  double delta_pos_mu;
  double delta_pos_sigma;
  double delta_neg_mu;
  double delta_neg_sigma;
  double tau_mu;
  double tau_sigma;
  Eigen::Matrix<double,-1,1> theta_mu_data__;
  int a_free_size;
  int delta_pos_size;
  int delta_neg_size;
  Eigen::Map<Eigen::Matrix<double,-1,-1>> Q_matrix{nullptr, 0, 0};
  Eigen::Map<Eigen::Matrix<double,-1,1>> theta_mu{nullptr, 0};
public:
  ~model_FCGGUM() {}
  model_FCGGUM(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_FCGGUM_namespace::model_FCGGUM";
    // 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__ = 72;
      context__.validate_dims("data initialization", "N_obs", "int",
        std::vector<size_t>{});
      N_obs = std::numeric_limits<int>::min();
      current_statement__ = 72;
      N_obs = context__.vals_i("N_obs")[(1 - 1)];
      current_statement__ = 72;
      stan::math::check_greater_or_equal(function__, "N_obs", N_obs, 1);
      current_statement__ = 73;
      context__.validate_dims("data initialization", "N", "int",
        std::vector<size_t>{});
      N = std::numeric_limits<int>::min();
      current_statement__ = 73;
      N = context__.vals_i("N")[(1 - 1)];
      current_statement__ = 73;
      stan::math::check_greater_or_equal(function__, "N", N, 1);
      current_statement__ = 74;
      context__.validate_dims("data initialization", "B", "int",
        std::vector<size_t>{});
      B = std::numeric_limits<int>::min();
      current_statement__ = 74;
      B = context__.vals_i("B")[(1 - 1)];
      current_statement__ = 74;
      stan::math::check_greater_or_equal(function__, "B", B, 1);
      current_statement__ = 75;
      context__.validate_dims("data initialization", "I", "int",
        std::vector<size_t>{});
      I = std::numeric_limits<int>::min();
      current_statement__ = 75;
      I = context__.vals_i("I")[(1 - 1)];
      current_statement__ = 75;
      stan::math::check_greater_or_equal(function__, "I", I, 1);
      current_statement__ = 76;
      context__.validate_dims("data initialization", "D", "int",
        std::vector<size_t>{});
      D = std::numeric_limits<int>::min();
      current_statement__ = 76;
      D = context__.vals_i("D")[(1 - 1)];
      current_statement__ = 76;
      stan::math::check_greater_or_equal(function__, "D", D, 1);
      current_statement__ = 77;
      context__.validate_dims("data initialization", "max_poly", "int",
        std::vector<size_t>{});
      max_poly = std::numeric_limits<int>::min();
      current_statement__ = 77;
      max_poly = context__.vals_i("max_poly")[(1 - 1)];
      current_statement__ = 77;
      stan::math::check_greater_or_equal(function__, "max_poly", max_poly, 1);
      current_statement__ = 78;
      stan::math::validate_non_negative_index("pid", "N_obs", N_obs);
      current_statement__ = 79;
      context__.validate_dims("data initialization", "pid", "int",
        std::vector<size_t>{static_cast<size_t>(N_obs)});
      pid = std::vector<int>(N_obs, std::numeric_limits<int>::min());
      current_statement__ = 79;
      pid = context__.vals_i("pid");
      current_statement__ = 79;
      stan::math::check_greater_or_equal(function__, "pid", pid, 1);
      current_statement__ = 79;
      stan::math::check_less_or_equal(function__, "pid", pid, N);
      current_statement__ = 80;
      stan::math::validate_non_negative_index("bid", "N_obs", N_obs);
      current_statement__ = 81;
      context__.validate_dims("data initialization", "bid", "int",
        std::vector<size_t>{static_cast<size_t>(N_obs)});
      bid = std::vector<int>(N_obs, std::numeric_limits<int>::min());
      current_statement__ = 81;
      bid = context__.vals_i("bid");
      current_statement__ = 81;
      stan::math::check_greater_or_equal(function__, "bid", bid, 1);
      current_statement__ = 81;
      stan::math::check_less_or_equal(function__, "bid", bid, B);
      current_statement__ = 82;
      stan::math::validate_non_negative_index("y", "N_obs", N_obs);
      current_statement__ = 83;
      context__.validate_dims("data initialization", "y", "int",
        std::vector<size_t>{static_cast<size_t>(N_obs)});
      y = std::vector<int>(N_obs, std::numeric_limits<int>::min());
      current_statement__ = 83;
      y = context__.vals_i("y");
      current_statement__ = 83;
      stan::math::check_greater_or_equal(function__, "y", y, 1);
      current_statement__ = 84;
      stan::math::validate_non_negative_index("length_poly", "I", I);
      current_statement__ = 85;
      context__.validate_dims("data initialization", "length_poly", "int",
        std::vector<size_t>{static_cast<size_t>(I)});
      length_poly = std::vector<int>(I, std::numeric_limits<int>::min());
      current_statement__ = 85;
      length_poly = context__.vals_i("length_poly");
      current_statement__ = 85;
      stan::math::check_greater_or_equal(function__, "length_poly",
        length_poly, 2);
      current_statement__ = 85;
      stan::math::check_less_or_equal(function__, "length_poly", length_poly,
        max_poly);
      current_statement__ = 86;
      stan::math::validate_non_negative_index("Q_matrix", "I", I);
      current_statement__ = 87;
      stan::math::validate_non_negative_index("Q_matrix", "D", D);
      current_statement__ = 88;
      context__.validate_dims("data initialization", "Q_matrix", "double",
        std::vector<size_t>{static_cast<size_t>(I), static_cast<size_t>(D)});
      Q_matrix_data__ = Eigen::Matrix<double,-1,-1>::Constant(I, D,
                          std::numeric_limits<double>::quiet_NaN());
      new (&Q_matrix)
        Eigen::Map<Eigen::Matrix<double,-1,-1>>(Q_matrix_data__.data(), I, D);
      {
        std::vector<local_scalar_t__> Q_matrix_flat__;
        current_statement__ = 88;
        Q_matrix_flat__ = context__.vals_r("Q_matrix");
        current_statement__ = 88;
        pos__ = 1;
        current_statement__ = 88;
        for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
          current_statement__ = 88;
          for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
            current_statement__ = 88;
            stan::model::assign(Q_matrix, Q_matrix_flat__[(pos__ - 1)],
              "assigning variable Q_matrix", stan::model::index_uni(sym2__),
              stan::model::index_uni(sym1__));
            current_statement__ = 88;
            pos__ = (pos__ + 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, 1);
      current_statement__ = 91;
      stan::math::validate_non_negative_index("fc_type", "B", B);
      current_statement__ = 92;
      context__.validate_dims("data initialization", "fc_type", "int",
        std::vector<size_t>{static_cast<size_t>(B)});
      fc_type = std::vector<int>(B, std::numeric_limits<int>::min());
      current_statement__ = 92;
      fc_type = context__.vals_i("fc_type");
      current_statement__ = 92;
      stan::math::check_greater_or_equal(function__, "fc_type", fc_type, 1);
      current_statement__ = 92;
      stan::math::check_less_or_equal(function__, "fc_type", fc_type, 3);
      current_statement__ = 93;
      context__.validate_dims("data initialization", "total_block_items",
        "int", std::vector<size_t>{});
      total_block_items = std::numeric_limits<int>::min();
      current_statement__ = 93;
      total_block_items = context__.vals_i("total_block_items")[(1 - 1)];
      current_statement__ = 93;
      stan::math::check_greater_or_equal(function__, "total_block_items",
        total_block_items, 1);
      current_statement__ = 94;
      stan::math::validate_non_negative_index("block_items",
        "total_block_items", total_block_items);
      current_statement__ = 95;
      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__ = 95;
      block_items = context__.vals_i("block_items");
      current_statement__ = 95;
      stan::math::check_greater_or_equal(function__, "block_items",
        block_items, 1);
      current_statement__ = 95;
      stan::math::check_less_or_equal(function__, "block_items", block_items,
        I);
      current_statement__ = 96;
      stan::math::validate_non_negative_index("item_start", "B + 1", (B + 1));
      current_statement__ = 97;
      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__ = 97;
      item_start = context__.vals_i("item_start");
      current_statement__ = 97;
      stan::math::check_greater_or_equal(function__, "item_start",
        item_start, 1);
      current_statement__ = 98;
      stan::math::validate_non_negative_index("n_total", "B", B);
      current_statement__ = 99;
      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__ = 99;
      n_total = context__.vals_i("n_total");
      current_statement__ = 99;
      stan::math::check_greater_or_equal(function__, "n_total", n_total, 1);
      current_statement__ = 100;
      context__.validate_dims("data initialization", "total_cells_total",
        "int", std::vector<size_t>{});
      total_cells_total = std::numeric_limits<int>::min();
      current_statement__ = 100;
      total_cells_total = context__.vals_i("total_cells_total")[(1 - 1)];
      current_statement__ = 100;
      stan::math::check_greater_or_equal(function__, "total_cells_total",
        total_cells_total, 1);
      current_statement__ = 101;
      stan::math::validate_non_negative_index("patterns_total",
        "total_cells_total", total_cells_total);
      current_statement__ = 102;
      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__ = 102;
      patterns_total = context__.vals_i("patterns_total");
      current_statement__ = 102;
      stan::math::check_greater_or_equal(function__, "patterns_total",
        patterns_total, 1);
      current_statement__ = 103;
      stan::math::validate_non_negative_index("total_start", "B + 1", (B + 1));
      current_statement__ = 104;
      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__ = 104;
      total_start = context__.vals_i("total_start");
      current_statement__ = 104;
      stan::math::check_greater_or_equal(function__, "total_start",
        total_start, 1);
      current_statement__ = 105;
      stan::math::validate_non_negative_index("n_obs", "B", B);
      current_statement__ = 106;
      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__ = 106;
      n_obs = context__.vals_i("n_obs");
      current_statement__ = 106;
      stan::math::check_greater_or_equal(function__, "n_obs", n_obs, 1);
      current_statement__ = 107;
      context__.validate_dims("data initialization", "total_cells_obs",
        "int", std::vector<size_t>{});
      total_cells_obs = std::numeric_limits<int>::min();
      current_statement__ = 107;
      total_cells_obs = context__.vals_i("total_cells_obs")[(1 - 1)];
      current_statement__ = 107;
      stan::math::check_greater_or_equal(function__, "total_cells_obs",
        total_cells_obs, 1);
      current_statement__ = 108;
      stan::math::validate_non_negative_index("patterns_obs",
        "total_cells_obs", total_cells_obs);
      current_statement__ = 109;
      context__.validate_dims("data initialization", "patterns_obs", "int",
        std::vector<size_t>{static_cast<size_t>(total_cells_obs)});
      patterns_obs = std::vector<int>(total_cells_obs,
                       std::numeric_limits<int>::min());
      current_statement__ = 109;
      patterns_obs = context__.vals_i("patterns_obs");
      current_statement__ = 109;
      stan::math::check_greater_or_equal(function__, "patterns_obs",
        patterns_obs, 1);
      current_statement__ = 110;
      stan::math::validate_non_negative_index("obs_start", "B + 1", (B + 1));
      current_statement__ = 111;
      context__.validate_dims("data initialization", "obs_start", "int",
        std::vector<size_t>{static_cast<size_t>((B + 1))});
      obs_start = std::vector<int>((B + 1), std::numeric_limits<int>::min());
      current_statement__ = 111;
      obs_start = context__.vals_i("obs_start");
      current_statement__ = 111;
      stan::math::check_greater_or_equal(function__, "obs_start", obs_start,
        1);
      current_statement__ = 112;
      stan::math::validate_non_negative_index("fc_len", "B", B);
      current_statement__ = 113;
      context__.validate_dims("data initialization", "fc_len", "int",
        std::vector<size_t>{static_cast<size_t>(B)});
      fc_len = std::vector<int>(B, std::numeric_limits<int>::min());
      current_statement__ = 113;
      fc_len = context__.vals_i("fc_len");
      current_statement__ = 113;
      stan::math::check_greater_or_equal(function__, "fc_len", fc_len, 1);
      current_statement__ = 114;
      context__.validate_dims("data initialization", "a_mu", "double",
        std::vector<size_t>{});
      a_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 114;
      a_mu = context__.vals_r("a_mu")[(1 - 1)];
      current_statement__ = 115;
      context__.validate_dims("data initialization", "a_sigma", "double",
        std::vector<size_t>{});
      a_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 115;
      a_sigma = context__.vals_r("a_sigma")[(1 - 1)];
      current_statement__ = 115;
      stan::math::check_greater_or_equal(function__, "a_sigma", a_sigma, 0);
      current_statement__ = 116;
      context__.validate_dims("data initialization", "delta_pos_mu",
        "double", std::vector<size_t>{});
      delta_pos_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 116;
      delta_pos_mu = context__.vals_r("delta_pos_mu")[(1 - 1)];
      current_statement__ = 117;
      context__.validate_dims("data initialization", "delta_pos_sigma",
        "double", std::vector<size_t>{});
      delta_pos_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 117;
      delta_pos_sigma = context__.vals_r("delta_pos_sigma")[(1 - 1)];
      current_statement__ = 117;
      stan::math::check_greater_or_equal(function__, "delta_pos_sigma",
        delta_pos_sigma, 0);
      current_statement__ = 118;
      context__.validate_dims("data initialization", "delta_neg_mu",
        "double", std::vector<size_t>{});
      delta_neg_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 118;
      delta_neg_mu = context__.vals_r("delta_neg_mu")[(1 - 1)];
      current_statement__ = 119;
      context__.validate_dims("data initialization", "delta_neg_sigma",
        "double", std::vector<size_t>{});
      delta_neg_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 119;
      delta_neg_sigma = context__.vals_r("delta_neg_sigma")[(1 - 1)];
      current_statement__ = 119;
      stan::math::check_greater_or_equal(function__, "delta_neg_sigma",
        delta_neg_sigma, 0);
      current_statement__ = 120;
      context__.validate_dims("data initialization", "tau_mu", "double",
        std::vector<size_t>{});
      tau_mu = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 120;
      tau_mu = context__.vals_r("tau_mu")[(1 - 1)];
      current_statement__ = 121;
      context__.validate_dims("data initialization", "tau_sigma", "double",
        std::vector<size_t>{});
      tau_sigma = std::numeric_limits<double>::quiet_NaN();
      current_statement__ = 121;
      tau_sigma = context__.vals_r("tau_sigma")[(1 - 1)];
      current_statement__ = 121;
      stan::math::check_greater_or_equal(function__, "tau_sigma", tau_sigma,
        0);
      current_statement__ = 122;
      stan::math::validate_non_negative_index("theta_mu", "D", D);
      current_statement__ = 123;
      context__.validate_dims("data initialization", "theta_mu", "double",
        std::vector<size_t>{static_cast<size_t>(D)});
      theta_mu_data__ = Eigen::Matrix<double,-1,1>::Constant(D,
                          std::numeric_limits<double>::quiet_NaN());
      new (&theta_mu)
        Eigen::Map<Eigen::Matrix<double,-1,1>>(theta_mu_data__.data(), D);
      {
        std::vector<local_scalar_t__> theta_mu_flat__;
        current_statement__ = 123;
        theta_mu_flat__ = context__.vals_r("theta_mu");
        current_statement__ = 123;
        pos__ = 1;
        current_statement__ = 123;
        for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
          current_statement__ = 123;
          stan::model::assign(theta_mu, theta_mu_flat__[(pos__ - 1)],
            "assigning variable theta_mu", stan::model::index_uni(sym1__));
          current_statement__ = 123;
          pos__ = (pos__ + 1);
        }
      }
      current_statement__ = 124;
      a_free_size = std::numeric_limits<int>::min();
      current_statement__ = 124;
      a_free_size = 0;
      current_statement__ = 125;
      delta_pos_size = std::numeric_limits<int>::min();
      current_statement__ = 125;
      delta_pos_size = 0;
      current_statement__ = 126;
      delta_neg_size = std::numeric_limits<int>::min();
      current_statement__ = 126;
      delta_neg_size = 0;
      current_statement__ = 136;
      for (int i = 1; i <= I; ++i) {
        current_statement__ = 134;
        for (int j = 1; j <= D; ++j) {
          current_statement__ = 132;
          if (stan::math::logical_neq(
                stan::model::rvalue(Q_matrix, "Q_matrix",
                  stan::model::index_uni(i), stan::model::index_uni(j)), 0)) {
            current_statement__ = 127;
            a_free_size = (a_free_size + 1);
            current_statement__ = 130;
            if (stan::math::logical_eq(
                  stan::model::rvalue(Q_matrix, "Q_matrix",
                    stan::model::index_uni(i), stan::model::index_uni(j)), 1)) {
              current_statement__ = 129;
              delta_pos_size = (delta_pos_size + 1);
            } else {
              current_statement__ = 128;
              delta_neg_size = (delta_neg_size + 1);
            }
          }
        }
      }
      current_statement__ = 137;
      stan::math::validate_non_negative_index("a_free", "a_free_size",
        a_free_size);
      current_statement__ = 138;
      stan::math::validate_non_negative_index("delta_neg", "delta_neg_size",
        delta_neg_size);
      current_statement__ = 139;
      stan::math::validate_non_negative_index("delta_pos", "delta_pos_size",
        delta_pos_size);
      current_statement__ = 140;
      stan::math::validate_non_negative_index("neg_tau", "I", I);
      current_statement__ = 141;
      stan::math::validate_non_negative_index("L_Corr", "D", D);
      current_statement__ = 141;
      stan::math::validate_non_negative_index("L_Corr", "D", D);
      current_statement__ = 142;
      stan::math::validate_non_negative_index("theta_raw", "N", N);
      current_statement__ = 143;
      stan::math::validate_non_negative_index("theta_raw", "D", D);
      current_statement__ = 144;
      stan::math::validate_non_negative_index("a", "I", I);
      current_statement__ = 145;
      stan::math::validate_non_negative_index("a", "D", D);
      current_statement__ = 146;
      stan::math::validate_non_negative_index("delta", "I", I);
      current_statement__ = 147;
      stan::math::validate_non_negative_index("delta", "D", D);
      current_statement__ = 148;
      stan::math::validate_non_negative_index("tau", "I", I);
      current_statement__ = 149;
      stan::math::validate_non_negative_index("tau", "max_poly", max_poly);
      current_statement__ = 150;
      stan::math::validate_non_negative_index("theta", "N", N);
      current_statement__ = 151;
      stan::math::validate_non_negative_index("theta", "D", D);
      current_statement__ = 152;
      stan::math::validate_non_negative_index("Corr", "D", D);
      current_statement__ = 153;
      stan::math::validate_non_negative_index("Corr", "D", D);
      current_statement__ = 154;
      stan::math::validate_non_negative_index("log_lik", "N_obs", N_obs);
    } catch (const std::exception& e) {
      stan::lang::rethrow_located(e, locations_array__[current_statement__]);
    }
    num_params_r__ = a_free_size + delta_neg_size + delta_pos_size + I + ((D
      * (D - 1)) / 2) + (N * D);
  }
  inline std::string model_name() const final {
    return "model_FCGGUM";
  }
  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_FCGGUM_namespace::log_prob";
    // suppress unused var warning
    (void) function__;
    try {
      Eigen::Matrix<local_scalar_t__,-1,1> a_free =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(a_free_size,
          DUMMY_VAR__);
      current_statement__ = 1;
      a_free = in__.template read_constrain_lb<
                 Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, lp__,
                 a_free_size);
      Eigen::Matrix<local_scalar_t__,-1,1> delta_neg =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(delta_neg_size,
          DUMMY_VAR__);
      current_statement__ = 2;
      delta_neg = in__.template read_constrain_ub<
                    Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0,
                    lp__, delta_neg_size);
      Eigen::Matrix<local_scalar_t__,-1,1> delta_pos =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(delta_pos_size,
          DUMMY_VAR__);
      current_statement__ = 3;
      delta_pos = in__.template read_constrain_lb<
                    Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0,
                    lp__, delta_pos_size);
      Eigen::Matrix<local_scalar_t__,-1,1> neg_tau =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(I, DUMMY_VAR__);
      current_statement__ = 4;
      neg_tau = in__.template read_constrain_lb<
                  Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, lp__,
                  I);
      Eigen::Matrix<local_scalar_t__,-1,-1> L_Corr =
        Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(D, D, DUMMY_VAR__);
      current_statement__ = 5;
      L_Corr = in__.template read_constrain_cholesky_factor_corr<
                 Eigen::Matrix<local_scalar_t__,-1,-1>, jacobian__>(lp__, D);
      std::vector<Eigen::Matrix<local_scalar_t__,-1,1>> theta_raw =
        std::vector<Eigen::Matrix<local_scalar_t__,-1,1>>(N,
          Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__));
      current_statement__ = 6;
      theta_raw = in__.template read<
                    std::vector<Eigen::Matrix<local_scalar_t__,-1,1>>>(N, D);
      Eigen::Matrix<local_scalar_t__,-1,-1> a =
        Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(I, D, DUMMY_VAR__);
      Eigen::Matrix<local_scalar_t__,-1,-1> delta =
        Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(I, D, DUMMY_VAR__);
      Eigen::Matrix<local_scalar_t__,-1,-1> tau =
        Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(I, max_poly,
          DUMMY_VAR__);
      Eigen::Matrix<local_scalar_t__,-1,-1> theta =
        Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(N, D, DUMMY_VAR__);
      {
        int idx = std::numeric_limits<int>::min();
        current_statement__ = 13;
        idx = 1;
        current_statement__ = 23;
        for (int i = 1; i <= I; ++i) {
          current_statement__ = 21;
          for (int j = 1; j <= D; ++j) {
            current_statement__ = 19;
            if (stan::math::logical_neq(
                  stan::model::rvalue(Q_matrix, "Q_matrix",
                    stan::model::index_uni(i), stan::model::index_uni(j)), 0)) {
              current_statement__ = 16;
              stan::model::assign(a,
                stan::model::rvalue(a_free, "a_free",
                  stan::model::index_uni(idx)), "assigning variable a",
                stan::model::index_uni(i), stan::model::index_uni(j));
              current_statement__ = 17;
              idx = (idx + 1);
            } else {
              current_statement__ = 14;
              stan::model::assign(a, 0.0, "assigning variable a",
                stan::model::index_uni(i), stan::model::index_uni(j));
            }
          }
        }
      }
      {
        int idx_pos = std::numeric_limits<int>::min();
        current_statement__ = 25;
        idx_pos = 1;
        int idx_neg = std::numeric_limits<int>::min();
        current_statement__ = 26;
        idx_neg = 1;
        current_statement__ = 40;
        for (int i = 1; i <= I; ++i) {
          current_statement__ = 38;
          for (int j = 1; j <= D; ++j) {
            current_statement__ = 36;
            if (stan::math::logical_eq(
                  stan::model::rvalue(Q_matrix, "Q_matrix",
                    stan::model::index_uni(i), stan::model::index_uni(j)), 1)) {
              current_statement__ = 33;
              stan::model::assign(delta,
                stan::model::rvalue(delta_pos, "delta_pos",
                  stan::model::index_uni(idx_pos)),
                "assigning variable delta", stan::model::index_uni(i),
                stan::model::index_uni(j));
              current_statement__ = 34;
              idx_pos = (idx_pos + 1);
            } else {
              current_statement__ = 32;
              if (stan::math::logical_eq(
                    stan::model::rvalue(Q_matrix, "Q_matrix",
                      stan::model::index_uni(i), stan::model::index_uni(j)),
                    -1)) {
                current_statement__ = 29;
                stan::model::assign(delta,
                  stan::model::rvalue(delta_neg, "delta_neg",
                    stan::model::index_uni(idx_neg)),
                  "assigning variable delta", stan::model::index_uni(i),
                  stan::model::index_uni(j));
                current_statement__ = 30;
                idx_neg = (idx_neg + 1);
              } else {
                current_statement__ = 27;
                stan::model::assign(delta, 0.0, "assigning variable delta",
                  stan::model::index_uni(i), stan::model::index_uni(j));
              }
            }
          }
        }
      }
      current_statement__ = 49;
      for (int i = 1; i <= I; ++i) {
        current_statement__ = 42;
        stan::model::assign(tau, 0.0, "assigning variable tau",
          stan::model::index_uni(i), stan::model::index_uni(1));
        current_statement__ = 43;
        stan::model::assign(tau,
          -stan::model::rvalue(neg_tau, "neg_tau", stan::model::index_uni(i)),
          "assigning variable tau", stan::model::index_uni(i),
          stan::model::index_uni(2));
        current_statement__ = 47;
        if (stan::math::logical_gt(max_poly, 2)) {
          current_statement__ = 45;
          for (int k = 3; k <= max_poly; ++k) {
            current_statement__ = 44;
            stan::model::assign(tau, 0.0, "assigning variable tau",
              stan::model::index_uni(i), stan::model::index_uni(k));
          }
        }
      }
      current_statement__ = 54;
      for (int n = 1; n <= N; ++n) {
        current_statement__ = 52;
        if (stan::math::logical_gt(D, 1)) {
          current_statement__ = 51;
          stan::model::assign(theta,
            stan::math::transpose(
              stan::math::add(theta_mu,
                stan::math::multiply(L_Corr,
                  stan::model::rvalue(theta_raw, "theta_raw",
                    stan::model::index_uni(n))))),
            "assigning variable theta", stan::model::index_uni(n));
        } else {
          current_statement__ = 50;
          stan::model::assign(theta,
            (stan::model::rvalue(theta_mu, "theta_mu",
               stan::model::index_uni(1)) +
            stan::model::rvalue(
              stan::model::rvalue(theta_raw, "theta_raw",
                stan::model::index_uni(n)), "theta_raw[n]",
              stan::model::index_uni(1))), "assigning variable theta",
            stan::model::index_uni(n), stan::model::index_uni(1));
        }
      }
      current_statement__ = 7;
      stan::math::check_greater_or_equal(function__, "a", a, 0);
      {
        current_statement__ = 61;
        lp_accum__.add(stan::math::lognormal_lpdf<propto__>(a_free, a_mu,
                         a_sigma));
        current_statement__ = 62;
        lp_accum__.add(stan::math::normal_lpdf<propto__>(delta_neg,
                         delta_neg_mu, delta_neg_sigma));
        current_statement__ = 63;
        lp_accum__.add(stan::math::normal_lpdf<propto__>(delta_pos,
                         delta_pos_mu, delta_pos_sigma));
        current_statement__ = 64;
        lp_accum__.add(stan::math::lognormal_lpdf<propto__>(neg_tau, tau_mu,
                         tau_sigma));
        current_statement__ = 66;
        if (stan::math::logical_gt(D, 1)) {
          current_statement__ = 65;
          lp_accum__.add(stan::math::lkj_corr_cholesky_lpdf<propto__>(L_Corr,
                           1));
        }
        current_statement__ = 68;
        for (int n = 1; n <= N; ++n) {
          current_statement__ = 67;
          lp_accum__.add(stan::math::std_normal_lpdf<propto__>(
                           stan::model::rvalue(theta_raw, "theta_raw",
                             stan::model::index_uni(n))));
        }
        current_statement__ = 71;
        for (int obs = 1; obs <= N_obs; ++obs) {
          current_statement__ = 69;
          fcggum_obs_lp<propto__>(
            stan::model::rvalue(pid, "pid", stan::model::index_uni(obs)),
            stan::model::rvalue(bid, "bid", stan::model::index_uni(obs)),
            stan::model::rvalue(y, "y", stan::model::index_uni(obs)), theta,
            a, delta, tau, D, n_items, fc_type, block_items, item_start,
            length_poly, n_total, patterns_total, total_start, patterns_obs,
            obs_start, fc_len, lp__, lp_accum__, pstream__);
        }
      }
    } 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_FCGGUM_namespace::write_array";
    // suppress unused var warning
    (void) function__;
    try {
      Eigen::Matrix<double,-1,1> a_free =
        Eigen::Matrix<double,-1,1>::Constant(a_free_size,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 1;
      a_free = in__.template read_constrain_lb<
                 Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, lp__,
                 a_free_size);
      Eigen::Matrix<double,-1,1> delta_neg =
        Eigen::Matrix<double,-1,1>::Constant(delta_neg_size,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 2;
      delta_neg = in__.template read_constrain_ub<
                    Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0,
                    lp__, delta_neg_size);
      Eigen::Matrix<double,-1,1> delta_pos =
        Eigen::Matrix<double,-1,1>::Constant(delta_pos_size,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 3;
      delta_pos = in__.template read_constrain_lb<
                    Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0,
                    lp__, delta_pos_size);
      Eigen::Matrix<double,-1,1> neg_tau =
        Eigen::Matrix<double,-1,1>::Constant(I,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 4;
      neg_tau = in__.template read_constrain_lb<
                  Eigen::Matrix<local_scalar_t__,-1,1>, jacobian__>(0, lp__,
                  I);
      Eigen::Matrix<double,-1,-1> L_Corr =
        Eigen::Matrix<double,-1,-1>::Constant(D, D,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 5;
      L_Corr = in__.template read_constrain_cholesky_factor_corr<
                 Eigen::Matrix<local_scalar_t__,-1,-1>, jacobian__>(lp__, D);
      std::vector<Eigen::Matrix<double,-1,1>> theta_raw =
        std::vector<Eigen::Matrix<double,-1,1>>(N,
          Eigen::Matrix<double,-1,1>::Constant(D,
            std::numeric_limits<double>::quiet_NaN()));
      current_statement__ = 6;
      theta_raw = in__.template read<
                    std::vector<Eigen::Matrix<local_scalar_t__,-1,1>>>(N, D);
      Eigen::Matrix<double,-1,-1> a =
        Eigen::Matrix<double,-1,-1>::Constant(I, D,
          std::numeric_limits<double>::quiet_NaN());
      Eigen::Matrix<double,-1,-1> delta =
        Eigen::Matrix<double,-1,-1>::Constant(I, D,
          std::numeric_limits<double>::quiet_NaN());
      Eigen::Matrix<double,-1,-1> tau =
        Eigen::Matrix<double,-1,-1>::Constant(I, max_poly,
          std::numeric_limits<double>::quiet_NaN());
      Eigen::Matrix<double,-1,-1> theta =
        Eigen::Matrix<double,-1,-1>::Constant(N, D,
          std::numeric_limits<double>::quiet_NaN());
      out__.write(a_free);
      out__.write(delta_neg);
      out__.write(delta_pos);
      out__.write(neg_tau);
      out__.write(L_Corr);
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= N; ++sym2__) {
          out__.write(theta_raw[(sym2__ - 1)][(sym1__ - 1)]);
        }
      }
      if (stan::math::logical_negation(
            (stan::math::primitive_value(emit_transformed_parameters__) ||
            stan::math::primitive_value(emit_generated_quantities__)))) {
        return ;
      }
      {
        int idx = std::numeric_limits<int>::min();
        current_statement__ = 13;
        idx = 1;
        current_statement__ = 23;
        for (int i = 1; i <= I; ++i) {
          current_statement__ = 21;
          for (int j = 1; j <= D; ++j) {
            current_statement__ = 19;
            if (stan::math::logical_neq(
                  stan::model::rvalue(Q_matrix, "Q_matrix",
                    stan::model::index_uni(i), stan::model::index_uni(j)), 0)) {
              current_statement__ = 16;
              stan::model::assign(a,
                stan::model::rvalue(a_free, "a_free",
                  stan::model::index_uni(idx)), "assigning variable a",
                stan::model::index_uni(i), stan::model::index_uni(j));
              current_statement__ = 17;
              idx = (idx + 1);
            } else {
              current_statement__ = 14;
              stan::model::assign(a, 0.0, "assigning variable a",
                stan::model::index_uni(i), stan::model::index_uni(j));
            }
          }
        }
      }
      {
        int idx_pos = std::numeric_limits<int>::min();
        current_statement__ = 25;
        idx_pos = 1;
        int idx_neg = std::numeric_limits<int>::min();
        current_statement__ = 26;
        idx_neg = 1;
        current_statement__ = 40;
        for (int i = 1; i <= I; ++i) {
          current_statement__ = 38;
          for (int j = 1; j <= D; ++j) {
            current_statement__ = 36;
            if (stan::math::logical_eq(
                  stan::model::rvalue(Q_matrix, "Q_matrix",
                    stan::model::index_uni(i), stan::model::index_uni(j)), 1)) {
              current_statement__ = 33;
              stan::model::assign(delta,
                stan::model::rvalue(delta_pos, "delta_pos",
                  stan::model::index_uni(idx_pos)),
                "assigning variable delta", stan::model::index_uni(i),
                stan::model::index_uni(j));
              current_statement__ = 34;
              idx_pos = (idx_pos + 1);
            } else {
              current_statement__ = 32;
              if (stan::math::logical_eq(
                    stan::model::rvalue(Q_matrix, "Q_matrix",
                      stan::model::index_uni(i), stan::model::index_uni(j)),
                    -1)) {
                current_statement__ = 29;
                stan::model::assign(delta,
                  stan::model::rvalue(delta_neg, "delta_neg",
                    stan::model::index_uni(idx_neg)),
                  "assigning variable delta", stan::model::index_uni(i),
                  stan::model::index_uni(j));
                current_statement__ = 30;
                idx_neg = (idx_neg + 1);
              } else {
                current_statement__ = 27;
                stan::model::assign(delta, 0.0, "assigning variable delta",
                  stan::model::index_uni(i), stan::model::index_uni(j));
              }
            }
          }
        }
      }
      current_statement__ = 49;
      for (int i = 1; i <= I; ++i) {
        current_statement__ = 42;
        stan::model::assign(tau, 0.0, "assigning variable tau",
          stan::model::index_uni(i), stan::model::index_uni(1));
        current_statement__ = 43;
        stan::model::assign(tau,
          -stan::model::rvalue(neg_tau, "neg_tau", stan::model::index_uni(i)),
          "assigning variable tau", stan::model::index_uni(i),
          stan::model::index_uni(2));
        current_statement__ = 47;
        if (stan::math::logical_gt(max_poly, 2)) {
          current_statement__ = 45;
          for (int k = 3; k <= max_poly; ++k) {
            current_statement__ = 44;
            stan::model::assign(tau, 0.0, "assigning variable tau",
              stan::model::index_uni(i), stan::model::index_uni(k));
          }
        }
      }
      current_statement__ = 54;
      for (int n = 1; n <= N; ++n) {
        current_statement__ = 52;
        if (stan::math::logical_gt(D, 1)) {
          current_statement__ = 51;
          stan::model::assign(theta,
            stan::math::transpose(
              stan::math::add(theta_mu,
                stan::math::multiply(L_Corr,
                  stan::model::rvalue(theta_raw, "theta_raw",
                    stan::model::index_uni(n))))),
            "assigning variable theta", stan::model::index_uni(n));
        } else {
          current_statement__ = 50;
          stan::model::assign(theta,
            (stan::model::rvalue(theta_mu, "theta_mu",
               stan::model::index_uni(1)) +
            stan::model::rvalue(
              stan::model::rvalue(theta_raw, "theta_raw",
                stan::model::index_uni(n)), "theta_raw[n]",
              stan::model::index_uni(1))), "assigning variable theta",
            stan::model::index_uni(n), stan::model::index_uni(1));
        }
      }
      current_statement__ = 7;
      stan::math::check_greater_or_equal(function__, "a", a, 0);
      if (emit_transformed_parameters__) {
        out__.write(a);
        out__.write(delta);
        out__.write(tau);
        out__.write(theta);
      }
      if (stan::math::logical_negation(emit_generated_quantities__)) {
        return ;
      }
      Eigen::Matrix<double,-1,-1> Corr =
        Eigen::Matrix<double,-1,-1>::Constant(D, D,
          std::numeric_limits<double>::quiet_NaN());
      Eigen::Matrix<double,-1,1> log_lik =
        Eigen::Matrix<double,-1,1>::Constant(N_obs,
          std::numeric_limits<double>::quiet_NaN());
      current_statement__ = 57;
      if (stan::math::logical_gt(D, 1)) {
        current_statement__ = 56;
        stan::model::assign(Corr,
          stan::math::multiply_lower_tri_self_transpose(L_Corr),
          "assigning variable Corr");
      } else {
        current_statement__ = 55;
        stan::model::assign(Corr, 1.0, "assigning variable Corr",
          stan::model::index_uni(1), stan::model::index_uni(1));
      }
      current_statement__ = 60;
      for (int obs = 1; obs <= N_obs; ++obs) {
        current_statement__ = 58;
        stan::model::assign(log_lik,
          fcggum_obs_ll(
            stan::model::rvalue(pid, "pid", stan::model::index_uni(obs)),
            stan::model::rvalue(bid, "bid", stan::model::index_uni(obs)),
            stan::model::rvalue(y, "y", stan::model::index_uni(obs)), theta,
            a, delta, tau, D, n_items, fc_type, block_items, item_start,
            length_poly, n_total, patterns_total, total_start, patterns_obs,
            obs_start, fc_len, pstream__), "assigning variable log_lik",
          stan::model::index_uni(obs));
      }
      out__.write(Corr);
      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> a_free =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(a_free_size,
          DUMMY_VAR__);
      current_statement__ = 1;
      stan::model::assign(a_free,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(a_free_size),
        "assigning variable a_free");
      out__.write_free_lb(0, a_free);
      Eigen::Matrix<local_scalar_t__,-1,1> delta_neg =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(delta_neg_size,
          DUMMY_VAR__);
      current_statement__ = 2;
      stan::model::assign(delta_neg,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(delta_neg_size),
        "assigning variable delta_neg");
      out__.write_free_ub(0, delta_neg);
      Eigen::Matrix<local_scalar_t__,-1,1> delta_pos =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(delta_pos_size,
          DUMMY_VAR__);
      current_statement__ = 3;
      stan::model::assign(delta_pos,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(delta_pos_size),
        "assigning variable delta_pos");
      out__.write_free_lb(0, delta_pos);
      Eigen::Matrix<local_scalar_t__,-1,1> neg_tau =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(I, DUMMY_VAR__);
      current_statement__ = 4;
      stan::model::assign(neg_tau,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(I),
        "assigning variable neg_tau");
      out__.write_free_lb(0, neg_tau);
      Eigen::Matrix<local_scalar_t__,-1,-1> L_Corr =
        Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(D, D, DUMMY_VAR__);
      current_statement__ = 5;
      stan::model::assign(L_Corr,
        in__.read<Eigen::Matrix<local_scalar_t__,-1,-1>>(D, D),
        "assigning variable L_Corr");
      out__.write_free_cholesky_factor_corr(L_Corr);
      std::vector<Eigen::Matrix<local_scalar_t__,-1,1>> theta_raw =
        std::vector<Eigen::Matrix<local_scalar_t__,-1,1>>(N,
          Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__));
      current_statement__ = 6;
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        current_statement__ = 6;
        for (int sym2__ = 1; sym2__ <= N; ++sym2__) {
          current_statement__ = 6;
          stan::model::assign(theta_raw, in__.read<local_scalar_t__>(),
            "assigning variable theta_raw", stan::model::index_uni(sym2__),
            stan::model::index_uni(sym1__));
        }
      }
      out__.write(theta_raw);
    } 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", "a_free", "double",
        std::vector<size_t>{static_cast<size_t>(a_free_size)});
      current_statement__ = 2;
      context__.validate_dims("parameter initialization", "delta_neg",
        "double", std::vector<size_t>{static_cast<size_t>(delta_neg_size)});
      current_statement__ = 3;
      context__.validate_dims("parameter initialization", "delta_pos",
        "double", std::vector<size_t>{static_cast<size_t>(delta_pos_size)});
      current_statement__ = 4;
      context__.validate_dims("parameter initialization", "neg_tau",
        "double", std::vector<size_t>{static_cast<size_t>(I)});
      current_statement__ = 5;
      context__.validate_dims("parameter initialization", "L_Corr", "double",
        std::vector<size_t>{static_cast<size_t>(D), static_cast<size_t>(D)});
      current_statement__ = 6;
      context__.validate_dims("parameter initialization", "theta_raw",
        "double",
        std::vector<size_t>{static_cast<size_t>(N), static_cast<size_t>(D)});
      int pos__ = std::numeric_limits<int>::min();
      pos__ = 1;
      Eigen::Matrix<local_scalar_t__,-1,1> a_free =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(a_free_size,
          DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> a_free_flat__;
        current_statement__ = 1;
        a_free_flat__ = context__.vals_r("a_free");
        current_statement__ = 1;
        pos__ = 1;
        current_statement__ = 1;
        for (int sym1__ = 1; sym1__ <= a_free_size; ++sym1__) {
          current_statement__ = 1;
          stan::model::assign(a_free, a_free_flat__[(pos__ - 1)],
            "assigning variable a_free", stan::model::index_uni(sym1__));
          current_statement__ = 1;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_lb(0, a_free);
      Eigen::Matrix<local_scalar_t__,-1,1> delta_neg =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(delta_neg_size,
          DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> delta_neg_flat__;
        current_statement__ = 2;
        delta_neg_flat__ = context__.vals_r("delta_neg");
        current_statement__ = 2;
        pos__ = 1;
        current_statement__ = 2;
        for (int sym1__ = 1; sym1__ <= delta_neg_size; ++sym1__) {
          current_statement__ = 2;
          stan::model::assign(delta_neg, delta_neg_flat__[(pos__ - 1)],
            "assigning variable delta_neg", stan::model::index_uni(sym1__));
          current_statement__ = 2;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_ub(0, delta_neg);
      Eigen::Matrix<local_scalar_t__,-1,1> delta_pos =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(delta_pos_size,
          DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> delta_pos_flat__;
        current_statement__ = 3;
        delta_pos_flat__ = context__.vals_r("delta_pos");
        current_statement__ = 3;
        pos__ = 1;
        current_statement__ = 3;
        for (int sym1__ = 1; sym1__ <= delta_pos_size; ++sym1__) {
          current_statement__ = 3;
          stan::model::assign(delta_pos, delta_pos_flat__[(pos__ - 1)],
            "assigning variable delta_pos", stan::model::index_uni(sym1__));
          current_statement__ = 3;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_lb(0, delta_pos);
      Eigen::Matrix<local_scalar_t__,-1,1> neg_tau =
        Eigen::Matrix<local_scalar_t__,-1,1>::Constant(I, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> neg_tau_flat__;
        current_statement__ = 4;
        neg_tau_flat__ = context__.vals_r("neg_tau");
        current_statement__ = 4;
        pos__ = 1;
        current_statement__ = 4;
        for (int sym1__ = 1; sym1__ <= I; ++sym1__) {
          current_statement__ = 4;
          stan::model::assign(neg_tau, neg_tau_flat__[(pos__ - 1)],
            "assigning variable neg_tau", stan::model::index_uni(sym1__));
          current_statement__ = 4;
          pos__ = (pos__ + 1);
        }
      }
      out__.write_free_lb(0, neg_tau);
      Eigen::Matrix<local_scalar_t__,-1,-1> L_Corr =
        Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(D, D, DUMMY_VAR__);
      {
        std::vector<local_scalar_t__> L_Corr_flat__;
        current_statement__ = 5;
        L_Corr_flat__ = context__.vals_r("L_Corr");
        current_statement__ = 5;
        pos__ = 1;
        current_statement__ = 5;
        for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
          current_statement__ = 5;
          for (int sym2__ = 1; sym2__ <= D; ++sym2__) {
            current_statement__ = 5;
            stan::model::assign(L_Corr, L_Corr_flat__[(pos__ - 1)],
              "assigning variable L_Corr", stan::model::index_uni(sym2__),
              stan::model::index_uni(sym1__));
            current_statement__ = 5;
            pos__ = (pos__ + 1);
          }
        }
      }
      out__.write_free_cholesky_factor_corr(L_Corr);
      std::vector<Eigen::Matrix<local_scalar_t__,-1,1>> theta_raw =
        std::vector<Eigen::Matrix<local_scalar_t__,-1,1>>(N,
          Eigen::Matrix<local_scalar_t__,-1,1>::Constant(D, DUMMY_VAR__));
      {
        std::vector<local_scalar_t__> theta_raw_flat__;
        current_statement__ = 6;
        theta_raw_flat__ = context__.vals_r("theta_raw");
        current_statement__ = 6;
        pos__ = 1;
        current_statement__ = 6;
        for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
          current_statement__ = 6;
          for (int sym2__ = 1; sym2__ <= N; ++sym2__) {
            current_statement__ = 6;
            stan::model::assign(theta_raw, theta_raw_flat__[(pos__ - 1)],
              "assigning variable theta_raw", stan::model::index_uni(sym2__),
              stan::model::index_uni(sym1__));
            current_statement__ = 6;
            pos__ = (pos__ + 1);
          }
        }
      }
      out__.write(theta_raw);
    } 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>{"a_free", "delta_neg", "delta_pos",
                "neg_tau", "L_Corr", "theta_raw"};
    if (emit_transformed_parameters__) {
      std::vector<std::string> temp{"a", "delta", "tau", "theta"};
      names__.reserve(names__.size() + temp.size());
      names__.insert(names__.end(), temp.begin(), temp.end());
    }
    if (emit_generated_quantities__) {
      std::vector<std::string> temp{"Corr", "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>(
                                                                    a_free_size)},
                std::vector<size_t>{static_cast<size_t>(delta_neg_size)},
                std::vector<size_t>{static_cast<size_t>(delta_pos_size)},
                std::vector<size_t>{static_cast<size_t>(I)},
                std::vector<size_t>{static_cast<size_t>(D),
                  static_cast<size_t>(D)},
                std::vector<size_t>{static_cast<size_t>(N),
                  static_cast<size_t>(D)}};
    if (emit_transformed_parameters__) {
      std::vector<std::vector<size_t>>
        temp{std::vector<size_t>{static_cast<size_t>(I),
               static_cast<size_t>(D)},
             std::vector<size_t>{static_cast<size_t>(I),
               static_cast<size_t>(D)},
             std::vector<size_t>{static_cast<size_t>(I),
               static_cast<size_t>(max_poly)},
             std::vector<size_t>{static_cast<size_t>(N),
               static_cast<size_t>(D)}};
      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>(D),
               static_cast<size_t>(D)},
             std::vector<size_t>{static_cast<size_t>(N_obs)}};
      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__ <= a_free_size; ++sym1__) {
      param_names__.emplace_back(std::string() + "a_free" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= delta_neg_size; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta_neg" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= delta_pos_size; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta_pos" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= I; ++sym1__) {
      param_names__.emplace_back(std::string() + "neg_tau" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
      for (int sym2__ = 1; sym2__ <= D; ++sym2__) {
        param_names__.emplace_back(std::string() + "L_Corr" + '.' +
          std::to_string(sym2__) + '.' + std::to_string(sym1__));
      }
    }
    for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
      for (int sym2__ = 1; sym2__ <= N; ++sym2__) {
        param_names__.emplace_back(std::string() + "theta_raw" + '.' +
          std::to_string(sym2__) + '.' + std::to_string(sym1__));
      }
    }
    if (emit_transformed_parameters__) {
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
          param_names__.emplace_back(std::string() + "a" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
          param_names__.emplace_back(std::string() + "delta" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= max_poly; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
          param_names__.emplace_back(std::string() + "tau" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= N; ++sym2__) {
          param_names__.emplace_back(std::string() + "theta" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
    }
    if (emit_generated_quantities__) {
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= D; ++sym2__) {
          param_names__.emplace_back(std::string() + "Corr" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= N_obs; ++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__ <= a_free_size; ++sym1__) {
      param_names__.emplace_back(std::string() + "a_free" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= delta_neg_size; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta_neg" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= delta_pos_size; ++sym1__) {
      param_names__.emplace_back(std::string() + "delta_pos" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= I; ++sym1__) {
      param_names__.emplace_back(std::string() + "neg_tau" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= ((D * (D - 1)) / 2); ++sym1__) {
      param_names__.emplace_back(std::string() + "L_Corr" + '.' +
        std::to_string(sym1__));
    }
    for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
      for (int sym2__ = 1; sym2__ <= N; ++sym2__) {
        param_names__.emplace_back(std::string() + "theta_raw" + '.' +
          std::to_string(sym2__) + '.' + std::to_string(sym1__));
      }
    }
    if (emit_transformed_parameters__) {
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
          param_names__.emplace_back(std::string() + "a" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
          param_names__.emplace_back(std::string() + "delta" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= max_poly; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= I; ++sym2__) {
          param_names__.emplace_back(std::string() + "tau" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= N; ++sym2__) {
          param_names__.emplace_back(std::string() + "theta" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
    }
    if (emit_generated_quantities__) {
      for (int sym1__ = 1; sym1__ <= D; ++sym1__) {
        for (int sym2__ = 1; sym2__ <= D; ++sym2__) {
          param_names__.emplace_back(std::string() + "Corr" + '.' +
            std::to_string(sym2__) + '.' + std::to_string(sym1__));
        }
      }
      for (int sym1__ = 1; sym1__ <= N_obs; ++sym1__) {
        param_names__.emplace_back(std::string() + "log_lik" + '.' +
          std::to_string(sym1__));
      }
    }
  }
  inline std::string get_constrained_sizedtypes() const {
    return std::string("[{\"name\":\"a_free\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(a_free_size) + "},\"block\":\"parameters\"},{\"name\":\"delta_neg\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(delta_neg_size) + "},\"block\":\"parameters\"},{\"name\":\"delta_pos\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(delta_pos_size) + "},\"block\":\"parameters\"},{\"name\":\"neg_tau\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(I) + "},\"block\":\"parameters\"},{\"name\":\"L_Corr\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(D) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"parameters\"},{\"name\":\"theta_raw\",\"type\":{\"name\":\"array\",\"length\":" + std::to_string(N) + ",\"element_type\":{\"name\":\"vector\",\"length\":" + std::to_string(D) + "}},\"block\":\"parameters\"},{\"name\":\"a\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(I) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"transformed_parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(I) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"transformed_parameters\"},{\"name\":\"tau\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(I) + ",\"cols\":" + std::to_string(max_poly) + "},\"block\":\"transformed_parameters\"},{\"name\":\"theta\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(N) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"transformed_parameters\"},{\"name\":\"Corr\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(D) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"generated_quantities\"},{\"name\":\"log_lik\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(N_obs) + "},\"block\":\"generated_quantities\"}]");
  }
  inline std::string get_unconstrained_sizedtypes() const {
    return std::string("[{\"name\":\"a_free\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(a_free_size) + "},\"block\":\"parameters\"},{\"name\":\"delta_neg\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(delta_neg_size) + "},\"block\":\"parameters\"},{\"name\":\"delta_pos\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(delta_pos_size) + "},\"block\":\"parameters\"},{\"name\":\"neg_tau\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(I) + "},\"block\":\"parameters\"},{\"name\":\"L_Corr\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(((D * (D - 1)) /2)) + "},\"block\":\"parameters\"},{\"name\":\"theta_raw\",\"type\":{\"name\":\"array\",\"length\":" + std::to_string(N) + ",\"element_type\":{\"name\":\"vector\",\"length\":" + std::to_string(D) + "}},\"block\":\"parameters\"},{\"name\":\"a\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(I) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"transformed_parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(I) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"transformed_parameters\"},{\"name\":\"tau\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(I) + ",\"cols\":" + std::to_string(max_poly) + "},\"block\":\"transformed_parameters\"},{\"name\":\"theta\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(N) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"transformed_parameters\"},{\"name\":\"Corr\",\"type\":{\"name\":\"matrix\",\"rows\":" + std::to_string(D) + ",\"cols\":" + std::to_string(D) + "},\"block\":\"generated_quantities\"},{\"name\":\"log_lik\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(N_obs) + "},\"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__ = (((((a_free_size + delta_neg_size) +
      delta_pos_size) + I) + (D * D)) + (N * D));
    const size_t num_transformed = emit_transformed_parameters * (((((I * D)
      + (I * D)) + (I * max_poly)) + (N * D)));
    const size_t num_gen_quantities = emit_generated_quantities * (((D * D) +
      N_obs));
    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__ = (((((a_free_size + delta_neg_size) +
      delta_pos_size) + I) + (D * D)) + (N * D));
    const size_t num_transformed = emit_transformed_parameters * (((((I * D)
      + (I * D)) + (I * max_poly)) + (N * D)));
    const size_t num_gen_quantities = emit_generated_quantities * (((D * D) +
      N_obs));
    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_FCGGUM_namespace::model_FCGGUM;
#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_FCGGUM_namespace::profiles__;
}
#endif
#endif
