1 #ifndef BARRY_DEFM_MOTIF_FORMULA_HPP 
    2 #define BARRY_DEFM_MOTIF_FORMULA_HPP 
   48     std::vector< size_t > & locations,
 
   49     std::vector< bool > & signs,
 
   52     std::string & covar_name,
 
   60     std::regex pattern_intercept(
 
   61         std::string(
"\\{\\s*[01]?y[0-9]+(_[0-9]+)?(\\s*,\\s*[01]?y[0-9]+(_[0-9]+)?)*\\s*\\}") +
 
   62         std::string(
"(\\s*x\\s*[^\\s]+([(].+[)])?\\s*)?")
 
   64     std::regex pattern_transition(
 
   65         std::string(
"\\{\\s*[01]?y[0-9]+(_[0-9]+)?(\\s*,\\s*[01]?y[0-9]+(_[0-9]+)?)*\\}\\s*(>)\\s*") +
 
   66         std::string(
"\\{\\s*[01]?y[0-9]+(_[0-9]+)?(\\s*,\\s*[01]?y[0-9]+(_[0-9]+)?)*\\s*\\}") +
 
   67         std::string(
"(\\s*x\\s*[^\\s]+([(].+[)])?\\s*)?")
 
   70     auto empty = std::sregex_iterator();
 
   74     std::vector< bool > selected((m_order + 1) * y_ncol, 
false);
 
   77     std::regex_match(formula, match, pattern_transition);
 
   82             throw std::logic_error(
"Transition effects are only valid when the data is a markov process.");
 
   85         std::regex pattern_conditional(
".+[}]\\s+x\\s+([^(]+)([(][^)]+[)])?\\s*$");
 
   86         std::smatch condmatch;
 
   87         std::regex_match(formula, condmatch, pattern_conditional);
 
   89         if (!condmatch.empty())
 
   91             covar_name = condmatch[1].str();
 
   92             vname = condmatch[2].str();
 
   96                 vname = vname.substr(1, vname.size() - 2);
 
  101         size_t arrow_position = match.position(4u);
 
  104         std::regex pattern(
"(0?)y([0-9]+)(_([0-9]+))?");
 
  106         auto iter = std::sregex_iterator(formula.begin(), formula.end(), pattern);
 
  108         for (
auto i = iter; 
i != empty; ++
i)
 
  112             size_t current_location = 
i->position(0u);
 
  115             bool is_positive = 
true;
 
  116             if (
i->operator[](1u).str() == 
"0")
 
  120             size_t y_col = std::stoul(
i->operator[](2u).str());
 
  122                 throw std::logic_error(
"The proposed column is out of range.");
 
  126             std::string tmp_str = 
i->operator[](4u).str();
 
  133                     if (current_location > arrow_position)
 
  136                         throw std::logic_error(
"LHS of transition must specify time when m_order > 1");
 
  139                     y_row = std::stoul(tmp_str);
 
  142                     throw std::logic_error(
"The proposed row is out of range.");
 
  149                     y_row = std::stoul(tmp_str);
 
  151                     y_row = (current_location < arrow_position ? 0u: 1u);
 
  155             if (selected[y_col * (m_order + 1) + y_row])
 
  156                 throw std::logic_error(
 
  157                     "The term " + 
i->str() + 
" shows more than once in the formula.");
 
  161             if ((current_location > arrow_position) && (y_row != m_order))
 
  162                 throw std::logic_error(
 
  163                     "Only the row " + std::to_string(m_order) +
 
  164                     " can be specified at the RHS of the motif." 
  167             selected[y_col * (m_order + 1) + y_row] = 
true;
 
  169             locations.push_back(y_col * (m_order + 1) + y_row);
 
  170             signs.push_back(is_positive);
 
  179     std::regex_match(formula, match, pattern_intercept);
 
  184         std::regex pattern_conditional(
".+[}]\\s+x\\s+([^(]+)([(][^)]+[)])?\\s*$");
 
  185         std::smatch condmatch;
 
  186         std::regex_match(formula, condmatch, pattern_conditional);
 
  188         if (!condmatch.empty())
 
  190             covar_name = condmatch[1].str();
 
  191             vname = condmatch[2].str();
 
  195                 vname = vname.substr(1, vname.size() - 2);
 
  199         std::regex pattern(
"(0?)y([0-9]+)(_([0-9]+))?");
 
  201         auto iter = std::sregex_iterator(formula.begin(), formula.end(), pattern);
 
  203         for (
auto i = iter; 
i != empty; ++
i)
 
  207             bool is_positive = 
true;
 
  208             if (
i->operator[](1u).str() == 
"0")
 
  212             size_t y_col = std::stoul(
i->operator[](2u).str());
 
  214                 throw std::logic_error(
"The proposed column is out of range.");
 
  218             if (
i->operator[](4u).str() == 
"") 
 
  222                 y_row = std::stoul(
i->operator[](4u).str());
 
  224                 if (y_row != m_order)
 
  225                     throw std::logic_error(
 
  226                         std::string(
"Intercept motifs cannot feature past events. ") +
 
  227                         std::string(
"Only transition motifs can: {...} > {...}.")
 
  232             if (selected[y_col * (m_order + 1) + y_row])
 
  233                 throw std::logic_error(
 
  234                     "The term " + 
i->str() + 
" shows more than once in the formula.");
 
  236             selected[y_col * (m_order + 1) + y_row] = 
true;
 
  238             locations.push_back(y_col * (m_order + 1) + y_row);
 
  239             signs.push_back(is_positive);
 
  248     throw std::logic_error(
 
  249         "The motif specified in the formula: " + formula +
 
  250         " has the wrong syntax."