2 #define BARRAY_DEFM_H 1 
   27 #define MAKE_DEFM_HASHER(hasher,a,cov)                                  \ 
   28     barry::Hasher_fun_type<DEFMArray, DEFMCounterData>                  \ 
   29         hasher = [cov](const DEFMArray & array, DEFMCounterData * d) -> \ 
   30            std::vector< double > {                                      \ 
   31             std::vector< double > res;                                  \ 
   33             for (size_t i = 0u; i < array.nrow(); ++i)                  \ 
   34                 res.push_back(array.D()(i, cov));                       \ 
   36             for (size_t i = 0u; i < (array.nrow() - 1); ++i)            \ 
   37                 for (size_t j = 0u; j < array.ncol(); ++j)              \ 
   38                     res.push_back(array(i, j));                         \ 
   47 #define DEFM_COUNTER(a) \ 
   48 inline double (a) (const DEFMArray & Array, size_t i, size_t j, DEFMCounterData & data) 
   51 #define DEFM_COUNTER_LAMBDA(a) \ 
   52 barry::Counter_fun_type<DEFMArray, DEFMCounterData> a = \ 
   53     [](const DEFMArray & Array, size_t i, size_t j, DEFMCounterData & data) -> double 
   61 #define DEFM_RULE(a) \ 
   62 inline bool (a) (const DEFMArray & Array, size_t i, size_t j, bool & data) 
   65 #define DEFM_RULE_LAMBDA(a) \ 
   66 barry::Rule_fun_type<DEFMArray, DEFMRuleData> a = \ 
   67 [](const DEFMArray & Array, size_t i, size_t j, DEFMRuleData & data) -> bool 
   71 #define DEFM_RULEDYN_LAMBDA(a) \ 
   72 barry::Rule_fun_type<DEFMArray, DEFMRuleDynData> a = \ 
   73 [](const DEFMArray & Array, size_t i, size_t j, DEFMRuleDynData & data) -> bool 
   92     std::string vname = 
"",
 
   93     const std::vector< std::string > * x_names = 
nullptr 
  107             if (
i != (Array.nrow() - 1))
 
  110             return Array.D()(
i, 
data.idx(0u));
 
  116             if (x_names != 
nullptr)
 
  117                 vname = x_names->operator[](covar_index);
 
  119                 vname = std::string(
"attr")+ std::to_string(covar_index);
 
  123             counter_tmp, 
nullptr, 
hasher,
 
  125             "Num. of ones x " + vname, 
 
  126             "Overall number of ones" 
  137             if (
i != (Array.nrow() - 1))
 
  147             count_ones, 
nullptr, 
nullptr,
 
  150             "Overall number of ones" 
  173     std::vector< size_t > which = {},
 
  174     int covar_index = -1,
 
  175     std::string vname = 
"",
 
  176     const std::vector< std::string > * x_names = 
nullptr,
 
  177     const std::vector< std::string > * y_names = nullptr
 
  181     if (which.size() == 0u)
 
  183         which.resize(n_y, 0u);
 
  184         std::iota(which.begin(), which.end(), 0u);
 
  188                 throw std::logic_error(
"Values in `which` are out of range.");
 
  197             if (
i != (Array.nrow() - 1))
 
  200             if (
j != 
data.idx(0u))
 
  209             if (y_names != 
nullptr)
 
  210                 vname = y_names->operator[](
i);
 
  212                 vname = std::to_string(
i);
 
  215                 tmp_counter, 
nullptr, 
nullptr,
 
  217                 "Logit intercept " + vname, 
 
  218                 "Equal to one if the outcome " + vname + 
" is one. Equivalent to the logistic regression intercept." 
  227             if (
i != Array.nrow() - 1)
 
  230             if (
j != 
data.idx(0u))
 
  233             return Array.D()(
i, 
data.idx(1u));
 
  237         bool hasher_added = 
false;
 
  243             if (y_names != 
nullptr)
 
  244                 yname = y_names->operator[](
i);
 
  246                 yname = std::to_string(
i);
 
  250                 if (x_names != 
nullptr)
 
  251                     vname = x_names->operator[](covar_index);
 
  253                     vname = std::string(
"attr")+ std::to_string(covar_index);
 
  258                     tmp_counter, 
nullptr, 
nullptr,
 
  260                     "Logit intercept " + yname + 
" x " + vname, 
 
  261                     "Equal to one if the outcome " + yname + 
" is one. Equivalent to the logistic regression intercept." 
  268                     tmp_counter, 
nullptr, 
hasher,
 
  270                     "Logit intercept " + yname + 
" x " + vname, 
 
  271                     "Equal to one if the outcome " + yname + 
" is one. Equivalent to the logistic regression intercept." 
  291     std::vector< size_t > coords,
 
  292     std::vector< bool > signs,
 
  295     int covar_index = -1,
 
  296     std::string vname = 
"",
 
  297     const std::vector< std::string > * x_names = 
nullptr,
 
  298     const std::vector< std::string > * y_names = 
nullptr 
  303     if (signs.size() == 0u)
 
  304         signs.resize(coords.size(), 
true);
 
  305     else if (signs.size() != coords.size())
 
  306         throw std::length_error(
"Size of -coords- and -signs- must match.");
 
  308     if (covar_index >= 0)
 
  309         coords.push_back(
static_cast<size_t>(covar_index));
 
  311         coords.push_back(1000u);
 
  316         auto indices = 
data.indices;
 
  317         auto sgn     = 
data.logical;
 
  318         int covaridx = indices[indices.size() - 1u];
 
  324         for (
size_t k = 0u; k < (indices.size() - 1u); ++k)
 
  326             if (indices[k] >= (Array.ncol()* Array.nrow()))
 
  327                 throw std::range_error(
"The motif includes entries out of range.");
 
  331         const auto & array = Array.get_data();
 
  332         for (
size_t k = 0u; k < (indices.size() - 1); ++k)
 
  334             auto cellv = array[indices[k]];
 
  335             if (sgn[k] && (cellv != 1))
 
  340         return (covaridx < 1000) ? Array.D()(Array.nrow() - 1u, covaridx) : 1.0;
 
  347         auto dat = 
data.indices;
 
  348         auto sgn = 
data.logical;
 
  349         int covaridx = dat[dat.size() - 1u];
 
  352         const auto & array = Array.get_data();
 
  353         size_t loc = 
i + 
j * Array.nrow();
 
  354         size_t n_cells = dat.size() - 1u;
 
  359         bool baseline_value = 
false;
 
  360         bool i_in_array = 
false;
 
  361         for (
size_t e = 0u; e < n_cells; ++e)
 
  368                 baseline_value = sgn[e];
 
  371             if ((sgn[e] && (array[dat[e]] == 1)) || (!sgn[e] && (array[dat[e]] == 0)))
 
  380         size_t n_prev = n_now;
 
  390             double val = Array.D()(Array.nrow() - 1u, covaridx);
 
  391             double value_now  = n_now == n_cells ?  val : 0.0;
 
  392             double value_prev = n_prev == n_cells ? val : 0.0;
 
  394             return value_now - value_prev;
 
  400             double value_now  = n_now == n_cells ? 1.0 : 0.0;
 
  401             double value_prev = n_prev == n_cells ? 1.0 : 0.0;
 
  403             return value_now - value_prev;
 
  411     if (coords.size() == 1u)
 
  417     barry::BArrayDense<int> motif(m_order + 1u, n_y, 0);
 
  421     size_t n_cells = coords.size() - 1u;
 
  422     for (
size_t d = 0u; d < n_cells; ++d)
 
  424         size_t c = std::floor(coords[d] / (m_order + 1u));
 
  425         size_t r = coords[d] - c * (m_order + 1u);
 
  426         motif(r, c) = signs[d] ? 1 : -1;
 
  431     bool any_before_event = 
false;
 
  433     for (
size_t i = 0u; 
i < m_order; ++
i)
 
  435         for (
size_t j = 0u; 
j < n_y; ++
j)
 
  439                 any_before_event = 
true;
 
  446     #ifdef BARRY_WITH_LATEX 
  450     if (any_before_event)
 
  451         #ifdef BARRY_WITH_LATEX 
  457     #ifdef BARRY_WITH_LATEX 
  460                 ((a) == 0) ? "_0" : (\
 
  461                 ((a) == 1) ? "_1" : (\
 
  462                 ((a) == 2) ? "_2" : (\
 
  463                 ((a) == 3) ? "_3" : (\
 
  464                 ((a) == 4) ? "_4" : (\
 
  465                 ((a) == 5) ? "_5" : (\
 
  466                 ((a) == 6) ? "_6" : (\
 
  467                 ((a) == 7) ? "_7" : (\
 
  468                 ((a) == 8) ? "_8" : \
 
  474                 ((a) == 0) ? u8"\u2080" : (\
 
  475                 ((a) == 1) ? u8"\u2081" : (\
 
  476                 ((a) == 2) ? u8"\u2082" : (\
 
  477                 ((a) == 3) ? u8"\u2083" : (\
 
  478                 ((a) == 4) ? u8"\u2084" : (\
 
  479                 ((a) == 5) ? u8"\u2085" : (\
 
  480                 ((a) == 6) ? u8"\u2086" : (\
 
  481                 ((a) == 7) ? u8"\u2087" : (\
 
  482                 ((a) == 8) ? u8"\u2088" : \
 
  488     for (
size_t i = 0u; 
i < m_order; ++
i)
 
  491         bool row_start = 
true;
 
  492         for (
size_t j = 0u; 
j < n_y; ++
j)
 
  505             if (y_names != 
nullptr)
 
  506                 name += y_names->operator[](
j);
 
  508                 name += (std::string(
"y") + std::to_string(
j));
 
  510             #ifdef BARRY_WITH_LATEX 
  511                 name += (motif(
i,
j) < 0 ? 
"^-" : 
"^+");
 
  513                 name += (motif(
i,
j) < 0 ? u8
"\u207B" : u8
"\u207A");
 
  521     if (any_before_event & (m_order > 0u))
 
  522         #ifdef BARRY_WITH_LATEX
 
  525             name += std::string(
"}") + u8
"\u21E8" + std::string(
"{");
 
  528         #ifdef BARRY_WITH_LATEX 
  535     bool row_start = 
true;
 
  536     for (
size_t j = 0u; 
j < n_y; ++
j)
 
  539         if (motif(m_order, 
j) == 0)
 
  547         if (y_names != 
nullptr)
 
  548             name += y_names->operator[](
j);
 
  550             name += (std::string(
"y") + std::to_string(
j));
 
  552         #ifdef BARRY_WITH_LATEX 
  553         name += (motif(m_order, 
j) < 0 ? 
"^-" : 
"^+" );
 
  555         name += (motif(m_order, 
j) < 0 ? u8
"\u207B" : u8
"\u207A" );
 
  563     #ifdef BARRY_WITH_LATEX 
  569     if (covar_index >= 0)
 
  576             if (x_names != 
nullptr)
 
  577                 vname = x_names->operator[](covar_index);
 
  579                 vname = std::string(
"attr")+ std::to_string(covar_index);
 
  583             count_ones, count_init, 
hasher,
 
  585             name + 
" x " + vname, 
 
  586             "Motif weighted by single attribute" 
  592             count_ones, count_init, 
nullptr,
 
  616     int covar_index = -1,
 
  617     std::string vname = 
"",
 
  618     const std::vector< std::string > * x_names = 
nullptr,
 
  619     const std::vector< std::string > * y_names = 
nullptr 
  622     std::vector< size_t > coords;
 
  623     std::vector< bool > signs;
 
  624     std::string covar_name = 
"";
 
  627         formula, coords, signs, m_order, n_y, covar_name, vname
 
  630     if ((covar_name != 
"") && (covar_index >= 0))
 
  631         throw std::logic_error(
"Can't have both a formula and a covariate index.");
 
  633     if (covar_name != 
"")
 
  636         if (x_names != 
nullptr)
 
  638             for (
size_t i = 0u; 
i < x_names->size(); ++
i)
 
  639                 if (x_names->operator[](
i) == covar_name)
 
  641                     covar_index = 
static_cast<int>(
i);
 
  647             throw std::logic_error(
 
  648                 std::string(
"The covariate name '") +
 
  650                 std::string(
"' was not found in the list of covariates.")
 
  656     if (coords.size() == 1u)
 
  660         size_t coord = 
static_cast< size_t >(
 
  662             static_cast<double>(coords[0u]) / 
static_cast<double>(m_order + 1)
 
  678             counters, coords, signs, m_order, n_y, covar_index, vname,
 
  697     std::string vname = 
"",
 
  698     const std::vector< std::string > * x_names = 
nullptr 
  704         return std::pow(Array.D()((
size_t) 
i, 
data.idx(0u)), 
data.num(0u));
 
  714     if (x_names != 
nullptr)
 
  715         vname = x_names->operator[](covar_index);
 
  717         vname = std::string(
"attr")+ std::to_string(covar_index);
 
  720         count_tmp, count_init, 
hasher,
 
  722         "Fixed effect feature (" + vname + 
")^" + std::to_string(k)
 
  742         return i >= 
data.idx(0u);
 
  748         std::string(
"Markov model of order ") + std::to_string(markov_order),
 
  749         std::string(
"Blocks the first morder cells of the array.")
 
  763     std::vector<size_t> ids
 
  770             std::vector< size_t > tmp(Array.ncol(), 0u);
 
  772             for (
auto v : 
data.indices)
 
  774                 if (v >= Array.ncol())
 
  775                     throw std::range_error(
"The specified id for `dont_become_zero` is out of range.");
 
  780             data.indices.resize(Array.ncol());
 
  781             for (
size_t v = 0u; v < tmp.size(); ++v)
 
  782                 data.indices[v] = tmp[v];
 
  788         if (
data.indices[
j] == 0u)
 
  792         if (
i != (Array.nrow() - 1))
 
  797         return (Array(
i - 1, 
j) != 1) || (Array(
i, 
j) != 1);
 
  801     support->get_rules()->add_rule(
 
  804         std::string(
"Ones can't become zero"),
 
  805         std::string(
"Blocks cells that have became equal to one.")
 
  841     support->get_rules_dyn()->add_rule(
 
  844             support->get_current_stats(),
 
  847         support->get_counters()->get_names()[pos] +
 
  848             "' within [" + std::to_string(lb) + 
", " +
 
  849             std::to_string(ub) + std::string(
"]"),
 
  850         std::string(
"When the support is ennumerated, only states where the statistic '") + 
 
  851             support->get_counters()->get_names()[pos] +
 
  852             std::to_string(pos) + 
"' falls within [" + std::to_string(lb) + 
", " +
 
  853             std::to_string(ub) + 
"] are included." 
Data class used to store arbitrary size_t or double vectors.
 
Data_Type &&counter_ name(std::move(counter_.name))
 
Data_Type &&counter_ data(std::move(counter_.data))
 
Data_Type hasher(counter_.hasher)
 
#define DEFM_COUNTER_LAMBDA(a)
 
#define DEFM_RULE_LAMBDA(a)
 
#define DEFM_RULEDYN_LAMBDA(a)
 
void counter_transition(DEFMCounters *counters, std::vector< size_t > coords, std::vector< bool > signs, size_t m_order, size_t n_y, int covar_index=-1, std::string vname="", const std::vector< std::string > *x_names=nullptr, const std::vector< std::string > *y_names=nullptr)
Prevalence of ones.
 
void rules_markov_fixed(DEFMRules *rules, size_t markov_order)
Number of edges.
 
void counter_ones(DEFMCounters *counters, int covar_index=-1, std::string vname="", const std::vector< std::string > *x_names=nullptr)
Prevalence of ones.
 
void counter_fixed_effect(DEFMCounters *counters, int covar_index, double k, std::string vname="", const std::vector< std::string > *x_names=nullptr)
Prevalence of ones.
 
void counter_logit_intercept(DEFMCounters *counters, size_t n_y, std::vector< size_t > which={}, int covar_index=-1, std::string vname="", const std::vector< std::string > *x_names=nullptr, const std::vector< std::string > *y_names=nullptr)
 
void rule_constrain_support(DEFMSupport *support, size_t pos, double lb, double ub)
Overall functional gains.
 
void rules_dont_become_zero(DEFMSupport *support, std::vector< size_t > ids)
Blocks switching a one to zero.
 
void counter_transition_formula(DEFMCounters *counters, std::string formula, size_t m_order, size_t n_y, int covar_index=-1, std::string vname="", const std::vector< std::string > *x_names=nullptr, const std::vector< std::string > *y_names=nullptr)
Prevalence of ones.
 
#define MAKE_DEFM_HASHER(hasher, a, cov)
Data for the counters.
 
bool is_motif
If false, then is a logit intercept.
 
barry::Counters< DEFMArray, DEFMCounterData > DEFMCounters
 
barry::Rules< DEFMArray, DEFMRuleData > DEFMRules
 
barry::Support< DEFMArray, DEFMCounterData, DEFMRuleData, DEFMRuleDynData > DEFMSupport