12#include <gtest/gtest.h>
27 for (
size_t i = 0; i < poly1.size(); ++i) {
29 poly2.at(i) = poly1[i];
33 auto eval1 = poly1.evaluate(challenge);
34 auto eval2 = poly2.evaluate(challenge);
36 EXPECT_EQ(eval1, eval2);
39TEST(polynomials, ifft_consistency)
41 constexpr size_t n = 16;
43 domain.compute_lookup_table();
50 for (
size_t k = 0; k < n; ++k) {
57 for (
size_t j = 0; j < n; ++j) {
59 for (
size_t k = 0; k < n; ++k) {
60 fr w = domain.root.
pow(
static_cast<uint64_t
>(j * k));
64 values_copy[j] = values[j];
70 for (
size_t k = 0; k < n; ++k) {
71 EXPECT_EQ(recovered[k], coeffs[k]);
72 EXPECT_EQ(values[k], values_copy[k]);
78using FieldTypes = ::testing::Types<bb::fr, grumpkin::fr>;
86 constexpr size_t n = 256;
91 for (
size_t i = 0; i < n; ++i) {
93 expected *= (z - roots[i]);
100 EXPECT_EQ(result, expected);
106 using FF = TypeParam;
112 EXPECT_EQ(dest[0], -
FF(7));
113 EXPECT_EQ(dest[1],
FF(1));
118 std::array<FF, 3> dest{};
120 EXPECT_EQ(dest[0],
FF(2));
121 EXPECT_EQ(dest[1], -
FF(3));
122 EXPECT_EQ(dest[2],
FF(1));
128 using FF = TypeParam;
129 constexpr size_t n = 256;
132 EXPECT_EQ(domain.size, 256UL);
133 EXPECT_EQ(domain.log2_size, 8UL);
140 using FF = TypeParam;
142 domain.compute_lookup_table();
143 const size_t round_roots_before = domain.get_round_roots().size();
144 EXPECT_GT(round_roots_before, 0UL);
148 EXPECT_EQ(domain.size, 256UL);
149 EXPECT_EQ(domain.get_round_roots().size(), round_roots_before);
158 using FF = TypeParam;
159 constexpr size_t n = 256;
161 src.compute_lookup_table();
162 EXPECT_GT(src.get_round_roots().size(), 0UL);
167 EXPECT_EQ(dst.
size, n);
170 EXPECT_EQ(src.size, 0UL);
171 EXPECT_EQ(src.num_threads, 0UL);
172 EXPECT_EQ(src.thread_size, 0UL);
173 EXPECT_EQ(src.log2_size, 0UL);
174 EXPECT_EQ(src.log2_thread_size, 0UL);
175 EXPECT_EQ(src.log2_num_threads, 0UL);
176 EXPECT_EQ(src.generator_size, 0UL);
177 EXPECT_EQ(src.get_round_roots().size(), 0UL);
178 EXPECT_EQ(src.get_inverse_round_roots().size(), 0UL);
183 using FF = TypeParam;
184 constexpr size_t n = 256;
190 result = domain.root.
pow(
static_cast<uint64_t
>(n));
192 EXPECT_EQ((result == expected),
true);
197 using FF = TypeParam;
198 constexpr size_t n = 16;
203 FF* roots = root_table[root_table.size() - 1];
204 FF* inverse_roots = inverse_root_table[inverse_root_table.size() - 1];
205 for (
size_t i = 0; i < (n - 1) / 2; ++i) {
206 EXPECT_EQ(roots[i] * domain.
root, roots[i + 1]);
207 EXPECT_EQ(inverse_roots[i] * domain.
root_inverse, inverse_roots[i + 1]);
208 EXPECT_EQ(roots[i] * inverse_roots[i],
FF::one());
214 using FF = TypeParam;
215 constexpr size_t n = 250;
218 for (
size_t i = 0; i < n; ++i) {
222 for (
size_t i = 0; i < n; ++i) {
228 for (
size_t i = 0; i < n; ++i) {
229 EXPECT_EQ(src[i], poly[i]);
235 using FF = TypeParam;
236 constexpr size_t n = 15;
239 for (
size_t i = 0; i < n; ++i) {
243 for (
size_t i = 0; i < n; ++i) {
249 for (
size_t i = 0; i < n; ++i) {
250 EXPECT_EQ(src[i], poly[i]);
254 for (
size_t i = 0; i < n; ++i) {
255 poly[i] =
FF(i + 54);
258 for (
size_t i = 0; i < n; ++i) {
259 x[i] =
FF(i - n / 2);
264 for (
size_t i = 0; i < n; ++i) {
265 EXPECT_EQ(src[i], poly[i]);
270 for (
size_t i = 0; i < n; ++i) {
271 poly[i] =
FF(i * i + 57);
274 for (
size_t i = 0; i < n; ++i) {
275 x[i] =
FF(i - (n - 1));
280 for (
size_t i = 0; i < n; ++i) {
281 EXPECT_EQ(src[i], poly[i]);
287 using FF = TypeParam;
289 auto root = std::array{
FF(3) };
290 auto eval = std::array{
FF(4) };
292 ASSERT_EQ(t.
size(), 1);
293 ASSERT_EQ(t[0], eval[0]);
298 using FF = TypeParam;
300 constexpr size_t N = 32;
303 for (
size_t i = 0; i < N; ++i) {
308 auto roots_copy(roots);
309 auto evaluations_copy(evaluations);
313 ASSERT_EQ(interpolated.
size(), N);
314 ASSERT_EQ(roots, roots_copy);
315 ASSERT_EQ(evaluations, evaluations_copy);
317 for (
size_t i = 0; i < N; ++i) {
319 ASSERT_EQ(eval, evaluations[i]);
325 using FF = TypeParam;
327 auto test_case = [](
size_t N) {
330 EXPECT_EQ(N, 1 << m);
332 for (
size_t i = 1; i < N - 1; ++i) {
337 EXPECT_TRUE(poly[0].is_zero());
340 std::vector<FF> u(m);
341 for (
size_t l = 0; l < m; ++l) {
345 std::vector<FF> lagrange_evals(N,
FF(1));
346 for (
size_t i = 0; i < N; ++i) {
347 auto& coef = lagrange_evals[i];
348 for (
size_t l = 0; l < m; ++l) {
349 size_t mask = (1 << l);
350 if ((i & mask) == 0) {
351 coef *= (
FF(1) - u[l]);
361 for (
size_t i = 0; i < N; ++i) {
362 real_eval += poly[i] * lagrange_evals[i];
365 EXPECT_EQ(real_eval, computed_eval);
368 FF real_eval_shift(0);
369 for (
size_t i = 1; i < N; ++i) {
370 real_eval_shift += poly[i] * lagrange_evals[i - 1];
373 EXPECT_EQ(real_eval_shift, computed_eval_shift);
386 using FF = TypeParam;
389 size_t num_coeffs = 64;
391 for (
size_t i = 0; i < num_coeffs; i++) {
401 EXPECT_EQ(polynomial_a.
data(),
nullptr);
402 EXPECT_EQ(polynomial_a.
size(), 0UL);
404 EXPECT_TRUE(polynomial_a.
is_empty());
407 auto polynomial_c =
std::move(polynomial_b);
409 EXPECT_EQ(polynomial_b.
data(),
nullptr);
410 EXPECT_EQ(polynomial_b.
size(), 0UL);
412 EXPECT_TRUE(polynomial_b.
is_empty());
416 for (
size_t i = 0; i < num_coeffs; i++) {
423 EXPECT_EQ(polynomial_c.data(),
nullptr);
424 EXPECT_EQ(polynomial_c.size(), 0UL);
425 EXPECT_EQ(polynomial_c.virtual_size(), 0UL);
426 EXPECT_TRUE(polynomial_c.is_empty());
431 using FF = TypeParam;
434 size_t num_coeffs = 64;
436 for (
size_t i = 0; i < num_coeffs; i++) {
446 poly = interesting_poly;
449 for (
size_t i = 0; i < num_coeffs; ++i) {
450 EXPECT_EQ(poly[i], interesting_poly[i]);
452 EXPECT_EQ(poly.
size(), interesting_poly.
size());
456TEST(polynomials, FactorRootsExactDivisionRegression)
460 std::array<FF, 3> exact_poly = { -
FF(1),
FF(0),
FF(1) };
462 EXPECT_EQ(exact_poly[0],
FF(1));
463 EXPECT_EQ(exact_poly[1],
FF(1));
464 EXPECT_EQ(exact_poly[2],
FF(0));
468TEST(polynomials, FactorRootsNonExactDivisionAsserts)
470 GTEST_FLAG_SET(death_test_style,
"threadsafe");
472 std::array<FF, 3> bad_poly = {
FF(1),
FF(0),
FF(1) };
477TEST(polynomials, InterpolationCtorMismatchedSpansAsserts)
479 GTEST_FLAG_SET(death_test_style,
"threadsafe");
481 std::vector<FF> points = {
FF(1),
FF(2),
FF(3),
FF(4) };
482 std::vector<FF> evals = {
FF(10),
FF(20) };
488TEST(polynomials, ParseSizeStringOverflowAsserts)
500TEST(polynomials, ComputeEfficientInterpolationDuplicatePointsAsserts)
502 GTEST_FLAG_SET(death_test_style,
"threadsafe");
504 constexpr size_t n = 3;
509 polynomial_arithmetic::compute_efficient_interpolation<FF>(src.data(), dest.data(), points.data(), n),
".*");
513TEST(polynomials, FftInnerParallelInPlaceAsserts)
515 GTEST_FLAG_SET(death_test_style,
"threadsafe");
517 constexpr size_t n = 16;
519 domain.compute_lookup_table();
522 for (
size_t i = 0; i < n; ++i) {
523 coeffs[i] =
FF(i + 1);
#define ASSERT_THROW_OR_ABORT(statement, matcher)
size_t parse_size_string(const std::string &size_str)
void compute_lookup_table()
const std::vector< FF * > & get_round_roots() const
const std::vector< FF * > & get_inverse_round_roots() const
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
std::size_t virtual_size() const
Fr evaluate(const Fr &z) const
Fr evaluate_mle(std::span< const Fr > evaluation_points, bool shift=false) const
evaluate multi-linear extension p(X_0,…,X_{n-1}) = \sum_i a_i*L_i(X_0,…,X_{n-1}) at u = (u_0,...
Fr & at(size_t index)
Our mutable accessor, unlike operator[]. We abuse precedent a bit to differentiate at() and operator[...
testing::Types< bb::fr > FieldTypes
constexpr T get_msb(const T in)
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
void ifft(Fr *coeffs, Fr *target, const EvaluationDomain< Fr > &domain)
void compute_linear_polynomial_product(const Fr *roots, Fr *dest, const size_t n)
Fr evaluate(const Fr *coeffs, const Fr &z, const size_t n)
void factor_roots(std::span< Fr > polynomial, const Fr &root)
Divides p(X) by (X-r) in-place.
void fft_inner_parallel(Fr *coeffs, Fr *target, const EvaluationDomain< Fr > &domain, const Fr &, const std::vector< Fr * > &root_table)
void compute_efficient_interpolation(const Fr *src, Fr *dest, const Fr *evaluation_points, const size_t n)
Entry point for Barretenberg command-line interface.
EvaluationDomain< bb::fr > evaluation_domain
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
field< Bn254FrParams > fr
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static constexpr field one()
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()