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: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
12#include <span>
13
14namespace bb {
15
23template <class Fr, size_t view_domain_end, size_t view_domain_start, size_t skip_count> class UnivariateView;
24
35template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0> class Univariate {
36 public:
37 static constexpr size_t LENGTH = domain_end - domain_start;
38 static constexpr size_t SKIP_COUNT = skip_count;
40 static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1;
42
43 using value_type = Fr; // used to get the type of the elements consistently with std::array
44
45 // TODO(https://github.com/AztecProtocol/barretenberg/issues/714) Try out std::valarray?
47
48 Univariate() = default;
49
53 ~Univariate() = default;
54 Univariate(const Univariate& other) = default;
55 Univariate(Univariate&& other) noexcept = default;
56 Univariate& operator=(const Univariate& other) = default;
57 Univariate& operator=(Univariate&& other) noexcept = default;
58
60 requires(LENGTH > 1)
61 {
62 static_assert(domain_end >= 2);
63 static_assert(domain_start == 0);
64
66 result.coefficients[0] = evaluations[0];
67 result.coefficients[1] = evaluations[1] - evaluations[0];
68 result.coefficients[2] = evaluations[1];
69 return result;
70 }
71
72 template <bool has_a0_plus_a1> Univariate(UnivariateCoefficientBasis<Fr, 2, has_a0_plus_a1> monomial)
73 {
74 static_assert(domain_start == 0);
75 Fr to_add = monomial.coefficients[1];
76 evaluations[0] = monomial.coefficients[0];
77 auto prev = evaluations[0];
78 for (size_t i = 1; i < skip_count + 1; ++i) {
79 evaluations[i] = 0;
80 prev = prev + to_add;
81 }
82
83 for (size_t i = skip_count + 1; i < domain_end; ++i) {
84 prev = prev + to_add;
85 evaluations[i] = prev;
86 }
87 }
88
89 template <bool has_a0_plus_a1> Univariate(UnivariateCoefficientBasis<Fr, 3, has_a0_plus_a1> monomial)
90 {
91 static_assert(domain_start == 0);
92 Fr to_add = monomial.coefficients[1]; // a1 + a2
93 Fr derivative = monomial.coefficients[2] + monomial.coefficients[2]; // 2a2
94 evaluations[0] = monomial.coefficients[0];
95 auto prev = evaluations[0];
96 for (size_t i = 1; i < skip_count + 1; ++i) {
97 evaluations[i] = 0;
98 prev += to_add;
99 to_add += derivative;
100 }
101
102 for (size_t i = skip_count + 1; i < domain_end - 1; ++i) {
103 prev += to_add;
104 evaluations[i] = prev;
105 to_add += derivative;
106 }
107 prev += to_add;
108 evaluations[domain_end - 1] = prev;
109 }
110
118 {
120 result.evaluations[0] = evaluations[0];
121 for (size_t i = 1; i < skip_count + 1; i++) {
122 result.evaluations[i] = Fr::zero();
123 }
124 for (size_t i = skip_count + 1; i < LENGTH; i++) {
125 result.evaluations[i] = evaluations[i];
126 }
127 return result;
128 }
129 // Construct constant Univariate from scalar which represents the value that all the points in the domain
130 // evaluate to
132 : evaluations{}
133 {
134 for (size_t i = 0; i < LENGTH; ++i) {
135 evaluations[i] = value;
136 }
137 }
138 // Construct Univariate from UnivariateView
140 : evaluations{}
141 {
142 for (size_t i = 0; i < in.evaluations.size(); ++i) {
143 evaluations[i] = in.evaluations[i];
144 }
145 }
146
147 Fr& value_at(size_t i)
148 {
149 if constexpr (domain_start == 0) {
150 return evaluations[i];
151 } else {
152 return evaluations[i - domain_start];
153 }
154 };
155 const Fr& value_at(size_t i) const
156 {
157 if constexpr (domain_start == 0) {
158 return evaluations[i];
159 } else {
160 return evaluations[i - domain_start];
161 }
162 };
163 size_t size() { return evaluations.size(); };
164
165 // Check if the univariate is identically zero
166 bool is_zero() const
167 {
168 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
169 if (!evaluations[i].is_zero()) {
170 return false;
171 }
172 }
173 return evaluations[0].is_zero();
174 }
175
176 // Write the Univariate evaluations to a buffer
177 [[nodiscard]] std::vector<uint8_t> to_buffer() const { return ::to_buffer(evaluations); }
178
179 // Static method for creating a Univariate from a buffer
180 // IMPROVEMENT: Could be made to identically match equivalent methods in e.g. field.hpp. Currently bypasses
181 // unnecessary ::from_buffer call
183 {
184 Univariate result;
186 return result;
187 }
188
190 {
192 for (size_t i = 0; i != LENGTH; ++i) {
193 output.value_at(i) = Fr::random_element();
194 }
195 return output;
196 };
197
199 {
201 for (size_t i = 0; i != LENGTH; ++i) {
202 output.value_at(i) = Fr::zero();
203 }
204 return output;
205 }
206
207 static Univariate random_element() { return get_random(); };
208
209 // Operations between Univariate and other Univariate
210 bool operator==(const Univariate& other) const = default;
211
213 {
214 evaluations[0] += other.evaluations[0];
215 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
216 evaluations[i] += other.evaluations[i];
217 }
218 return *this;
219 }
221 {
222 evaluations[0] -= other.evaluations[0];
223 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
224
225 evaluations[i] -= other.evaluations[i];
226 }
227 return *this;
228 }
230 {
231 evaluations[0] *= other.evaluations[0];
232 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
233 evaluations[i] *= other.evaluations[i];
234 }
235 return *this;
236 }
238 {
240 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
242 }
243 return *this;
244 }
245 Univariate operator+(const Univariate& other) const
246 {
247 Univariate res(*this);
248 res += other;
249 return res;
250 }
251
252 Univariate operator-(const Univariate& other) const
253 {
254 Univariate res(*this);
255 res -= other;
256 return res;
257 }
259 {
260 Univariate res(*this);
261 size_t i = 0;
262 for (auto& eval : res.evaluations) {
263 if (i == 0 || i >= (skip_count + 1)) {
264 eval = -eval;
265 }
266 i++;
267 }
268 return res;
269 }
270
271 Univariate operator*(const Univariate& other) const
272 {
273 Univariate res(*this);
274 res *= other;
275 return res;
276 }
277
279 {
280 Univariate res(*this);
281 res.self_sqr();
282 return res;
283 }
284
285 // Operations between Univariate and scalar
286 Univariate& operator+=(const Fr& scalar)
287 {
288 size_t i = 0;
289 for (auto& eval : evaluations) {
290 if (i == 0 || i >= (skip_count + 1)) {
291 eval += scalar;
292 }
293 i++;
294 }
295 return *this;
296 }
297
298 Univariate& operator-=(const Fr& scalar)
299 {
300 size_t i = 0;
301 for (auto& eval : evaluations) {
302 // If skip count is zero, will be enabled on every line, otherwise don't compute for [domain_start+1,..,
303 // domain_start + skip_count]
304 if (i == 0 || i >= (skip_count + 1)) {
305 eval -= scalar;
306 }
307 i++;
308 }
309 return *this;
310 }
311 Univariate& operator*=(const Fr& scalar)
312 {
313 size_t i = 0;
314 for (auto& eval : evaluations) {
315 // If skip count is zero, will be enabled on every line, otherwise don't compute for [domain_start+1,..,
316 // domain_start + skip_count]
317 if (i == 0 || i >= (skip_count + 1)) {
318 eval *= scalar;
319 }
320 i++;
321 }
322 return *this;
323 }
324
325 Univariate operator+(const Fr& scalar) const
326 {
327 Univariate res(*this);
328 res += scalar;
329 return res;
330 }
331
332 Univariate operator-(const Fr& scalar) const
333 {
334 Univariate res(*this);
335 res -= scalar;
336 return res;
337 }
338
339 Univariate operator*(const Fr& scalar) const
340 {
341 Univariate res(*this);
342 res *= scalar;
343 return res;
344 }
345
346 // Operations between Univariate and UnivariateView
348 {
349 evaluations[0] += view.evaluations[0];
350 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
351 evaluations[i] += view.evaluations[i];
352 }
353 return *this;
354 }
355
357 {
358 evaluations[0] -= view.evaluations[0];
359 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
360 evaluations[i] -= view.evaluations[i];
361 }
362 return *this;
363 }
364
366 {
367 evaluations[0] *= view.evaluations[0];
368 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
369 evaluations[i] *= view.evaluations[i];
370 }
371 return *this;
372 }
373
375 {
376 Univariate res(*this);
377 res += view;
378 return res;
379 }
380
382 {
383 Univariate res(*this);
384 res -= view;
385 return res;
386 }
387
389 {
390 Univariate res(*this);
391 res *= view;
392 return res;
393 }
394
395 // Output is immediately parsable as a list of integers by Python.
396 friend std::ostream& operator<<(std::ostream& os, const Univariate& u)
397 {
398 os << "[";
399 os << u.evaluations[0] << "," << std::endl;
400 for (size_t i = 1; i < u.evaluations.size(); i++) {
401 os << " " << u.evaluations[i];
402 if (i + 1 < u.evaluations.size()) {
403 os << "," << std::endl;
404 } else {
405 os << "]";
406 };
407 }
408 return os;
409 }
410
411 template <size_t EXTENDED_DOMAIN_END, size_t NUM_SKIPPED_INDICES = 0>
413 requires(domain_start == 0 && domain_end == 2)
414 {
415 return extend_to<EXTENDED_DOMAIN_END, NUM_SKIPPED_INDICES>();
416 }
417
436 template <size_t EXTENDED_DOMAIN_END, size_t NUM_SKIPPED_INDICES = 0>
438 {
439 static constexpr size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start;
441 static_assert(EXTENDED_LENGTH >= LENGTH);
442
444
445 std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin());
446
447 static constexpr Fr inverse_two = Fr(2).invert();
448 static_assert(NUM_SKIPPED_INDICES < LENGTH);
449 if constexpr (LENGTH == 2) {
450 Fr delta = value_at(1) - value_at(0);
451 static_assert(EXTENDED_LENGTH != 0);
452 for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
453 result.value_at(idx + 1) = result.value_at(idx) + delta;
454 }
455 } else if constexpr (LENGTH == 3) {
456 // Based off https://hackmd.io/@aztec-network/SyR45cmOq?type=view
457 // The technique used here is the same as the length == 3 case below.
458 Fr a = (value_at(2) + value_at(0)) * inverse_two - value_at(1);
459 Fr b = value_at(1) - a - value_at(0);
460 Fr a2 = a + a;
461 Fr a_mul = a2;
462 for (size_t i = 0; i < domain_end - 2; i++) {
463 a_mul += a2;
464 }
465 Fr extra = a_mul + a + b;
466 for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
467 result.value_at(idx + 1) = result.value_at(idx) + extra;
468 extra += a2;
469 }
470 } else if constexpr (LENGTH == 4) {
471 static constexpr Fr inverse_six = Fr(6).invert(); // computed at compile time for efficiency
472
473 // To compute a barycentric extension, we can compute the coefficients of the univariate.
474 // We have the evaluation of the polynomial at the domain (which is assumed to be 0, 1, 2, 3).
475 // Therefore, we have the 4 linear equations from plugging into f(x) = ax^3 + bx^2 + cx + d:
476 // a*0 + b*0 + c*0 + d = f(0)
477 // a*1 + b*1 + c*1 + d = f(1)
478 // a*2^3 + b*2^2 + c*2 + d = f(2)
479 // a*3^3 + b*3^2 + c*3 + d = f(3)
480 // These equations can be rewritten as a matrix equation M * [a, b, c, d] = [f(0), f(1), f(2),
481 // f(3)], where M is:
482 // 0, 0, 0, 1
483 // 1, 1, 1, 1
484 // 2^3, 2^2, 2, 1
485 // 3^3, 3^2, 3, 1
486 // We can invert this matrix in order to compute a, b, c, d:
487 // -1/6, 1/2, -1/2, 1/6
488 // 1, -5/2, 2, -1/2
489 // -11/6, 3, -3/2, 1/3
490 // 1, 0, 0, 0
491 // To compute these values, we can multiply everything by 6 and multiply by inverse_six at the
492 // end for each coefficient The resulting computation here does 18 field adds, 6 subtracts, 3
493 // muls to compute a, b, c, and d.
494 Fr zero_times_3 = value_at(0) + value_at(0) + value_at(0);
495 Fr zero_times_6 = zero_times_3 + zero_times_3;
496 Fr zero_times_12 = zero_times_6 + zero_times_6;
497 Fr one_times_3 = value_at(1) + value_at(1) + value_at(1);
498 Fr one_times_6 = one_times_3 + one_times_3;
499 Fr two_times_3 = value_at(2) + value_at(2) + value_at(2);
500 Fr three_times_2 = value_at(3) + value_at(3);
501 Fr three_times_3 = three_times_2 + value_at(3);
502
503 Fr one_minus_two_times_3 = one_times_3 - two_times_3;
504 Fr one_minus_two_times_6 = one_minus_two_times_3 + one_minus_two_times_3;
505 Fr one_minus_two_times_12 = one_minus_two_times_6 + one_minus_two_times_6;
506 Fr a = (one_minus_two_times_3 + value_at(3) - value_at(0)) * inverse_six; // compute a in 1 muls and 4 adds
507 Fr b = (zero_times_6 - one_minus_two_times_12 - one_times_3 - three_times_3) * inverse_six;
508 Fr c = (value_at(0) - zero_times_12 + one_minus_two_times_12 + one_times_6 + two_times_3 + three_times_2) *
509 inverse_six;
510
511 // Then, outside of the a, b, c, d computation, we need to do some extra precomputation
512 // This work is 3 field muls, 8 adds
513 Fr a_plus_b = a + b;
514 Fr a_plus_b_times_2 = a_plus_b + a_plus_b;
515 size_t start_idx_sqr = (domain_end - 1) * (domain_end - 1);
516 size_t idx_sqr_three = start_idx_sqr + start_idx_sqr + start_idx_sqr;
517 Fr idx_sqr_three_times_a = Fr(idx_sqr_three) * a;
518 Fr x_a_term = Fr(6 * (domain_end - 1)) * a;
519 Fr three_a = a + a + a;
520 Fr six_a = three_a + three_a;
521
522 Fr three_a_plus_two_b = a_plus_b_times_2 + a;
523 Fr linear_term = Fr(domain_end - 1) * three_a_plus_two_b + (a_plus_b + c);
524 // For each new evaluation, we do only 6 field additions and 0 muls.
525 for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
526 result.value_at(idx + 1) = result.value_at(idx) + idx_sqr_three_times_a + linear_term;
527
528 idx_sqr_three_times_a += x_a_term + three_a;
529 x_a_term += six_a;
530
531 linear_term += three_a_plus_two_b;
532 }
533 } else {
534 for (size_t k = domain_end; k != EXTENDED_DOMAIN_END; ++k) {
535 result.value_at(k) = 0;
536 // compute each term v_j / (d_j*(x-x_j)) of the sum
537 for (size_t j = domain_start; j != domain_end; ++j) {
538 Fr term = value_at(j);
539 term *= Data::precomputed_denominator_inverses[LENGTH * k + j];
540 result.value_at(k) += term;
541 }
542 // scale the sum by the value of of B(x)
543 result.value_at(k) *= Data::full_numerator_values[k];
544 }
545 }
546 return result;
547 }
548
549 template <size_t INITIAL_LENGTH> void self_extend_from()
550 {
551 if constexpr (INITIAL_LENGTH == 2) {
552 const Fr delta = value_at(1) - value_at(0);
553 Fr next = value_at(1);
554 for (size_t idx = 2; idx < LENGTH; idx++) {
555 next += delta;
556 value_at(idx) = next;
557 }
558 }
559 }
560
567 Fr evaluate(const Fr& u) const
568 {
570 Fr full_numerator_value = 1;
571 for (size_t i = domain_start; i != domain_end; ++i) {
572 full_numerator_value *= u - i;
573 }
574
575 // build set of domain size-many denominator inverses 1/(d_i*(x_k - x_j)). will multiply against
576 // each of these (rather than to divide by something) for each barycentric evaluation
577 std::array<Fr, LENGTH> denominator_inverses;
578 for (size_t i = 0; i != LENGTH; ++i) {
579 Fr inv = Data::lagrange_denominators[i];
580 inv *= u - Data::big_domain[i]; // warning: need to avoid zero here
581 inv = Fr(1) / inv;
582 denominator_inverses[i] = inv;
583 }
584
585 Fr result = 0;
586 // compute each term v_j / (d_j*(x-x_j)) of the sum
587 for (size_t i = domain_start; i != domain_end; ++i) {
588 Fr term = value_at(i);
589 term *= denominator_inverses[i - domain_start];
590 result += term;
591 }
592 // scale the sum by the value of of B(x)
593 result *= full_numerator_value;
594 return result;
595 };
596
597 // Begin iterators
598 auto begin() { return evaluations.begin(); }
599 auto begin() const { return evaluations.begin(); }
600 // End iterators
601 auto end() { return evaluations.end(); }
602 auto end() const { return evaluations.end(); }
603};
604
605template <typename B, class Fr, size_t domain_end, size_t domain_start = 0>
606inline void read(B& it, Univariate<Fr, domain_end, domain_start>& univariate)
607{
608 using serialize::read;
609 read(it, univariate.evaluations);
610}
611
612template <typename B, class Fr, size_t domain_end, size_t domain_start = 0>
613inline void write(B& it, Univariate<Fr, domain_end, domain_start> const& univariate)
614{
615 using serialize::write;
616 write(it, univariate.evaluations);
617}
618
619template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0>
625
626template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0>
632
633template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0>
639
640template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0> class UnivariateView {
641 public:
642 static constexpr size_t LENGTH = domain_end - domain_start;
644 static constexpr size_t MONOMIAL_LENGTH = LENGTH > 1 ? 2 : 1;
646
647 UnivariateView() = default;
648
649 bool operator==(const UnivariateView& other) const
650 {
651 bool r = true;
652 r = r && (evaluations[0] == other.evaluations[0]);
653 // a view might have nonzero terms in its skip_count if accessing an original monomial
654 for (size_t i = skip_count + 1; i < LENGTH; ++i) {
655 r = r && (evaluations[i] == other.evaluations[i]);
656 }
657 return r;
658 };
659
660 const Fr& value_at(size_t i) const { return evaluations[i]; };
661
662 template <size_t full_domain_end, size_t full_domain_start = 0>
664 : evaluations(std::span<const Fr>(univariate_in.evaluations.data(), LENGTH)){};
665
667 requires(LENGTH > 1)
668 {
669 static_assert(domain_end >= 2);
670 static_assert(domain_start == 0);
671
673
674 result.coefficients[0] = evaluations[0];
675 result.coefficients[1] = evaluations[1] - evaluations[0];
676 result.coefficients[2] = evaluations[1];
677 return result;
678 }
679
686
693
695 {
697 size_t i = 0;
698 for (auto& eval : res.evaluations) {
699 if (i == 0 || i >= (skip_count + 1)) {
700 eval = -eval;
701 }
702 i++;
703 }
704 return res;
705 }
706
719
727
735
737 {
739 res += other;
740 return res;
741 }
742
744 {
746 res -= other;
747 return res;
748 }
749
751 {
753 res *= other;
754 return res;
755 }
756
764
765 // Output is immediately parsable as a list of integers by Python.
766 friend std::ostream& operator<<(std::ostream& os, const UnivariateView& u)
767 {
768 os << "[";
769 os << u.evaluations[0] << "," << std::endl;
770 for (size_t i = 1; i < u.evaluations.size(); i++) {
771 os << " " << u.evaluations[i];
772 if (i + 1 < u.evaluations.size()) {
773 os << "," << std::endl;
774 } else {
775 os << "]";
776 };
777 }
778 return os;
779 }
780};
781
782template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0>
788
789template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0>
795
796template <class Fr, size_t domain_end, size_t domain_start = 0, size_t skip_count = 0>
802
816template <typename T, typename U, std::size_t N, std::size_t... Is>
817std::array<T, sizeof...(Is)> array_to_array_aux(const std::array<U, N>& elements, std::index_sequence<Is...>)
818{
819 return { { T{ elements[Is] }... } };
820};
821
839template <typename T, typename U, std::size_t N> std::array<T, N> array_to_array(const std::array<U, N>& elements)
840{
841 // Calls the aux method that uses the index sequence to unpack all values in `elements`
842 return array_to_array_aux<T, U, N>(elements, std::make_index_sequence<N>());
843};
844
845} // namespace bb
846
847namespace std {
848template <typename T, size_t N> struct tuple_size<bb::Univariate<T, N>> : std::integral_constant<std::size_t, N> {};
849
850} // namespace std
A view of a univariate, also used to truncate univariates.
std::array< Fr, 3 > coefficients
coefficients is a length-3 array with the following representation:
A univariate polynomial represented by its values on {domain_start, domain_start + 1,...
Univariate & operator-=(const Fr &scalar)
Univariate operator*(const Univariate &other) const
Univariate operator-(const Univariate &other) const
Univariate & operator+=(const UnivariateView< Fr, domain_end, domain_start, skip_count > &view)
Fr & value_at(size_t i)
static Univariate serialize_from_buffer(uint8_t const *buffer)
Univariate operator+(const UnivariateView< Fr, domain_end, domain_start, skip_count > &view) 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...
static Univariate random_element()
static Univariate get_random()
Univariate & operator*=(const Univariate &other)
Univariate & operator*=(const UnivariateView< Fr, domain_end, domain_start, skip_count > &view)
Univariate & operator=(const Univariate &other)=default
bool operator==(const Univariate &other) const =default
Univariate(UnivariateView< Fr, domain_end, domain_start, skip_count > in)
std::vector< uint8_t > to_buffer() const
static constexpr size_t MONOMIAL_LENGTH
friend std::ostream & operator<<(std::ostream &os, const Univariate &u)
Univariate sqr() const
bool is_zero() const
Univariate< Fr, EXTENDED_DOMAIN_END, 0, NUM_SKIPPED_INDICES > extend_to() const
Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the evaluation...
static Univariate zero()
Univariate & operator+=(const Univariate &other)
Univariate & operator*=(const Fr &scalar)
auto end() const
Univariate(UnivariateCoefficientBasis< Fr, 3, has_a0_plus_a1 > monomial)
const Fr & value_at(size_t i) const
Univariate & operator+=(const Fr &scalar)
static constexpr size_t LENGTH
Univariate(Fr value)
Univariate< Fr, domain_end, domain_start > convert() const noexcept
Convert from a version with skipped evaluations to one without skipping (with zeroes in previously sk...
Univariate & operator=(Univariate &&other) noexcept=default
Univariate & operator-=(const Univariate &other)
Univariate(std::array< Fr, LENGTH > evaluations)
Univariate operator+(const Fr &scalar) const
auto begin() const
std::array< Fr, LENGTH > evaluations
Univariate(Univariate &&other) noexcept=default
Univariate(const Univariate &other)=default
static constexpr size_t SKIP_COUNT
Univariate operator*(const Fr &scalar) const
Univariate operator-() const
Univariate & self_sqr()
Univariate operator-(const UnivariateView< Fr, domain_end, domain_start, skip_count > &view) const
void self_extend_from()
Univariate operator*(const UnivariateView< Fr, domain_end, domain_start, skip_count > &view) const
Univariate & operator-=(const UnivariateView< Fr, domain_end, domain_start, skip_count > &view)
~Univariate()=default
Univariate operator-(const Fr &scalar) const
Univariate()=default
Univariate(UnivariateCoefficientBasis< Fr, 2, has_a0_plus_a1 > monomial)
Univariate operator+(const Univariate &other) const
A view of a univariate, also used to truncate univariates.
static constexpr size_t LENGTH
std::span< const Fr, LENGTH > evaluations
Univariate< Fr, domain_end, domain_start, skip_count > operator+(const UnivariateView &other) const
Univariate< Fr, domain_end, domain_start, skip_count > operator-() const
friend std::ostream & operator<<(std::ostream &os, const UnivariateView &u)
UnivariateView(const Univariate< Fr, full_domain_end, full_domain_start, skip_count > &univariate_in)
Univariate< Fr, domain_end, domain_start, skip_count > operator*(const Univariate< Fr, domain_end, domain_start, skip_count > &other) const
Univariate< Fr, domain_end, domain_start, skip_count > operator+(const Univariate< Fr, domain_end, domain_start, skip_count > &other) const
Univariate< Fr, domain_end, domain_start, skip_count > sqr() const
bool operator==(const UnivariateView &other) const
static constexpr size_t MONOMIAL_LENGTH
Univariate< Fr, domain_end, domain_start, skip_count > operator-(const Univariate< Fr, domain_end, domain_start, skip_count > &other) const
Univariate< Fr, domain_end, domain_start, skip_count > operator*(const UnivariateView &other) const
const Fr & value_at(size_t i) const
Univariate< Fr, domain_end, domain_start, skip_count > operator-(const Fr &other) const
Univariate< Fr, domain_end, domain_start, skip_count > operator*(const Fr &other) const
UnivariateView()=default
Univariate< Fr, domain_end, domain_start, skip_count > operator+(const Fr &other) const
Univariate< Fr, domain_end, domain_start, skip_count > operator-(const UnivariateView &other) const
const std::vector< FF > data
FF a
FF b
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
Entry point for Barretenberg command-line interface.
Univariate< Fr, domain_end, domain_start, skip_count > operator+(const Fr &ff, const Univariate< Fr, domain_end, domain_start, skip_count > &uv)
void read(B &it, field2< base_field, Params > &value)
std::conditional_t< is_field_type_v< Fr >, BarycentricDataCompileTime< Fr, domain_end, num_evals, domain_start >, BarycentricDataRunTime< Fr, domain_end, num_evals, domain_start > > BarycentricData
Exposes BarycentricData with compile time arrays if the type is bberg::field and runtime arrays other...
Univariate< Fr, domain_end, domain_start, skip_count > operator*(const Fr &ff, const Univariate< Fr, domain_end, domain_start, skip_count > &uv)
void write(B &buf, field2< base_field, Params > const &value)
Univariate< Fr, domain_end, domain_start, skip_count > operator-(const Fr &ff, const Univariate< Fr, domain_end, domain_start, skip_count > &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...
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by MSGPACK_FIEL...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by MSGPACK_FIE...
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
constexpr field invert() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()