38 constexpr size_t NUM_LOOKUP_TERMS = Relation::NUM_LOOKUP_TERMS;
39 constexpr size_t NUM_TABLE_TERMS = Relation::NUM_TABLE_TERMS;
41 auto& inverse_polynomial = Relation::get_inverse_polynomial(polynomials);
42 const size_t offset =
std::max(inverse_polynomial.start_index(), start_index);
44 const size_t actual_size = inverse_polynomial.end_index() >
offset ? inverse_polynomial.end_index() -
offset : 0;
45 const auto compute_inverses = [&](
size_t start,
size_t end) {
46 for (
size_t i = start; i < end; ++i) {
47 const size_t row_idx = i +
offset;
49 auto row = polynomials.get_row(row_idx);
50 bool has_inverse = Relation::operation_exists_at_row(row);
55 bb::constexpr_for<0, NUM_LOOKUP_TERMS, 1>([&]<
size_t lookup_index> {
56 auto denominator_term =
57 Relation::template compute_lookup_term<Accumulator, lookup_index>(row, relation_parameters);
58 denominator *= denominator_term;
60 bb::constexpr_for<0, NUM_TABLE_TERMS, 1>([&]<
size_t table_index> {
61 auto denominator_term =
62 Relation::template compute_table_term<Accumulator, table_index>(row, relation_parameters);
63 denominator *= denominator_term;
65 inverse_polynomial.at(row_idx) = denominator;
68 FF* ffstart = &inverse_polynomial.
data()[start +
offset - inverse_polynomial.start_index()];
74 if constexpr (UseMultithreading) {
77 auto range = chunk.
range(actual_size);
79 size_t start = *range.begin();
80 size_t end = start + range.size();
81 compute_inverses(start, end);
85 compute_inverses(0, actual_size);
110 const AllEntities& in,
111 const Parameters& params,
112 const FF& scaling_factor)
114 constexpr size_t NUM_LOOKUP_TERMS = Relation::NUM_LOOKUP_TERMS;
115 constexpr size_t NUM_TABLE_TERMS = Relation::NUM_TABLE_TERMS;
118 using View =
typename Accumulator::View;
120 auto lookup_inverses = View(Relation::get_inverse_polynomial(in));
122 constexpr size_t NUM_TOTAL_TERMS = NUM_LOOKUP_TERMS + NUM_TABLE_TERMS;
136 bb::constexpr_for<0, NUM_LOOKUP_TERMS, 1>(
137 [&]<
size_t i>() { lookup_terms[i] = Relation::template compute_lookup_term<Accumulator, i>(in, params); });
138 bb::constexpr_for<0, NUM_TABLE_TERMS, 1>([&]<
size_t i>() {
139 lookup_terms[i + NUM_LOOKUP_TERMS] = Relation::template compute_table_term<Accumulator, i>(in, params);
143 bb::constexpr_for<0, NUM_TOTAL_TERMS, 1>([&]<
size_t i>() { denominator_accumulator[i] = lookup_terms[i]; });
145 [&]<
size_t i>() { denominator_accumulator[i + 1] *= denominator_accumulator[i]; });
148 auto inverse_accumulator = Accumulator(lookup_inverses);
149 const auto inverse_exists = Relation::template compute_inverse_exists<Accumulator>(in);
152 (denominator_accumulator[NUM_TOTAL_TERMS - 1] * lookup_inverses - inverse_exists) * scaling_factor;
155 for (
size_t i = NUM_TOTAL_TERMS - 1; i > 0; --i) {
157 denominator_accumulator[i] = denominator_accumulator[i - 1] * inverse_accumulator;
159 inverse_accumulator = inverse_accumulator * lookup_terms[i];
162 denominator_accumulator[0] = inverse_accumulator;
165 bb::constexpr_for<0, NUM_LOOKUP_TERMS, 1>([&]<
size_t i>() {
167 Relation::template get_lookup_term_predicate<Accumulator, i>(in) * denominator_accumulator[i];
170 bb::constexpr_for<0, NUM_TABLE_TERMS, 1>([&]<
size_t i>() {
171 auto to_subtract = Relation::template get_table_term_predicate<Accumulator, i>(in) *
172 denominator_accumulator[i + NUM_LOOKUP_TERMS];
173 if constexpr (!IsPermutation) {
175 to_subtract *= Relation::template lookup_read_counts<Accumulator, i>(in);
void _accumulate_logderivative_subrelation_contributions(ContainerOverSubrelations &accumulator, const AllEntities &in, const Parameters ¶ms, const FF &scaling_factor)
Unified implementation of log-derivative subrelation accumulation.