Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
univariate.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Khashayar], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
9#include <array>
10#include <span>
11#include <vector>
12
17
18namespace bb {
19
27template <class Fr, size_t view_domain_end> class UnivariateView;
28
32template <class Fr, size_t domain_end> class Univariate {
33 public:
34 static constexpr size_t LENGTH = domain_end;
36 static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1;
38
39 using value_type = Fr; // used to get the type of the elements consistently with std::array
40
42
43 Univariate() = default;
44
48 ~Univariate() = default;
49 Univariate(const Univariate& other) = default;
50 Univariate(Univariate&& other) noexcept = default;
51 Univariate& operator=(const Univariate& other) = default;
52 Univariate& operator=(Univariate&& other) noexcept = default;
53
55 requires(LENGTH > 1)
56 {
57 static_assert(domain_end >= 2);
58
61 result.coefficients[1] = evaluations[1] - evaluations[0];
62 result.coefficients[2] = evaluations[1];
63 return result;
64 }
65
66 // Compute Lagrange coefficients of a given linear polynomial represented in monomial basis.
67 template <bool has_a0_plus_a1> Univariate(const UnivariateCoefficientBasis<Fr, 2, has_a0_plus_a1>& monomial)
68 {
69 // For domain_end == 1 the loop below never runs and the linear coefficient a1 would be silently
70 // discarded, so this constructor cannot represent a linear polynomial on a single point.
71 static_assert(domain_end >= 2);
72
73 Fr to_add = monomial.coefficients[1];
74 evaluations[0] = monomial.coefficients[0];
75 auto prev = evaluations[0];
76
77 for (size_t i = 1; i < domain_end; ++i) {
78 prev = prev + to_add;
79 evaluations[i] = prev;
80 }
81 }
82
83 // Compute Lagrange coefficients of a given quadratic polynomial represented in monomial basis.
84 template <bool has_a0_plus_a1> Univariate(const UnivariateCoefficientBasis<Fr, 3, has_a0_plus_a1>& monomial)
85 {
86 Fr to_add = monomial.coefficients[1]; // a1 + a2
87 Fr derivative = monomial.coefficients[2] + monomial.coefficients[2]; // 2a2
88 evaluations[0] = monomial.coefficients[0];
89 auto prev = evaluations[0];
90
91 for (size_t i = 1; i < domain_end - 1; ++i) {
92 prev += to_add;
93 evaluations[i] = prev;
94 to_add += derivative;
95 }
96 prev += to_add;
97 evaluations[domain_end - 1] = prev;
98 }
99
100 // Construct constant Univariate from scalar which represents the value that all the points in the domain
101 // evaluate to
102 explicit Univariate(const Fr& value)
103 {
104 for (size_t i = 0; i < LENGTH; ++i) {
105 evaluations[i] = value;
106 }
107 }
108 // Construct Univariate from UnivariateView.
109 // Lengths will match since we use `domain_end` both in the Univariate and the UnivariateView.
111 {
113 for (size_t i = 0; i < LENGTH; ++i) {
114 evaluations[i] = in.evaluations[i];
115 }
116 }
117
118 Fr& value_at(size_t i) { return evaluations[i]; }
119 const Fr& value_at(size_t i) const { return evaluations[i]; }
120 size_t size() { return evaluations.size(); };
121
122 // Check if the univariate is identically zero
123 bool is_zero() const
124 {
125 for (size_t i = 0; i < LENGTH; ++i) {
126 // Fr::is_zero() returns bool for both scalar Fr and VectorField (the new VectorField::is_zero
127 // returns true only when ALL lanes are zero — see VectorField for rationale and is_zero_mask).
128 if (!evaluations[i].is_zero()) {
129 return false;
130 }
131 }
132 return true;
133 }
134
135 // Write the Univariate evaluations to a buffer
136 [[nodiscard]] std::vector<uint8_t> to_buffer() const { return ::to_buffer(evaluations); }
137
138 // Static method for creating a Univariate from a buffer
139 // IMPROVEMENT: Could be made to identically match equivalent methods in e.g. field.hpp. Currently bypasses
140 // unnecessary ::from_buffer call
142 {
144 std::read(buffer, result.evaluations);
145 return result;
146 }
147
149 {
150 auto output = Univariate<Fr, domain_end>();
151 for (size_t i = 0; i != LENGTH; ++i) {
152 output.value_at(i) = Fr::random_element();
153 }
154 return output;
155 };
156
158
159 // Operations between Univariate and other Univariate
160 bool operator==(const Univariate& other) const = default;
161
163 {
164 for (size_t i = 0; i < LENGTH; ++i) {
165 evaluations[i] += other.evaluations[i];
166 }
167 return *this;
168 }
170 {
171 for (size_t i = 0; i < LENGTH; ++i) {
172 evaluations[i] -= other.evaluations[i];
173 }
174 return *this;
175 }
177 {
178 for (size_t i = 0; i < LENGTH; ++i) {
179 evaluations[i] *= other.evaluations[i];
180 }
181 return *this;
182 }
184 {
185 for (size_t i = 0; i < LENGTH; ++i) {
187 }
188 return *this;
189 }
190 Univariate operator+(const Univariate& other) const
191 {
192 Univariate res(*this);
193 res += other;
194 return res;
195 }
196
197 Univariate operator-(const Univariate& other) const
198 {
199 Univariate res(*this);
200 res -= other;
201 return res;
202 }
204 {
205 Univariate res(*this);
206 for (auto& eval : res.evaluations) {
207 eval = -eval;
208 }
209 return res;
210 }
211
212 Univariate operator*(const Univariate& other) const
213 {
214 Univariate res(*this);
215 res *= other;
216 return res;
217 }
218
220 {
221 Univariate res(*this);
222 res.self_sqr();
223 return res;
224 }
225
226 // Operations between Univariate and scalar
227 Univariate& operator+=(const Fr& scalar)
228 {
229 for (auto& eval : evaluations) {
230 eval += scalar;
231 }
232 return *this;
233 }
234
235 Univariate& operator-=(const Fr& scalar)
236 {
237 for (auto& eval : evaluations) {
238 eval -= scalar;
239 }
240 return *this;
241 }
242 Univariate& operator*=(const Fr& scalar)
243 {
244 for (auto& eval : evaluations) {
245 eval *= scalar;
246 }
247 return *this;
248 }
249
250 Univariate operator+(const Fr& scalar) const
251 {
252 Univariate res(*this);
253 res += scalar;
254 return res;
255 }
256
257 Univariate operator-(const Fr& scalar) const
258 {
259 Univariate res(*this);
260 res -= scalar;
261 return res;
262 }
263
264 Univariate operator*(const Fr& scalar) const
265 {
266 Univariate res(*this);
267 res *= scalar;
268 return res;
269 }
270
271 // Operations between Univariate and UnivariateView
273 {
274 for (size_t i = 0; i < LENGTH; ++i) {
275 evaluations[i] += view.evaluations[i];
276 }
277 return *this;
278 }
279
281 {
282 for (size_t i = 0; i < LENGTH; ++i) {
283 evaluations[i] -= view.evaluations[i];
284 }
285 return *this;
286 }
287
289 {
290 for (size_t i = 0; i < LENGTH; ++i) {
291 evaluations[i] *= view.evaluations[i];
292 }
293 return *this;
294 }
295
297 {
298 Univariate res(*this);
299 res += view;
300 return res;
301 }
302
304 {
305 Univariate res(*this);
306 res -= view;
307 return res;
308 }
309
311 {
312 Univariate res(*this);
313 res *= view;
314 return res;
315 }
316
317 // Output is immediately parsable as a list of integers by Python.
318 friend std::ostream& operator<<(std::ostream& os, const Univariate& u)
319 {
320 os << "[";
321 os << u.evaluations[0] << "," << std::endl;
322 for (size_t i = 1; i < u.evaluations.size(); i++) {
323 os << " " << u.evaluations[i];
324 if (i + 1 < u.evaluations.size()) {
325 os << "," << std::endl;
326 } else {
327 os << "]";
328 };
329 }
330 return os;
331 }
332
333 template <size_t EXTENDED_DOMAIN_END>
335 requires(domain_end == 2)
336 {
337 return extend_to<EXTENDED_DOMAIN_END>();
338 }
339
357 template <size_t EXTENDED_DOMAIN_END> Univariate<Fr, EXTENDED_DOMAIN_END> extend_to() const
358 {
359 static constexpr size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END;
361 static_assert(EXTENDED_LENGTH >= LENGTH);
362
364
365 std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin());
366
367 if constexpr (LENGTH == 2) {
368 // f = b x + c
369 // f(0) = c
370 // f(1) = b + c
371 // Hence, b = f(1) - f(0)
372 // f(i + 1) = f(i) + b
373 Fr delta = value_at(1) - value_at(0);
374 static_assert(EXTENDED_LENGTH != 0);
375 for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
376 result.value_at(idx + 1) = result.value_at(idx) + delta;
377 }
378 } else if constexpr (LENGTH == 3) {
379 static constexpr Fr inverse_two = Fr(2).invert();
380 // f = a x^2 + b x + c
381 // f(0) = c
382 // f(1) = a + b + c
383 // f(2) = 4a + 2b + c
384 // f(2) + f(0) - 2f(1) = 2a
385 // Hence, a = (f(2) + f(0) - 2f(1)) / 2
386 // b = f(1) - a - f(0)
387 // f(i+1) = f(i) + 2a * i + b + a
388 // Cost note: after computing a,b, extending several points costs a few adds per point (no
389 // inversions), vs the generic barycentric path.
390 Fr a = (value_at(2) + value_at(0)) * inverse_two - value_at(1);
391 Fr b = value_at(1) - a - value_at(0);
392 Fr a2 = a + a;
393 Fr a_mul = a2;
394 // compute 2a * (domain_end - 1)
395 for (size_t i = 0; i < domain_end - 2; i++) {
396 a_mul += a2;
397 }
398 Fr extra = a_mul + a + b;
399 for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
400 result.value_at(idx + 1) = result.value_at(idx) + extra;
401 extra += a2;
402 }
403 } else if constexpr (LENGTH == 4) {
404 static constexpr Fr inverse_six = Fr(6).invert(); // computed at compile time for efficiency
405
406 // To compute a barycentric extension, we can compute the coefficients of the univariate.
407 // We have the evaluation of the polynomial at the domain (which is assumed to be 0, 1, 2, 3).
408 // Therefore, we have the 4 linear equations from plugging into f(x) = ax^3 + bx^2 + cx + d:
409 // a*0 + b*0 + c*0 + d = f(0)
410 // a*1 + b*1 + c*1 + d = f(1)
411 // a*2^3 + b*2^2 + c*2 + d = f(2)
412 // a*3^3 + b*3^2 + c*3 + d = f(3)
413 // These equations can be rewritten as a matrix equation M * [a, b, c, d] = [f(0), f(1), f(2),
414 // f(3)], where M is:
415 // 0, 0, 0, 1
416 // 1, 1, 1, 1
417 // 2^3, 2^2, 2, 1
418 // 3^3, 3^2, 3, 1
419 // We can invert this matrix in order to compute a, b, c, d:
420 // -1/6, 1/2, -1/2, 1/6
421 // 1, -5/2, 2, -1/2
422 // -11/6, 3, -3/2, 1/3
423 // 1, 0, 0, 0
424 // To compute these values, we can multiply everything by 6 and multiply by inverse_six at the
425 // end for each coefficient The resulting computation here does 18 field adds, 6 subtracts, 3
426 // muls to compute a, b, c, and d.
427 Fr zero_times_3 = value_at(0) + value_at(0) + value_at(0);
428 Fr zero_times_6 = zero_times_3 + zero_times_3;
429 Fr zero_times_12 = zero_times_6 + zero_times_6;
430 Fr one_times_3 = value_at(1) + value_at(1) + value_at(1);
431 Fr one_times_6 = one_times_3 + one_times_3;
432 Fr two_times_3 = value_at(2) + value_at(2) + value_at(2);
433 Fr three_times_2 = value_at(3) + value_at(3);
434 Fr three_times_3 = three_times_2 + value_at(3);
435
436 Fr one_minus_two_times_3 = one_times_3 - two_times_3;
437 Fr one_minus_two_times_6 = one_minus_two_times_3 + one_minus_two_times_3;
438 Fr one_minus_two_times_12 = one_minus_two_times_6 + one_minus_two_times_6;
439 Fr a = (one_minus_two_times_3 + value_at(3) - value_at(0)) * inverse_six; // compute a in 1 muls and 4 adds
440 Fr b = (zero_times_6 - one_minus_two_times_12 - one_times_3 - three_times_3) * inverse_six;
441 Fr c = (value_at(0) - zero_times_12 + one_minus_two_times_12 + one_times_6 + two_times_3 + three_times_2) *
442 inverse_six;
443
444 // Then, outside of the a, b, c, d computation, we need to do some extra precomputation
445 // This work is 3 field muls, 8 adds
446 Fr a_plus_b = a + b;
447 Fr a_plus_b_times_2 = a_plus_b + a_plus_b;
448 size_t start_idx_sqr = (domain_end - 1) * (domain_end - 1);
449 size_t idx_sqr_three = start_idx_sqr + start_idx_sqr + start_idx_sqr;
450 Fr idx_sqr_three_times_a = Fr(idx_sqr_three) * a;
451 Fr x_a_term = Fr(6 * (domain_end - 1)) * a;
452 Fr three_a = a + a + a;
453 Fr six_a = three_a + three_a;
454
455 Fr three_a_plus_two_b = a_plus_b_times_2 + a;
456 Fr linear_term = Fr(domain_end - 1) * three_a_plus_two_b + (a_plus_b + c);
457 // For each new evaluation, we do only 6 field additions and 0 muls.
458 for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
459 result.value_at(idx + 1) = result.value_at(idx) + idx_sqr_three_times_a + linear_term;
460
461 idx_sqr_three_times_a += x_a_term + three_a;
462 x_a_term += six_a;
463
464 linear_term += three_a_plus_two_b;
465 }
466 } else {
467 for (size_t k = domain_end; k != EXTENDED_DOMAIN_END; ++k) {
468 result.value_at(k) = 0;
469 // compute each term v_j / (d_j*(x-x_j)) of the sum
470 for (size_t j = 0; j != domain_end; ++j) {
471 Fr term = value_at(j);
472 term *= Data::precomputed_denominator_inverses[LENGTH * k + j];
473 result.value_at(k) += term;
474 }
475 // scale the sum by the value of of B(x)
476 result.value_at(k) *= Data::full_numerator_values[k];
477 }
478 }
479 return result;
480 }
481
488 template <size_t INITIAL_LENGTH> void self_extend_from()
489 {
490 if constexpr (INITIAL_LENGTH == 2) {
491 const Fr delta = value_at(1) - value_at(0);
492 Fr next = value_at(1);
493 for (size_t idx = 2; idx < LENGTH; idx++) {
494 next += delta;
495 value_at(idx) = next;
496 }
497 } else {
498 throw_or_abort("self_extend_from called with INITIAL_LENGTH different from 2.");
499 }
500 }
501
508 Fr evaluate(const Fr& u) const
509 {
511 Fr full_numerator_value = 1;
512 for (size_t i = 0; i != domain_end; ++i) {
513 full_numerator_value *= u - i;
514 }
515
516 // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against
517 // each of these (rather than to divide by something) for each barycentric evaluation
518 std::array<Fr, LENGTH> denominator_inverses;
519 for (size_t i = 0; i != LENGTH; ++i) {
520 Fr inv = Data::lagrange_denominators[i];
521 inv *= u - Data::big_domain[i]; // warning: need to avoid zero here
522 inv = Fr(1) / inv;
523 denominator_inverses[i] = inv;
524 }
525
526 Fr result = 0;
527 // compute each term v_j / (d_j*(x-x_j)) of the sum
528 for (size_t i = 0; i != domain_end; ++i) {
529 Fr term = value_at(i);
530 term *= denominator_inverses[i];
531 result += term;
532 }
533 // scale the sum by the value of of B(x)
534 result *= full_numerator_value;
535 return result;
536 };
537
538 // Begin iterators
539 auto begin() { return evaluations.begin(); }
540 auto begin() const { return evaluations.begin(); }
541 // End iterators
542 auto end() { return evaluations.end(); }
543 auto end() const { return evaluations.end(); }
544};
545
546template <typename B, class Fr, size_t domain_end> inline void read(B& it, Univariate<Fr, domain_end>& univariate)
547{
548 using serialize::read;
549 read(it, univariate.evaluations);
550}
551
552template <typename B, class Fr, size_t domain_end>
553inline void write(B& it, Univariate<Fr, domain_end> const& univariate)
554{
555 using serialize::write;
556 write(it, univariate.evaluations);
557}
558
559template <class Fr, size_t domain_end>
561{
562 return uv + ff;
563}
564
565template <class Fr, size_t domain_end>
567{
568 return -uv + ff;
569}
570
571template <class Fr, size_t domain_end>
573{
574 return uv * ff;
575}
576
577template <class Fr, size_t domain_end> class UnivariateView {
578 public:
579 static constexpr size_t LENGTH = domain_end;
581 static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1;
583
584 UnivariateView() = default;
585
586 bool operator==(const UnivariateView& other) const
587 {
588 for (size_t i = 0; i < LENGTH; ++i) {
589 if (evaluations[i] != other.evaluations[i]) {
590 return false;
591 }
592 }
593 return true;
594 };
595
596 const Fr& value_at(size_t i) const { return evaluations[i]; };
597
598 template <size_t full_domain_end>
599 explicit UnivariateView(const Univariate<Fr, full_domain_end>& univariate_in)
600 : evaluations(std::span<const Fr>(univariate_in.evaluations.data(), LENGTH))
601 {
602 // Viewing more evaluations than the source holds would span out-of-bounds memory.
603 static_assert(LENGTH <= full_domain_end);
604 };
605
607 requires(LENGTH > 1)
608 {
609 static_assert(domain_end >= 2);
610
612
614 result.coefficients[1] = evaluations[1] - evaluations[0];
615 result.coefficients[2] = evaluations[1];
616 return result;
617 }
618
620 {
622 res += other;
623 return res;
624 }
625
627 {
629 res -= other;
630 return res;
631 }
632
634 {
636 for (auto& eval : res.evaluations) {
637 eval = -eval;
638 }
639 return res;
640 }
641
643 {
645 res *= other;
646 return res;
647 }
649 {
651 res = res.sqr();
652 return res;
653 }
654
656 {
658 res *= other;
659 return res;
660 }
661
663 {
665 res += other;
666 return res;
667 }
668
670 {
672 res += other;
673 return res;
674 }
675
677 {
679 res -= other;
680 return res;
681 }
682
684 {
686 res *= other;
687 return res;
688 }
689
691 {
693 res -= other;
694 return res;
695 }
696
697 // Output is immediately parsable as a list of integers by Python.
698 friend std::ostream& operator<<(std::ostream& os, const UnivariateView& u)
699 {
700 os << "[";
701 os << u.evaluations[0] << "," << std::endl;
702 for (size_t i = 1; i < u.evaluations.size(); i++) {
703 os << " " << u.evaluations[i];
704 if (i + 1 < u.evaluations.size()) {
705 os << "," << std::endl;
706 } else {
707 os << "]";
708 };
709 }
710 return os;
711 }
712};
713
714template <class Fr, size_t domain_end>
716{
717 return uv + ff;
718}
719
720template <class Fr, size_t domain_end>
722{
723 return -uv + ff;
724}
725
726template <class Fr, size_t domain_end>
728{
729 return uv * ff;
730}
731
745template <typename T, typename U, std::size_t N, std::size_t... Is>
746std::array<T, sizeof...(Is)> array_to_array_aux(const std::array<U, N>& elements, std::index_sequence<Is...>)
747{
748 return { { T{ elements[Is] }... } };
749};
750
768template <typename T, typename U, std::size_t N> std::array<T, N> array_to_array(const std::array<U, N>& elements)
769{
770 // Calls the aux method that uses the index sequence to unpack all values in `elements`
771 return array_to_array_aux<T, U, N>(elements, std::make_index_sequence<N>());
772};
773
774} // namespace bb
775
776namespace std {
777
778template <typename T, size_t N> struct tuple_size<bb::Univariate<T, N>> : std::integral_constant<std::size_t, N> {};
779
780} // namespace std
constexpr size_t N
A view of a univariate, also used to truncate univariates.
std::array< Fr, 3 > coefficients
Storage for polynomial coefficients (always 3 elements for uniform layout).
A univariate polynomial represented by its values on {0, 1,..., domain_end - 1}.
const Fr & value_at(size_t i) const
Univariate()=default
static constexpr size_t LENGTH
Univariate & operator+=(const Univariate &other)
Univariate & operator-=(const Univariate &other)
bool is_zero() const
bool operator==(const Univariate &other) const =default
Univariate & operator+=(const Fr &scalar)
Univariate operator*(const UnivariateView< Fr, domain_end > &view) const
Univariate(const std::array< Fr, LENGTH > &evaluations)
Fr & value_at(size_t i)
Univariate(const UnivariateCoefficientBasis< Fr, 3, has_a0_plus_a1 > &monomial)
static Univariate zero()
Univariate & self_sqr()
friend std::ostream & operator<<(std::ostream &os, const Univariate &u)
auto end() const
void self_extend_from()
Compute the evaluations of the polynomial from the INITIAL_LENGTH up to the total LENGTH....
Univariate & operator=(Univariate &&other) noexcept=default
Univariate operator*(const Fr &scalar) const
~Univariate()=default
Univariate & operator*=(const Fr &scalar)
Univariate operator+(const UnivariateView< Fr, domain_end > &view) const
std::array< Fr, LENGTH > evaluations
Univariate operator-(const Fr &scalar) const
static Univariate serialize_from_buffer(uint8_t const *buffer)
Univariate operator-(const UnivariateView< Fr, domain_end > &view) const
Univariate & operator=(const Univariate &other)=default
static Univariate get_random()
Univariate(Univariate &&other) noexcept=default
Univariate & operator*=(const UnivariateView< Fr, domain_end > &view)
Univariate operator-(const Univariate &other) const
auto begin() const
std::vector< uint8_t > to_buffer() const
Univariate & operator*=(const Univariate &other)
Univariate operator+(const Fr &scalar) const
static constexpr size_t MONOMIAL_LENGTH
Univariate & operator-=(const UnivariateView< Fr, domain_end > &view)
Univariate sqr() const
Univariate & operator+=(const UnivariateView< Fr, domain_end > &view)
Univariate operator*(const Univariate &other) const
Fr evaluate(const Fr &u) const
Evaluate a univariate at a point u not known at compile time and assumed not to be in the domain (els...
Univariate(const Univariate &other)=default
Univariate operator-() const
Univariate(const UnivariateCoefficientBasis< Fr, 2, has_a0_plus_a1 > &monomial)
Univariate(const UnivariateView< Fr, domain_end > &in)
Univariate operator+(const Univariate &other) const
Univariate(const Fr &value)
Univariate< Fr, EXTENDED_DOMAIN_END > extend_to() const
Given a univariate f represented by {f(0), ..., f(domain_end - 1)}, compute the evaluations {f(domain...
Univariate & operator-=(const Fr &scalar)
A view of a univariate, also used to truncate univariates.
Univariate< Fr, domain_end > sqr() const
bool operator==(const UnivariateView &other) const
friend std::ostream & operator<<(std::ostream &os, const UnivariateView &u)
Univariate< Fr, domain_end > operator-() const
std::span< const Fr, LENGTH > evaluations
static constexpr size_t LENGTH
Univariate< Fr, domain_end > operator-(const Fr &other) const
Univariate< Fr, domain_end > operator*(const UnivariateView &other) const
Univariate< Fr, domain_end > operator-(const UnivariateView &other) const
Univariate< Fr, domain_end > operator*(const Univariate< Fr, domain_end > &other) const
Univariate< Fr, domain_end > operator+(const Univariate< Fr, domain_end > &other) const
const Fr & value_at(size_t i) const
UnivariateView(const Univariate< Fr, full_domain_end > &univariate_in)
Univariate< Fr, domain_end > operator+(const UnivariateView &other) const
UnivariateView()=default
Univariate< Fr, domain_end > operator*(const Fr &other) const
Univariate< Fr, domain_end > operator+(const Fr &other) const
static constexpr size_t MONOMIAL_LENGTH
Univariate< Fr, domain_end > operator-(const Univariate< Fr, domain_end > &other) const
FF a
FF b
std::unique_ptr< uint8_t[]> buffer
Definition engine.cpp:60
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
void read(B &it, field2< base_field, Params > &value)
Univariate< Fr, domain_end > operator+(const Fr &ff, const Univariate< Fr, domain_end > &uv)
void write(B &buf, field2< base_field, Params > const &value)
Univariate< Fr, domain_end > operator-(const Fr &ff, const Univariate< Fr, domain_end > &uv)
Univariate< Fr, domain_end > operator*(const Fr &ff, const Univariate< Fr, domain_end > &uv)
std::array< T, N > array_to_array(const std::array< U, N > &elements)
Given an std::array<U,N>, returns an std::array<T,N>, by calling the (explicit) constructor T(U).
std::array< T, sizeof...(Is)> array_to_array_aux(const std::array< U, N > &elements, std::index_sequence< Is... >)
Create a sub-array of elements at the indices given in the template pack Is, converting them to the n...
std::conditional_t< is_field_type_v< Fr >, BarycentricDataCompileTime< Fr, domain_end, num_evals >, BarycentricDataRunTime< Fr, domain_end, num_evals > > BarycentricData
Exposes BarycentricData with compile time arrays if the type is bberg::field and runtime arrays other...
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by SERIALIZATIO...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by SERIALIZATI...
STL namespace.
void read(auto &buf, std::integral auto &value)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::ScalarField Fr
std::byte * data
constexpr field invert() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()
void throw_or_abort(std::string const &err)
VectorField result