From 140b0426d6ce7504d0b99af66f7d970acad6cab5 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Thu, 11 Jul 2024 11:47:54 +0000 Subject: [PATCH 1/4] fix: Lagrange interpolation bug --- .../polynomials/polynomial_arithmetic.cpp | 74 +++++++++++++++++++ .../polynomial_arithmetic.test.cpp | 55 ++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp index 0694349f95d..830cbcda7a3 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp @@ -1210,6 +1210,11 @@ template Fr compute_sum(const Fr* src, const size_t n) // This function computes the polynomial (x - a)(x - b)(x - c)... given n distinct roots (a, b, c, ...). template void compute_linear_polynomial_product(const Fr* roots, Fr* dest, const size_t n) { +<<<<<<< HEAD +======= + for (size_t i = 0; i < n; ++i) { + }; +>>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) auto scratch_space_ptr = get_scratch_space(n); auto scratch_space = scratch_space_ptr.get(); memcpy((void*)scratch_space, (void*)roots, n * sizeof(Fr)); @@ -1328,15 +1333,23 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati */ Fr numerator_polynomial[n + 1]; polynomial_arithmetic::compute_linear_polynomial_product(evaluation_points, numerator_polynomial, n); +<<<<<<< HEAD +======= + // First half contains roots, second half contains denominators (to be inverted) +>>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) Fr roots_and_denominators[2 * n]; Fr temp_src[n]; for (size_t i = 0; i < n; ++i) { roots_and_denominators[i] = -evaluation_points[i]; temp_src[i] = src[i]; dest[i] = 0; +<<<<<<< HEAD // compute constant denominator +======= + // compute constant denominators +>>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) roots_and_denominators[n + i] = 1; for (size_t j = 0; j < n; ++j) { if (j == i) { @@ -1345,11 +1358,17 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati roots_and_denominators[n + i] *= (evaluation_points[i] - evaluation_points[j]); } } +<<<<<<< HEAD +======= + // at this point roots_and_denominators is populated as follows + // (x_0,\ldots, x_{n-1}, d_0, \ldots, d_{n-1}) +>>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) Fr::batch_invert(roots_and_denominators, 2 * n); Fr z, multiplier; Fr temp_dest[n]; +<<<<<<< HEAD for (size_t i = 0; i < n; ++i) { z = roots_and_denominators[i]; multiplier = temp_src[i] * roots_and_denominators[n + i]; @@ -1360,6 +1379,61 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati temp_dest[j] = multiplier * numerator_polynomial[j] - temp_dest[j - 1]; temp_dest[j] *= z; dest[j] += temp_dest[j]; +======= + size_t idx_zero = 0; + bool interpolation_domain_contains_zero = false; + if (numerator_polynomial[0] == Fr(0)) { + for (size_t i = 0; i < n; ++i) { + if (evaluation_points[i] == Fr(0)) { + idx_zero = i; + interpolation_domain_contains_zero = true; + break; + } + } + }; + if (!interpolation_domain_contains_zero) { + for (size_t i = 0; i < n; ++i) { + // set z = - 1/x_i for x_i <> 0 + z = roots_and_denominators[i]; + // temp_src[i] is y_i, it gets multiplied by 1/d_i + multiplier = temp_src[i] * roots_and_denominators[n + i]; + temp_dest[0] = multiplier * numerator_polynomial[0]; + temp_dest[0] *= z; + dest[0] += temp_dest[0]; + for (size_t j = 1; j < n; ++j) { + temp_dest[j] = multiplier * numerator_polynomial[j] - temp_dest[j - 1]; + temp_dest[j] *= z; + dest[j] += temp_dest[j]; + } + } + } else { + for (size_t i = 0; i < n; ++i) { + if (i == idx_zero) { + // the contribution from the term corresponding to idx_zero is computed separately + continue; + } else { + // get the next inverted root + z = roots_and_denominators[i]; + // compute f(x_i) * d_{x_i}^{-1} + multiplier = temp_src[i] * roots_and_denominators[n + i]; + // get x_i^{-1} * f(x_i) * d_{x_i}^{-1} into the "free" term + temp_dest[1] = multiplier * numerator_polynomial[1]; + temp_dest[1] *= z; + // correct the first coefficient as it is now accumulating free terms from + // f(x_i) d_i^{-1} prod_(X-x_i, x_i <> 0) (X-x_i) * 1/(X-x_i) + dest[1] += temp_dest[1]; + // compute the quotient N(X)/(X-x_i) f(x_i)/d_{x_i} and its contribution to the target coefficients + for (size_t j = 2; j < n; ++j) { + temp_dest[j] = multiplier * numerator_polynomial[j] - temp_dest[j - 1]; + temp_dest[j] *= z; + dest[j] += temp_dest[j]; + }; + } + } + // correct the target coefficients by the contribution from N(X)/X * d_{idx_zero}^{-1} * f(idx_zero) + for (size_t i = 0; i < n; ++i) { + dest[i] += temp_src[idx_zero] * roots_and_denominators[n + idx_zero] * numerator_polynomial[i + 1]; +>>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) } } } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp index 16281c3a650..9bd6d99553f 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp @@ -999,6 +999,61 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation) EXPECT_EQ(src[i], poly[i]); } } +<<<<<<< HEAD +======= +// Test efficient Lagrange interpolation when interpolation points contain 0 +TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero) +{ + using FF = TypeParam; + constexpr size_t n = 15; + FF src[n], poly[n], x[n]; + + for (size_t i = 0; i < n; ++i) { + poly[i] = FF(i + 1); + } + + for (size_t i = 0; i < n; ++i) { + x[i] = FF(i); + src[i] = polynomial_arithmetic::evaluate(poly, x[i], n); + } + polynomial_arithmetic::compute_efficient_interpolation(src, src, x, n); + + for (size_t i = 0; i < n; ++i) { + EXPECT_EQ(src[i], poly[i]); + } + // Test for the domain (-n/2, ..., 0, ... , n/2) + + for (size_t i = 0; i < n; ++i) { + poly[i] = FF(i + 54); + } + + for (size_t i = 0; i < n; ++i) { + x[i] = FF(i - n / 2); + src[i] = polynomial_arithmetic::evaluate(poly, x[i], n); + } + polynomial_arithmetic::compute_efficient_interpolation(src, src, x, n); + + for (size_t i = 0; i < n; ++i) { + EXPECT_EQ(src[i], poly[i]); + } + + // Test for the domain (-n+1, ..., 0) + + for (size_t i = 0; i < n; ++i) { + poly[i] = FF(i * i + 57); + } + + for (size_t i = 0; i < n; ++i) { + x[i] = FF(i - (n - 1)); + src[i] = polynomial_arithmetic::evaluate(poly, x[i], n); + } + polynomial_arithmetic::compute_efficient_interpolation(src, src, x, n); + + for (size_t i = 0; i < n; ++i) { + EXPECT_EQ(src[i], poly[i]); + } +} +>>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) TYPED_TEST(PolynomialTests, interpolation_constructor_single) { From 08f9284bfa72b9c5ca6fff3894a287a3de98db94 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Thu, 11 Jul 2024 12:05:47 +0000 Subject: [PATCH 2/4] resolved merge conflicts --- .../polynomials/polynomial_arithmetic.cpp | 29 ------------------- .../polynomial_arithmetic.test.cpp | 3 -- 2 files changed, 32 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp index 830cbcda7a3..7e48f5ea7d8 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp @@ -1210,11 +1210,8 @@ template Fr compute_sum(const Fr* src, const size_t n) // This function computes the polynomial (x - a)(x - b)(x - c)... given n distinct roots (a, b, c, ...). template void compute_linear_polynomial_product(const Fr* roots, Fr* dest, const size_t n) { -<<<<<<< HEAD -======= for (size_t i = 0; i < n; ++i) { }; ->>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) auto scratch_space_ptr = get_scratch_space(n); auto scratch_space = scratch_space_ptr.get(); memcpy((void*)scratch_space, (void*)roots, n * sizeof(Fr)); @@ -1333,23 +1330,14 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati */ Fr numerator_polynomial[n + 1]; polynomial_arithmetic::compute_linear_polynomial_product(evaluation_points, numerator_polynomial, n); -<<<<<<< HEAD - -======= // First half contains roots, second half contains denominators (to be inverted) ->>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) Fr roots_and_denominators[2 * n]; Fr temp_src[n]; for (size_t i = 0; i < n; ++i) { roots_and_denominators[i] = -evaluation_points[i]; temp_src[i] = src[i]; dest[i] = 0; -<<<<<<< HEAD - - // compute constant denominator -======= // compute constant denominators ->>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) roots_and_denominators[n + i] = 1; for (size_t j = 0; j < n; ++j) { if (j == i) { @@ -1358,28 +1346,12 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati roots_and_denominators[n + i] *= (evaluation_points[i] - evaluation_points[j]); } } -<<<<<<< HEAD - -======= // at this point roots_and_denominators is populated as follows // (x_0,\ldots, x_{n-1}, d_0, \ldots, d_{n-1}) ->>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) Fr::batch_invert(roots_and_denominators, 2 * n); Fr z, multiplier; Fr temp_dest[n]; -<<<<<<< HEAD - for (size_t i = 0; i < n; ++i) { - z = roots_and_denominators[i]; - multiplier = temp_src[i] * roots_and_denominators[n + i]; - temp_dest[0] = multiplier * numerator_polynomial[0]; - temp_dest[0] *= z; - dest[0] += temp_dest[0]; - for (size_t j = 1; j < n; ++j) { - temp_dest[j] = multiplier * numerator_polynomial[j] - temp_dest[j - 1]; - temp_dest[j] *= z; - dest[j] += temp_dest[j]; -======= size_t idx_zero = 0; bool interpolation_domain_contains_zero = false; if (numerator_polynomial[0] == Fr(0)) { @@ -1433,7 +1405,6 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati // correct the target coefficients by the contribution from N(X)/X * d_{idx_zero}^{-1} * f(idx_zero) for (size_t i = 0; i < n; ++i) { dest[i] += temp_src[idx_zero] * roots_and_denominators[n + idx_zero] * numerator_polynomial[i + 1]; ->>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) } } } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp index 9bd6d99553f..60bb486afde 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp @@ -999,8 +999,6 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation) EXPECT_EQ(src[i], poly[i]); } } -<<<<<<< HEAD -======= // Test efficient Lagrange interpolation when interpolation points contain 0 TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero) { @@ -1053,7 +1051,6 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero) EXPECT_EQ(src[i], poly[i]); } } ->>>>>>> 2b46301b74 (WIP: 812fc71d08 applied stashed changes + resolved conflicts) TYPED_TEST(PolynomialTests, interpolation_constructor_single) { From 39da47052c69ad66e2961c21b03a1686dc464c99 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Fri, 12 Jul 2024 09:45:12 +0000 Subject: [PATCH 3/4] resolved comments --- .../polynomials/polynomial_arithmetic.cpp | 62 ++++++++++++------- .../polynomial_arithmetic.test.cpp | 20 +++--- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp index 7e48f5ea7d8..96f6edd4ab9 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp @@ -1210,8 +1210,7 @@ template Fr compute_sum(const Fr* src, const size_t n) // This function computes the polynomial (x - a)(x - b)(x - c)... given n distinct roots (a, b, c, ...). template void compute_linear_polynomial_product(const Fr* roots, Fr* dest, const size_t n) { - for (size_t i = 0; i < n; ++i) { - }; + auto scratch_space_ptr = get_scratch_space(n); auto scratch_space = scratch_space_ptr.get(); memcpy((void*)scratch_space, (void*)roots, n * sizeof(Fr)); @@ -1326,7 +1325,24 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati N(X) = ∏_{i \in [n]} (X - xi), di = ∏_{j != i} (xi - xj) For division of N(X) by (X - xi), we use the same trick that was used in compute_opening_polynomial() - function in the kate commitment scheme. + function in the Kate commitment scheme. + We denote + q_{x_i} = N(X)/(X-x_i) * y_i * (d_i)^{-1} = q_{x_i,0}*1 + ... + q_{x_i,n-1} * X^{n-1} for i=0,..., n-1. + + The computation of F(X) is split into two cases: + + - if 0 is not in the interpolation domain, then the numerator polynomial N(X) has a non-zero constant term + that is used to initialize the division algorithm mentioned above; the monomial coefficients q_{x_i, j} of + q_{x_i} are accumulated into dest[j] for j=0,..., n-1 + + - if 0 is in the domain at index i_0, the constant term of N(X) is 0 and the division algorithm computing + q_{x_i} for i != i_0 is initialized with the constant term of N(X)/X. Note that its coefficients are given + by numerator_polynommial[j] for j=1,...,n. The monomial coefficients of q_{x_i} are then accumuluated in + dest[j] for j=1,..., n-1. Whereas the coefficients of + q_{0} = N(X)/X * f(0) * (d_{i_0})^{-1} + are added to dest[j] for j=0,..., n-1. Note that these coefficients do not require performing the division + algorithm used in Kate commitment scheme, as the coefficients of N(X)/X are given by numerator_polynomial[j] + for j=1,...,n. */ Fr numerator_polynomial[n + 1]; polynomial_arithmetic::compute_linear_polynomial_product(evaluation_points, numerator_polynomial, n); @@ -1354,6 +1370,8 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati Fr temp_dest[n]; size_t idx_zero = 0; bool interpolation_domain_contains_zero = false; + // if the constant term of the numerator polynomial N(X) is 0, then the interpolation domain contains 0 + // we find the index i_0, such that x_{i_0} = 0 if (numerator_polynomial[0] == Fr(0)) { for (size_t i = 0; i < n; ++i) { if (evaluation_points[i] == Fr(0)) { @@ -1363,6 +1381,7 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati } } }; + if (!interpolation_domain_contains_zero) { for (size_t i = 0; i < n; ++i) { // set z = - 1/x_i for x_i <> 0 @@ -1381,28 +1400,27 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati } else { for (size_t i = 0; i < n; ++i) { if (i == idx_zero) { - // the contribution from the term corresponding to idx_zero is computed separately + // the contribution from the term corresponding to i_0 is computed separately continue; - } else { - // get the next inverted root - z = roots_and_denominators[i]; - // compute f(x_i) * d_{x_i}^{-1} - multiplier = temp_src[i] * roots_and_denominators[n + i]; - // get x_i^{-1} * f(x_i) * d_{x_i}^{-1} into the "free" term - temp_dest[1] = multiplier * numerator_polynomial[1]; - temp_dest[1] *= z; - // correct the first coefficient as it is now accumulating free terms from - // f(x_i) d_i^{-1} prod_(X-x_i, x_i <> 0) (X-x_i) * 1/(X-x_i) - dest[1] += temp_dest[1]; - // compute the quotient N(X)/(X-x_i) f(x_i)/d_{x_i} and its contribution to the target coefficients - for (size_t j = 2; j < n; ++j) { - temp_dest[j] = multiplier * numerator_polynomial[j] - temp_dest[j - 1]; - temp_dest[j] *= z; - dest[j] += temp_dest[j]; - }; } + // get the next inverted root + z = roots_and_denominators[i]; + // compute f(x_i) * d_{x_i}^{-1} + multiplier = temp_src[i] * roots_and_denominators[n + i]; + // get x_i^{-1} * f(x_i) * d_{x_i}^{-1} into the "free" term + temp_dest[1] = multiplier * numerator_polynomial[1]; + temp_dest[1] *= z; + // correct the first coefficient as it is now accumulating free terms from + // f(x_i) d_i^{-1} prod_(X-x_i, x_i != 0) (X-x_i) * 1/(X-x_i) + dest[1] += temp_dest[1]; + // compute the quotient N(X)/(X-x_i) f(x_i)/d_{x_i} and its contribution to the target coefficients + for (size_t j = 2; j < n; ++j) { + temp_dest[j] = multiplier * numerator_polynomial[j] - temp_dest[j - 1]; + temp_dest[j] *= z; + dest[j] += temp_dest[j]; + }; } - // correct the target coefficients by the contribution from N(X)/X * d_{idx_zero}^{-1} * f(idx_zero) + // correct the target coefficients by the contribution from q_{0} = N(X)/X * d_{i_0}^{-1} * f(0) for (size_t i = 0; i < n; ++i) { dest[i] += temp_src[idx_zero] * roots_and_denominators[n + idx_zero] * numerator_polynomial[i + 1]; } diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp index 60bb486afde..0a58f36b9b3 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.test.cpp @@ -983,7 +983,7 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation) { using FF = TypeParam; constexpr size_t n = 250; - FF src[n], poly[n], x[n]; + std::array src, poly, x; for (size_t i = 0; i < n; ++i) { poly[i] = FF::random_element(); @@ -991,9 +991,9 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation) for (size_t i = 0; i < n; ++i) { x[i] = FF::random_element(); - src[i] = polynomial_arithmetic::evaluate(poly, x[i], n); + src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n); } - polynomial_arithmetic::compute_efficient_interpolation(src, src, x, n); + polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n); for (size_t i = 0; i < n; ++i) { EXPECT_EQ(src[i], poly[i]); @@ -1004,7 +1004,7 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero) { using FF = TypeParam; constexpr size_t n = 15; - FF src[n], poly[n], x[n]; + std::array src, poly, x; for (size_t i = 0; i < n; ++i) { poly[i] = FF(i + 1); @@ -1012,9 +1012,9 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero) for (size_t i = 0; i < n; ++i) { x[i] = FF(i); - src[i] = polynomial_arithmetic::evaluate(poly, x[i], n); + src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n); } - polynomial_arithmetic::compute_efficient_interpolation(src, src, x, n); + polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n); for (size_t i = 0; i < n; ++i) { EXPECT_EQ(src[i], poly[i]); @@ -1027,9 +1027,9 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero) for (size_t i = 0; i < n; ++i) { x[i] = FF(i - n / 2); - src[i] = polynomial_arithmetic::evaluate(poly, x[i], n); + src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n); } - polynomial_arithmetic::compute_efficient_interpolation(src, src, x, n); + polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n); for (size_t i = 0; i < n; ++i) { EXPECT_EQ(src[i], poly[i]); @@ -1043,9 +1043,9 @@ TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero) for (size_t i = 0; i < n; ++i) { x[i] = FF(i - (n - 1)); - src[i] = polynomial_arithmetic::evaluate(poly, x[i], n); + src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n); } - polynomial_arithmetic::compute_efficient_interpolation(src, src, x, n); + polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n); for (size_t i = 0; i < n; ++i) { EXPECT_EQ(src[i], poly[i]); From 3e79a057574cb4791f860cf42ce650a741caf591 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Fri, 12 Jul 2024 15:52:40 +0000 Subject: [PATCH 4/4] fixed the typo --- .../cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp index 96f6edd4ab9..62ab0623735 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial_arithmetic.cpp @@ -1337,7 +1337,7 @@ void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluati - if 0 is in the domain at index i_0, the constant term of N(X) is 0 and the division algorithm computing q_{x_i} for i != i_0 is initialized with the constant term of N(X)/X. Note that its coefficients are given - by numerator_polynommial[j] for j=1,...,n. The monomial coefficients of q_{x_i} are then accumuluated in + by numerator_polynomial[j] for j=1,...,n. The monomial coefficients of q_{x_i} are then accumuluated in dest[j] for j=1,..., n-1. Whereas the coefficients of q_{0} = N(X)/X * f(0) * (d_{i_0})^{-1} are added to dest[j] for j=0,..., n-1. Note that these coefficients do not require performing the division