36 constexpr size_t NUM_LOOKUP_TERMS = Relation::NUM_LOOKUP_TERMS;
37 constexpr size_t NUM_TABLE_TERMS = Relation::NUM_TABLE_TERMS;
39 auto& inverse_polynomial = Relation::get_inverse_polynomial(polynomials);
40 const size_t offset = inverse_polynomial.start_index();
41 const auto compute_inverses = [&](
size_t start,
size_t end) {
42 for (
size_t i = start; i < end; ++i) {
44 auto row = polynomials.get_row(i +
offset);
45 bool has_inverse = Relation::operation_exists_at_row(row);
50 bb::constexpr_for<0, NUM_LOOKUP_TERMS, 1>([&]<
size_t lookup_index> {
51 auto denominator_term =
52 Relation::template compute_lookup_term<Accumulator, lookup_index>(row, relation_parameters);
53 denominator *= denominator_term;
55 bb::constexpr_for<0, NUM_TABLE_TERMS, 1>([&]<
size_t table_index> {
56 auto denominator_term =
57 Relation::template compute_table_term<Accumulator, table_index>(row, relation_parameters);
58 denominator *= denominator_term;
60 inverse_polynomial.at(i) = denominator;
62 FF* ffstart = &inverse_polynomial.coeffs()[start];
68 if constexpr (UseMultithreading) {
70 auto range = chunk.
range(circuit_size);
72 size_t start = *range.begin();
73 size_t end = start + range.size();
74 compute_inverses(start, end);
78 compute_inverses(0, inverse_polynomial.size());
103 const AllEntities& in,
104 const Parameters& params,
105 const FF& scaling_factor)
107 constexpr size_t NUM_LOOKUP_TERMS = Relation::NUM_LOOKUP_TERMS;
108 constexpr size_t NUM_TABLE_TERMS = Relation::NUM_TABLE_TERMS;
111 using View =
typename Accumulator::View;
113 auto lookup_inverses = View(Relation::get_inverse_polynomial(in));
115 constexpr size_t NUM_TOTAL_TERMS = NUM_LOOKUP_TERMS + NUM_TABLE_TERMS;
129 bb::constexpr_for<0, NUM_LOOKUP_TERMS, 1>(
130 [&]<
size_t i>() { lookup_terms[i] = Relation::template compute_lookup_term<Accumulator, i>(in, params); });
131 bb::constexpr_for<0, NUM_TABLE_TERMS, 1>([&]<
size_t i>() {
132 lookup_terms[i + NUM_LOOKUP_TERMS] = Relation::template compute_table_term<Accumulator, i>(in, params);
136 bb::constexpr_for<0, NUM_TOTAL_TERMS, 1>([&]<
size_t i>() { denominator_accumulator[i] = lookup_terms[i]; });
138 [&]<
size_t i>() { denominator_accumulator[i + 1] *= denominator_accumulator[i]; });
141 auto inverse_accumulator = Accumulator(lookup_inverses);
142 const auto inverse_exists = Relation::template compute_inverse_exists<Accumulator>(in);
145 (denominator_accumulator[NUM_TOTAL_TERMS - 1] * lookup_inverses - inverse_exists) * scaling_factor;
148 for (
size_t i = NUM_TOTAL_TERMS - 1; i > 0; --i) {
150 denominator_accumulator[i] = denominator_accumulator[i - 1] * inverse_accumulator;
152 inverse_accumulator = inverse_accumulator * lookup_terms[i];
155 denominator_accumulator[0] = inverse_accumulator;
158 bb::constexpr_for<0, NUM_LOOKUP_TERMS, 1>([&]<
size_t i>() {
160 Relation::template get_lookup_term_predicate<Accumulator, i>(in) * denominator_accumulator[i];
163 bb::constexpr_for<0, NUM_TABLE_TERMS, 1>([&]<
size_t i>() {
164 auto to_subtract = Relation::template get_table_term_predicate<Accumulator, i>(in) *
165 denominator_accumulator[i + NUM_LOOKUP_TERMS];
166 if constexpr (!IsPermutation) {
168 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.