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