Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
polynomial_arithmetic.test.cpp
Go to the documentation of this file.
6#include "polynomial.hpp"
7#include <algorithm>
8#include <cstddef>
9#include <gtest/gtest.h>
10#include <utility>
11
12using namespace bb;
13
17TEST(polynomials, evaluate)
18{
19 auto poly1 = Polynomial<fr>(15); // non power of 2
20 auto poly2 = Polynomial<fr>(64);
21 for (size_t i = 0; i < poly1.size(); ++i) {
22 poly1.at(i) = fr::random_element();
23 poly2.at(i) = poly1[i];
24 }
25
26 auto challenge = fr::random_element();
27 auto eval1 = poly1.evaluate(challenge);
28 auto eval2 = poly2.evaluate(challenge);
29
30 EXPECT_EQ(eval1, eval2);
31}
32
33TEST(polynomials, fft_with_small_degree)
34{
35 constexpr size_t n = 16;
36 fr fft_transform[n];
37 fr poly[n];
38
39 for (size_t i = 0; i < n; ++i) {
40 poly[i] = fr::random_element();
41 fr::__copy(poly[i], fft_transform[i]);
42 }
43
44 auto domain = evaluation_domain(n);
45 domain.compute_lookup_table();
46 polynomial_arithmetic::fft(fft_transform, domain);
47
48 fr work_root;
49 work_root = fr::one();
50 fr expected;
51 for (size_t i = 0; i < n; ++i) {
52 expected = polynomial_arithmetic::evaluate(poly, work_root, n);
53 EXPECT_EQ((fft_transform[i] == expected), true);
54 work_root *= domain.root;
55 }
56}
57
58TEST(polynomials, split_polynomial_fft)
59{
60 constexpr size_t n = 256;
61 fr fft_transform[n];
62 fr poly[n];
63
64 for (size_t i = 0; i < n; ++i) {
65 poly[i] = fr::random_element();
66 fr::__copy(poly[i], fft_transform[i]);
67 }
68
69 constexpr size_t num_poly = 4;
70 constexpr size_t n_poly = n / num_poly;
71 fr fft_transform_[num_poly][n_poly];
72 for (size_t i = 0; i < n; ++i) {
73 fft_transform_[i / n_poly][i % n_poly] = poly[i];
74 }
75
76 auto domain = evaluation_domain(n);
77 domain.compute_lookup_table();
78 polynomial_arithmetic::fft(fft_transform, domain);
79 polynomial_arithmetic::fft({ fft_transform_[0], fft_transform_[1], fft_transform_[2], fft_transform_[3] }, domain);
80
81 fr work_root;
82 work_root = fr::one();
83 fr expected;
84
85 for (size_t i = 0; i < n; ++i) {
86 expected = polynomial_arithmetic::evaluate(poly, work_root, n);
87 EXPECT_EQ((fft_transform[i] == expected), true);
88 EXPECT_EQ(fft_transform_[i / n_poly][i % n_poly], fft_transform[i]);
89 work_root *= domain.root;
90 }
91}
92
93TEST(polynomials, split_polynomial_evaluate)
94{
95 constexpr size_t n = 256;
96 fr fft_transform[n];
97 fr poly[n];
98
99 for (size_t i = 0; i < n; ++i) {
100 poly[i] = fr::random_element();
101 fr::__copy(poly[i], fft_transform[i]);
102 }
103
104 constexpr size_t num_poly = 4;
105 constexpr size_t n_poly = n / num_poly;
106 fr fft_transform_[num_poly][n_poly];
107 for (size_t i = 0; i < n; ++i) {
108 fft_transform_[i / n_poly][i % n_poly] = poly[i];
109 }
110
113 { fft_transform_[0], fft_transform_[1], fft_transform_[2], fft_transform_[3] }, z, n),
115}
116
117TEST(polynomials, basic_fft)
118{
119 constexpr size_t n = 1 << 14;
120 fr* data = (fr*)aligned_alloc(32, sizeof(fr) * n * 2);
121 fr* result = &data[0];
122 fr* expected = &data[n];
123 for (size_t i = 0; i < n; ++i) {
124 result[i] = fr::random_element();
125 fr::__copy(result[i], expected[i]);
126 }
127
128 auto domain = evaluation_domain(n);
129 domain.compute_lookup_table();
130 polynomial_arithmetic::fft(result, domain);
131 polynomial_arithmetic::ifft(result, domain);
132
133 for (size_t i = 0; i < n; ++i) {
134 EXPECT_EQ((result[i] == expected[i]), true);
135 }
136 aligned_free(data);
137}
138
139TEST(polynomials, fft_ifft_consistency)
140{
141 constexpr size_t n = 256;
142 fr result[n];
143 fr expected[n];
144 for (size_t i = 0; i < n; ++i) {
145 result[i] = fr::random_element();
146 fr::__copy(result[i], expected[i]);
147 }
148
149 auto domain = evaluation_domain(n);
150 domain.compute_lookup_table();
151 polynomial_arithmetic::fft(result, domain);
152 polynomial_arithmetic::ifft(result, domain);
153
154 for (size_t i = 0; i < n; ++i) {
155 EXPECT_EQ((result[i] == expected[i]), true);
156 }
157}
158
159TEST(polynomials, split_polynomial_fft_ifft_consistency)
160{
161 constexpr size_t n = 256;
162 constexpr size_t num_poly = 4;
163 fr result[num_poly][n];
164 fr expected[num_poly][n];
165 for (size_t j = 0; j < num_poly; j++) {
166 for (size_t i = 0; i < n; ++i) {
167 result[j][i] = fr::random_element();
168 fr::__copy(result[j][i], expected[j][i]);
169 }
170 }
171
172 auto domain = evaluation_domain(num_poly * n);
173 domain.compute_lookup_table();
174
175 std::vector<fr*> coeffs_vec;
176 for (size_t j = 0; j < num_poly; j++) {
177 coeffs_vec.push_back(result[j]);
178 }
179 polynomial_arithmetic::fft(coeffs_vec, domain);
180 polynomial_arithmetic::ifft(coeffs_vec, domain);
181
182 for (size_t j = 0; j < num_poly; j++) {
183 for (size_t i = 0; i < n; ++i) {
184 EXPECT_EQ((result[j][i] == expected[j][i]), true);
185 }
186 }
187}
188
189TEST(polynomials, fft_coset_ifft_consistency)
190{
191 constexpr size_t n = 256;
192 fr result[n];
193 fr expected[n];
194 for (size_t i = 0; i < n; ++i) {
195 result[i] = fr::random_element();
196 fr::__copy(result[i], expected[i]);
197 }
198
199 auto domain = evaluation_domain(n);
200 domain.compute_lookup_table();
201 fr T0;
202 T0 = domain.generator * domain.generator_inverse;
203 EXPECT_EQ((T0 == fr::one()), true);
204
205 polynomial_arithmetic::coset_fft(result, domain);
206 polynomial_arithmetic::coset_ifft(result, domain);
207
208 for (size_t i = 0; i < n; ++i) {
209 EXPECT_EQ((result[i] == expected[i]), true);
210 }
211}
212
213TEST(polynomials, split_polynomial_fft_coset_ifft_consistency)
214{
215 constexpr size_t n = 256;
216 constexpr size_t num_poly = 4;
217 fr result[num_poly][n];
218 fr expected[num_poly][n];
219 for (size_t j = 0; j < num_poly; j++) {
220 for (size_t i = 0; i < n; ++i) {
221 result[j][i] = fr::random_element();
222 fr::__copy(result[j][i], expected[j][i]);
223 }
224 }
225
226 auto domain = evaluation_domain(num_poly * n);
227 domain.compute_lookup_table();
228
229 std::vector<fr*> coeffs_vec;
230 for (size_t j = 0; j < num_poly; j++) {
231 coeffs_vec.push_back(result[j]);
232 }
233 polynomial_arithmetic::coset_fft(coeffs_vec, domain);
234 polynomial_arithmetic::coset_ifft(coeffs_vec, domain);
235
236 for (size_t j = 0; j < num_poly; j++) {
237 for (size_t i = 0; i < n; ++i) {
238 EXPECT_EQ((result[j][i] == expected[j][i]), true);
239 }
240 }
241}
242
243TEST(polynomials, fft_coset_ifft_cross_consistency)
244{
245 constexpr size_t n = 2;
246 fr expected[n];
247 fr poly_a[4 * n];
248 fr poly_b[4 * n];
249 fr poly_c[4 * n];
250
251 for (size_t i = 0; i < n; ++i) {
252 poly_a[i] = fr::random_element();
253 fr::__copy(poly_a[i], poly_b[i]);
254 fr::__copy(poly_a[i], poly_c[i]);
255 expected[i] = poly_a[i] + poly_c[i];
256 expected[i] += poly_b[i];
257 }
258
259 for (size_t i = n; i < 4 * n; ++i) {
260 poly_a[i] = fr::zero();
261 poly_b[i] = fr::zero();
262 poly_c[i] = fr::zero();
263 }
264 auto small_domain = evaluation_domain(n);
265 auto mid_domain = evaluation_domain(2 * n);
266 auto large_domain = evaluation_domain(4 * n);
267 small_domain.compute_lookup_table();
268 mid_domain.compute_lookup_table();
269 large_domain.compute_lookup_table();
270 polynomial_arithmetic::coset_fft(poly_a, small_domain);
271 polynomial_arithmetic::coset_fft(poly_b, mid_domain);
272 polynomial_arithmetic::coset_fft(poly_c, large_domain);
273
274 for (size_t i = 0; i < n; ++i) {
275 poly_a[i] = poly_a[i] + poly_c[4 * i];
276 poly_a[i] = poly_a[i] + poly_b[2 * i];
277 }
278
279 polynomial_arithmetic::coset_ifft(poly_a, small_domain);
280
281 for (size_t i = 0; i < n; ++i) {
282 EXPECT_EQ((poly_a[i] == expected[i]), true);
283 }
284}
285
286TEST(polynomials, compute_kate_opening_coefficients)
287{
288 // generate random polynomial F(X) = coeffs
289 constexpr size_t n = 256;
290 fr* coeffs = static_cast<fr*>(aligned_alloc(64, sizeof(fr) * 2 * n));
291 fr* W = static_cast<fr*>(aligned_alloc(64, sizeof(fr) * 2 * n));
292 for (size_t i = 0; i < n; ++i) {
293 coeffs[i] = fr::random_element();
294 coeffs[i + n] = fr::zero();
295 }
296 polynomial_arithmetic::copy_polynomial(coeffs, W, 2 * n, 2 * n);
297
298 // generate random evaluation point z
300
301 // compute opening polynomial W(X), and evaluation f = F(z)
303
304 // validate that W(X)(X - z) = F(X) - F(z)
305 // compute (X - z) in coefficient form
306 fr* multiplicand = static_cast<fr*>(aligned_alloc(64, sizeof(fr) * 2 * n));
307 multiplicand[0] = -z;
308 multiplicand[1] = fr::one();
309 for (size_t i = 2; i < 2 * n; ++i) {
310 multiplicand[i] = fr::zero();
311 }
312
313 // set F(X) = F(X) - F(z)
314 coeffs[0] -= f;
315
316 // compute fft of polynomials
317 auto domain = evaluation_domain(2 * n);
318 domain.compute_lookup_table();
319 polynomial_arithmetic::coset_fft(coeffs, domain);
321 polynomial_arithmetic::coset_fft(multiplicand, domain);
322
323 // validate that, at each evaluation, W(X)(X - z) = F(X) - F(z)
324 fr result;
325 for (size_t i = 0; i < domain.size; ++i) {
326 result = W[i] * multiplicand[i];
327 EXPECT_EQ((result == coeffs[i]), true);
328 }
329
330 aligned_free(coeffs);
331 aligned_free(W);
332 aligned_free(multiplicand);
333}
334
335TEST(polynomials, barycentric_weight_evaluations)
336{
337 constexpr size_t n = 16;
338
339 evaluation_domain domain(n);
340
341 std::vector<fr> poly(n);
342 std::vector<fr> barycentric_poly(n);
343
344 for (size_t i = 0; i < n / 2; ++i) {
345 poly[i] = fr::random_element();
346 barycentric_poly[i] = poly[i];
347 }
348 for (size_t i = n / 2; i < n; ++i) {
349 poly[i] = fr::zero();
350 barycentric_poly[i] = poly[i];
351 }
352 fr evaluation_point = fr{ 2, 0, 0, 0 }.to_montgomery_form();
353
354 fr result =
355 polynomial_arithmetic::compute_barycentric_evaluation(&barycentric_poly[0], n / 2, evaluation_point, domain);
356
357 domain.compute_lookup_table();
358
359 polynomial_arithmetic::ifft(&poly[0], domain);
360
361 fr expected = polynomial_arithmetic::evaluate(&poly[0], evaluation_point, n);
362
363 EXPECT_EQ((result == expected), true);
364}
365
366TEST(polynomials, linear_poly_product)
367{
368 constexpr size_t n = 64;
369 fr roots[n];
370
372 fr expected = 1;
373 for (size_t i = 0; i < n; ++i) {
374 roots[i] = fr::random_element();
375 expected *= (z - roots[i]);
376 }
377
378 fr dest[n + 1];
380 fr result = polynomial_arithmetic::evaluate(dest, z, n + 1);
381
382 EXPECT_EQ(result, expected);
383}
384
385template <typename FF> class PolynomialTests : public ::testing::Test {};
386
387using FieldTypes = ::testing::Types<bb::fr, grumpkin::fr>;
388
390
392{
393 using FF = TypeParam;
394 constexpr size_t n = 256;
395 auto domain = EvaluationDomain<FF>(n);
396
397 EXPECT_EQ(domain.size, 256UL);
398 EXPECT_EQ(domain.log2_size, 8UL);
399}
400
402{
403 using FF = TypeParam;
404 constexpr size_t n = 256;
405 auto domain = EvaluationDomain<FF>(n);
406
407 FF result;
408 FF expected;
409 expected = FF::one();
410 result = domain.root.pow(static_cast<uint64_t>(n));
411
412 EXPECT_EQ((result == expected), true);
413}
414
415TYPED_TEST(PolynomialTests, evaluation_domain_roots)
416{
417 using FF = TypeParam;
418 constexpr size_t n = 16;
419 EvaluationDomain<FF> domain(n);
420 domain.compute_lookup_table();
421 std::vector<FF*> root_table = domain.get_round_roots();
422 std::vector<FF*> inverse_root_table = domain.get_inverse_round_roots();
423 FF* roots = root_table[root_table.size() - 1];
424 FF* inverse_roots = inverse_root_table[inverse_root_table.size() - 1];
425 for (size_t i = 0; i < (n - 1) / 2; ++i) {
426 EXPECT_EQ(roots[i] * domain.root, roots[i + 1]);
427 EXPECT_EQ(inverse_roots[i] * domain.root_inverse, inverse_roots[i + 1]);
428 EXPECT_EQ(roots[i] * inverse_roots[i], FF::one());
429 }
430}
431
432TYPED_TEST(PolynomialTests, compute_interpolation)
433{
434 using FF = TypeParam;
435 constexpr size_t n = 100;
436 FF src[n], poly[n], x[n];
437
438 for (size_t i = 0; i < n; ++i) {
439 poly[i] = FF::random_element();
440 }
441
442 for (size_t i = 0; i < n; ++i) {
443 x[i] = FF::random_element();
444 src[i] = polynomial_arithmetic::evaluate(poly, x[i], n);
445 }
447
448 for (size_t i = 0; i < n; ++i) {
449 EXPECT_EQ(src[i], poly[i]);
450 }
451}
452
453TYPED_TEST(PolynomialTests, compute_efficient_interpolation)
454{
455 using FF = TypeParam;
456 constexpr size_t n = 250;
457 std::array<FF, n> src, poly, x;
458
459 for (size_t i = 0; i < n; ++i) {
460 poly[i] = FF::random_element();
461 }
462
463 for (size_t i = 0; i < n; ++i) {
464 x[i] = FF::random_element();
465 src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n);
466 }
467 polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n);
468
469 for (size_t i = 0; i < n; ++i) {
470 EXPECT_EQ(src[i], poly[i]);
471 }
472}
473// Test efficient Lagrange interpolation when interpolation points contain 0
474TYPED_TEST(PolynomialTests, compute_efficient_interpolation_domain_with_zero)
475{
476 using FF = TypeParam;
477 constexpr size_t n = 15;
478 std::array<FF, n> src, poly, x;
479
480 for (size_t i = 0; i < n; ++i) {
481 poly[i] = FF(i + 1);
482 }
483
484 for (size_t i = 0; i < n; ++i) {
485 x[i] = FF(i);
486 src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n);
487 }
488 polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n);
489
490 for (size_t i = 0; i < n; ++i) {
491 EXPECT_EQ(src[i], poly[i]);
492 }
493 // Test for the domain (-n/2, ..., 0, ... , n/2)
494
495 for (size_t i = 0; i < n; ++i) {
496 poly[i] = FF(i + 54);
497 }
498
499 for (size_t i = 0; i < n; ++i) {
500 x[i] = FF(i - n / 2);
501 src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n);
502 }
503 polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n);
504
505 for (size_t i = 0; i < n; ++i) {
506 EXPECT_EQ(src[i], poly[i]);
507 }
508
509 // Test for the domain (-n+1, ..., 0)
510
511 for (size_t i = 0; i < n; ++i) {
512 poly[i] = FF(i * i + 57);
513 }
514
515 for (size_t i = 0; i < n; ++i) {
516 x[i] = FF(i - (n - 1));
517 src[i] = polynomial_arithmetic::evaluate(poly.data(), x[i], n);
518 }
519 polynomial_arithmetic::compute_efficient_interpolation(src.data(), src.data(), x.data(), n);
520
521 for (size_t i = 0; i < n; ++i) {
522 EXPECT_EQ(src[i], poly[i]);
523 }
524}
525
526TYPED_TEST(PolynomialTests, interpolation_constructor_single)
527{
528 using FF = TypeParam;
529
530 auto root = std::array{ FF(3) };
531 auto eval = std::array{ FF(4) };
532 Polynomial<FF> t(root, eval, 1);
533 ASSERT_EQ(t.size(), 1);
534 ASSERT_EQ(t[0], eval[0]);
535}
536
537TYPED_TEST(PolynomialTests, interpolation_constructor)
538{
539 using FF = TypeParam;
540
541 constexpr size_t N = 32;
542 std::array<FF, N> roots;
543 std::array<FF, N> evaluations;
544 for (size_t i = 0; i < N; ++i) {
545 roots[i] = FF::random_element();
546 evaluations[i] = FF::random_element();
547 }
548
549 auto roots_copy(roots);
550 auto evaluations_copy(evaluations);
551
552 Polynomial<FF> interpolated(roots, evaluations, N);
553
554 ASSERT_EQ(interpolated.size(), N);
555 ASSERT_EQ(roots, roots_copy);
556 ASSERT_EQ(evaluations, evaluations_copy);
557
558 for (size_t i = 0; i < N; ++i) {
559 FF eval = interpolated.evaluate(roots[i]);
560 ASSERT_EQ(eval, evaluations[i]);
561 }
562}
563
564// LegacyPolynomials MLE
565TYPED_TEST(PolynomialTests, evaluate_mle_legacy)
566{
567 using FF = TypeParam;
568
569 auto test_case = [](size_t N) {
571 const size_t m = numeric::get_msb(N);
572 EXPECT_EQ(N, 1 << m);
573 Polynomial<FF> poly(N);
574 for (size_t i = 1; i < N - 1; ++i) {
575 poly.at(i) = FF::random_element(&engine);
576 }
577 poly.at(N - 1) = FF::zero();
578
579 EXPECT_TRUE(poly[0].is_zero());
580
581 // sample u = (u₀,…,uₘ₋₁)
582 std::vector<FF> u(m);
583 for (size_t l = 0; l < m; ++l) {
584 u[l] = FF::random_element(&engine);
585 }
586
587 std::vector<FF> lagrange_evals(N, FF(1));
588 for (size_t i = 0; i < N; ++i) {
589 auto& coef = lagrange_evals[i];
590 for (size_t l = 0; l < m; ++l) {
591 size_t mask = (1 << l);
592 if ((i & mask) == 0) {
593 coef *= (FF(1) - u[l]);
594 } else {
595 coef *= u[l];
596 }
597 }
598 }
599
600 // check eval by computing scalar product between
601 // lagrange evaluations and coefficients
602 FF real_eval(0);
603 for (size_t i = 0; i < N; ++i) {
604 real_eval += poly[i] * lagrange_evals[i];
605 }
606 FF computed_eval = poly.evaluate_mle(u);
607 EXPECT_EQ(real_eval, computed_eval);
608
609 // also check shifted eval
610 FF real_eval_shift(0);
611 for (size_t i = 1; i < N; ++i) {
612 real_eval_shift += poly[i] * lagrange_evals[i - 1];
613 }
614 FF computed_eval_shift = poly.evaluate_mle(u, true);
615 EXPECT_EQ(real_eval_shift, computed_eval_shift);
616 };
617 test_case(32);
618 test_case(4);
619 test_case(2);
620}
621
626TYPED_TEST(PolynomialTests, partial_evaluate_mle)
627{
628 // Initialize a random polynomial
629 using FF = TypeParam;
630 size_t N = 32;
631 Polynomial<FF> poly(N);
632 for (size_t i = 0; i < N; i++) {
633 poly.at(i) = FF::random_element();
634 }
635
636 // Define a random multivariate evaluation point u = (u_0, u_1, u_2, u_3, u_4)
637 auto u_0 = FF::random_element();
638 auto u_1 = FF::random_element();
639 auto u_2 = FF::random_element();
640 auto u_3 = FF::random_element();
641 auto u_4 = FF::random_element();
642 std::vector<FF> u_challenge = { u_0, u_1, u_2, u_3, u_4 };
643
644 // Show that directly computing v = p(u_0,...,u_4) yields the same result as first computing the partial evaluation
645 // in the last 3 variables g(X_0,X_1) = p(X_0,X_1,u_2,u_3,u_4), then v = g(u_0,u_1)
646
647 // Compute v = p(u_0,...,u_4)
648 auto v_expected = poly.evaluate_mle(u_challenge);
649
650 // Compute g(X_0,X_1) = p(X_0,X_1,u_2,u_3,u_4), then v = g(u_0,u_1)
651 std::vector<FF> u_part_1 = { u_0, u_1 };
652 std::vector<FF> u_part_2 = { u_2, u_3, u_4 };
653 auto partial_evaluated_poly = poly.partial_evaluate_mle(u_part_2);
654 auto v_result = partial_evaluated_poly.evaluate_mle(u_part_1);
655
656 EXPECT_EQ(v_result, v_expected);
657}
658
659TYPED_TEST(PolynomialTests, move_construct_and_assign)
660{
661 using FF = TypeParam;
662
663 // construct a poly with some arbitrary data
664 size_t num_coeffs = 64;
665 Polynomial<FF> polynomial_a(num_coeffs);
666 for (size_t i = 0; i < num_coeffs; i++) {
667 polynomial_a.at(i) = FF::random_element();
668 }
669
670 // construct a new poly from the original via the move constructor
671 Polynomial<FF> polynomial_b(std::move(polynomial_a));
672
673 // verifiy that source poly is appropriately destroyed
674 EXPECT_EQ(polynomial_a.data(), nullptr);
675
676 // construct another poly; this will also use the move constructor!
677 auto polynomial_c = std::move(polynomial_b);
678
679 // verifiy that source poly is appropriately destroyed
680 EXPECT_EQ(polynomial_b.data(), nullptr);
681
682 // define a poly with some arbitrary coefficients
683 Polynomial<FF> polynomial_d(num_coeffs);
684 for (size_t i = 0; i < num_coeffs; i++) {
685 polynomial_d.at(i) = FF::random_element();
686 }
687
688 // reset its data using move assignment
689 polynomial_d = std::move(polynomial_c);
690
691 // verifiy that source poly is appropriately destroyed
692 EXPECT_EQ(polynomial_c.data(), nullptr);
693}
694
695TYPED_TEST(PolynomialTests, default_construct_then_assign)
696{
697 using FF = TypeParam;
698
699 // construct an arbitrary but non-empty polynomial
700 size_t num_coeffs = 64;
701 Polynomial<FF> interesting_poly(num_coeffs);
702 for (size_t i = 0; i < num_coeffs; i++) {
703 interesting_poly.at(i) = FF::random_element();
704 }
705
706 // construct an empty poly via the default constructor
707 Polynomial<FF> poly;
708
709 EXPECT_EQ(poly.is_empty(), true);
710
711 // fill the empty poly using the assignment operator
712 poly = interesting_poly;
713
714 // coefficients and size should be equal in value
715 for (size_t i = 0; i < num_coeffs; ++i) {
716 EXPECT_EQ(poly[i], interesting_poly[i]);
717 }
718 EXPECT_EQ(poly.size(), interesting_poly.size());
719}
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 .....
bool is_empty() const
Polynomial partial_evaluate_mle(std::span< const Fr > evaluation_points) const
Partially evaluates in the last k variables a polynomial interpreted as a multilinear extension.
Fr evaluate(const Fr &z, size_t target_size) 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[...
std::size_t size() const
const std::vector< FF > data
numeric::RNG & engine
testing::Types< bb::fr > FieldTypes
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:190
void ifft(Fr *coeffs, const EvaluationDomain< Fr > &domain)
void coset_fft(Fr *coeffs, 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 fft(Fr *coeffs, const EvaluationDomain< Fr > &domain)
fr compute_barycentric_evaluation(const fr *coeffs, const size_t num_coeffs, const fr &z, const EvaluationDomain< fr > &domain)
void compute_interpolation(const Fr *src, Fr *dest, const Fr *evaluation_points, const size_t n)
Fr compute_kate_opening_coefficients(const Fr *src, Fr *dest, const Fr &z, const size_t n)
void coset_ifft(Fr *coeffs, const EvaluationDomain< Fr > &domain)
void copy_polynomial(const Fr *src, Fr *dest, size_t num_src_coefficients, size_t num_target_coefficients)
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(ShpleminiTest, TestSettings)
TEST(MegaCircuitBuilder, CopyConstructor)
typename Flavor::FF FF
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static constexpr field one()
BB_INLINE constexpr field to_montgomery_form() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
static BB_INLINE void __copy(const field &a, field &r) noexcept
static constexpr field zero()