2#include "barretenberg/common/assert.hpp"
3#include "barretenberg/common/serialize.hpp"
4#include "barretenberg/polynomials/barycentric.hpp"
16template <
class Fr,
size_t view_domain_end,
size_t view_domain_start>
class UnivariateView;
23template <
class Fr,
size_t domain_end,
size_t domain_start = 0>
class Univariate {
25 static constexpr size_t LENGTH = domain_end - domain_start;
29 std::array<Fr, LENGTH> evaluations;
33 explicit Univariate(std::array<Fr, LENGTH> evaluations)
34 : evaluations(evaluations)
46 for (
size_t i = 0; i < LENGTH; ++i) {
47 evaluations[i] = value;
54 for (
size_t i = 0; i < in.evaluations.size(); ++i) {
55 evaluations[i] = in.evaluations[i];
59 Fr& value_at(
size_t i) {
return evaluations[i - domain_start]; };
60 const Fr& value_at(
size_t i)
const {
return evaluations[i - domain_start]; };
61 size_t size() {
return evaluations.size(); };
64 [[nodiscard]] std::vector<uint8_t> to_buffer()
const { return ::to_buffer(evaluations); }
69 static Univariate serialize_from_buffer(uint8_t
const* buffer)
72 std::read(buffer, result.evaluations);
79 for (
size_t i = 0; i != LENGTH; ++i) {
80 output.value_at(i) = Fr::random_element();
88 for (
size_t i = 0; i != LENGTH; ++i) {
89 output.value_at(i) = Fr::zero();
94 static Univariate random_element() {
return get_random(); };
97 bool operator==(
const Univariate& other)
const =
default;
101 for (
size_t i = 0; i < LENGTH; ++i) {
102 evaluations[i] += other.evaluations[i];
108 for (
size_t i = 0; i < LENGTH; ++i) {
109 evaluations[i] -= other.evaluations[i];
115 for (
size_t i = 0; i < LENGTH; ++i) {
116 evaluations[i] *= other.evaluations[i];
136 for (
auto& eval : res.evaluations) {
152 for (
auto& eval : evaluations) {
160 for (
auto& eval : evaluations) {
167 for (
auto& eval : evaluations) {
197 for (
size_t i = 0; i < LENGTH; ++i) {
198 evaluations[i] += view.evaluations[i];
205 for (
size_t i = 0; i < LENGTH; ++i) {
206 evaluations[i] -= view.evaluations[i];
213 for (
size_t i = 0; i < LENGTH; ++i) {
214 evaluations[i] *= view.evaluations[i];
241 friend std::ostream& operator<<(std::ostream& os,
const Univariate& u)
244 os << u.evaluations[0] <<
"," << std::endl;
245 for (
size_t i = 1; i < u.evaluations.size(); i++) {
246 os <<
" " << u.evaluations[i];
247 if (i + 1 < u.evaluations.size()) {
248 os <<
"," << std::endl;
274 const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start;
276 static_assert(EXTENDED_LENGTH >= LENGTH);
280 std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin());
282 if constexpr (LENGTH == 2) {
283 Fr delta = value_at(1) - value_at(0);
284 static_assert(EXTENDED_LENGTH != 0);
285 for (
size_t idx = domain_start; idx < EXTENDED_DOMAIN_END - 1; idx++) {
286 result.value_at(idx + 1) = result.value_at(idx) + delta;
290 for (
size_t k = domain_end; k != EXTENDED_DOMAIN_END; ++k) {
291 result.value_at(k) = 0;
293 for (
size_t j = domain_start; j != domain_end; ++j) {
294 Fr term = value_at(j);
295 term *= Data::precomputed_denominator_inverses[LENGTH * k + j];
296 result.value_at(k) += term;
299 result.value_at(k) *= Data::full_numerator_values[k];
314 Fr full_numerator_value = 1;
315 for (
size_t i = domain_start; i != domain_end; ++i) {
316 full_numerator_value *= u - i;
321 std::array<Fr, LENGTH> denominator_inverses;
322 for (
size_t i = 0; i != LENGTH; ++i) {
323 Fr inv = Data::lagrange_denominators[i];
324 inv *= u - Data::big_domain[i];
326 denominator_inverses[i] = inv;
331 for (
size_t i = domain_start; i != domain_end; ++i) {
332 Fr term = value_at(i);
333 term *= denominator_inverses[i - domain_start];
337 result *= full_numerator_value;
342template <
typename B,
class Fr,
size_t domain_end,
size_t domain_start = 0>
343inline void read(B& it, Univariate<Fr, domain_end, domain_start>& univariate)
345 using serialize::read;
346 read(it, univariate.evaluations);
349template <
typename B,
class Fr,
size_t domain_end,
size_t domain_start = 0>
350inline void write(B& it, Univariate<Fr, domain_end, domain_start>
const& univariate)
352 using serialize::write;
353 write(it, univariate.evaluations);
356template <
class Fr,
size_t domain_end,
size_t domain_start = 0>
class UnivariateView {
358 static constexpr size_t LENGTH = domain_end - domain_start;
359 std::span<const Fr, LENGTH> evaluations;
363 const Fr& value_at(
size_t i)
const {
return evaluations[i]; };
365 template <
size_t full_domain_end,
size_t full_domain_start = 0>
367 : evaluations(std::span<const Fr>(univariate_in.evaluations.data(), LENGTH)){};
386 for (
auto& eval : res.evaluations) {
442 friend std::ostream& operator<<(std::ostream& os,
const UnivariateView& u)
445 os << u.evaluations[0] <<
"," << std::endl;
446 for (
size_t i = 1; i < u.evaluations.size(); i++) {
447 os <<
" " << u.evaluations[i];
448 if (i + 1 < u.evaluations.size()) {
449 os <<
"," << std::endl;
471template <
typename T,
typename U, std::size_t N, std::size_t... Is>
472std::array<T,
sizeof...(Is)>
array_to_array_aux(
const std::array<U, N>& elements, std::index_sequence<Is...>)
474 return { { T{ elements[Is] }... } };
493template <
typename T,
typename U, std::
size_t N> std::array<T, N>
array_to_array(
const std::array<U, N>& elements)
496 return array_to_array_aux<T, U, N>(elements, std::make_index_sequence<N>());
A view of a univariate, also used to truncate univariates.
Definition: univariate.hpp:356
A univariate polynomial represented by its values on {domain_start, domain_start + 1,...
Definition: univariate.hpp:23
Univariate< Fr, EXTENDED_DOMAIN_END > extend_to() const
Given a univariate f represented by {f(domain_start), ..., f(domain_end - 1)}, compute the evaluation...
Definition: univariate.hpp:272
Fr evaluate(const Fr &u)
Evaluate a univariate at a point u not known at compile time and assumed not to be in the domain (els...
Definition: univariate.hpp:311
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a cons...
Definition: constexpr_utils.hpp:16
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...
Definition: univariate.hpp:472
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).
Definition: univariate.hpp:493
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...
Definition: barycentric.hpp:257