65 static_assert(
N ==
VECTOR_FIELD_WIDTH,
"VectorField is fixed-width; N must equal VECTOR_FIELD_WIDTH");
74 template <
size_t N,
typename U = element_type>
77 static_assert(
N ==
VECTOR_FIELD_WIDTH,
"VectorField is fixed-width; N must equal VECTOR_FIELD_WIDTH");
86 size_t new_length = std::min(length,
span.size() -
offset);
119#define BB_VECTOR_PROXY_BINARY_OPS(Proxy, Value, Scalar) \
120 [[gnu::always_inline]] friend Value operator+(const Proxy& a, const Proxy& b) noexcept \
122 return Value(a) + Value(b); \
124 [[gnu::always_inline]] friend Value operator-(const Proxy& a, const Proxy& b) noexcept \
126 return Value(a) - Value(b); \
128 [[gnu::always_inline]] friend Value operator*(const Proxy& a, const Proxy& b) noexcept \
130 return Value(a) * Value(b); \
132 [[gnu::always_inline]] friend Value operator+(const Proxy& a, const Value& b) noexcept \
134 return Value(a) + b; \
136 [[gnu::always_inline]] friend Value operator+(const Value& a, const Proxy& b) noexcept \
138 return a + Value(b); \
140 [[gnu::always_inline]] friend Value operator-(const Proxy& a, const Value& b) noexcept \
142 return Value(a) - b; \
144 [[gnu::always_inline]] friend Value operator-(const Value& a, const Proxy& b) noexcept \
146 return a - Value(b); \
148 [[gnu::always_inline]] friend Value operator*(const Proxy& a, const Value& b) noexcept \
150 return Value(a) * b; \
152 [[gnu::always_inline]] friend Value operator*(const Value& a, const Proxy& b) noexcept \
154 return a * Value(b); \
156 [[gnu::always_inline]] friend Value operator+(const Proxy& a, const Scalar& s) noexcept \
158 return Value(a) + s; \
160 [[gnu::always_inline]] friend Value operator+(const Scalar& s, const Proxy& a) noexcept \
162 return s + Value(a); \
164 [[gnu::always_inline]] friend Value operator-(const Proxy& a, const Scalar& s) noexcept \
166 return Value(a) - s; \
168 [[gnu::always_inline]] friend Value operator-(const Scalar& s, const Proxy& a) noexcept \
170 return s - Value(a); \
172 [[gnu::always_inline]] friend Value operator*(const Proxy& a, const Scalar& s) noexcept \
174 return Value(a) * s; \
176 [[gnu::always_inline]] friend Value operator*(const Scalar& s, const Proxy& a) noexcept \
178 return s * Value(a); \
210 other.coefficients_.start_ = 0;
211 other.coefficients_.end_ = 0;
212 other.coefficients_.virtual_size_ = 0;
270 if (
this != &other) {
272 other.coefficients_.start_ = 0;
273 other.coefficients_.end_ = 0;
274 other.coefficients_.virtual_size_ = 0;
295 for (
size_t i = 0; i <
size(); i++) {
472 std::array<size_t, 5>
idx;
517 static_assert(
N ==
VECTOR_FIELD_WIDTH,
"VectorField is fixed-width; N must equal VECTOR_FIELD_WIDTH");
523 template <
size_t N,
typename U = Fr>
526 static_assert(
N ==
VECTOR_FIELD_WIDTH,
"VectorField is fixed-width; N must equal VECTOR_FIELD_WIDTH");
534 static_assert(
N ==
VECTOR_FIELD_WIDTH,
"VectorField is fixed-width; N must equal VECTOR_FIELD_WIDTH");
537 template <
size_t N,
typename U = Fr>
540 static_assert(
N ==
VECTOR_FIELD_WIDTH,
"VectorField is fixed-width; N must equal VECTOR_FIELD_WIDTH");
653 for (
size_t j = 0;
j < NUM_MASKED_ROWS;
j++) {
674template <
typename Fr>
677 const Fr& scaling_factor)
683 const size_t lo = *range.begin() + other.
start_index;
684 const size_t hi = lo + range.size();
699 vectorized_for<VECTOR_FIELD_WIDTH, Fr>(
700 lo, hi, [&](
auto ctx) { (*this)[ctx] = (*this)[ctx] + other[ctx] * scaling[ctx]; });
703template <
typename Fr>
714 [&other, scaling_factor,
this](
const ThreadChunk& chunk) {
715 BB_INLINE_STMT add_scaled_chunk(chunk, other, scaling_factor);
724template <
typename Fr>
731 const size_t lo = *range.begin() + other.
start_index;
732 const size_t hi = lo + range.size();
733 vectorized_for<VECTOR_FIELD_WIDTH, Fr>(lo, hi, [&](
auto ctx) { (*this)[ctx] = (*this)[ctx] + other[ctx]; });
736template <
typename Fr>
743 [&other,
this](
const ThreadChunk& chunk) { BB_INLINE_STMT add_chunk(chunk, other); },
749template <
typename Fr>
757 const size_t lo = *range.begin() + other.
start_index;
758 const size_t hi = lo + range.size();
759 vectorized_for<VECTOR_FIELD_WIDTH, Fr>(lo, hi, [&](
auto ctx) { (*this)[ctx] = (*this)[ctx] - other[ctx]; });
762template <
typename Fr>
769 [&other,
this](
const ThreadChunk& chunk) { BB_INLINE_STMT subtract_chunk(chunk, other); },
777template <
typename Fr>
780 auto range = chunk.
range(size());
784 const size_t lo = *range.begin() + start_index();
785 const size_t hi = lo + range.size();
787 vectorized_for<VECTOR_FIELD_WIDTH, Fr>(lo, hi, [&](
auto ctx) { (*this)[ctx] = (*this)[ctx] * scaling[ctx]; });
790template <
typename Fr>
810template <
typename Fr>
815template <
typename Fr>
819 source_spans.reserve(sources.size());
820 for (
const auto& source : sources) {
821 source_spans.emplace_back(source);
826template <
typename Fr>
843template <
typename Fr_>
852 if (coefficients.
size() == 0) {
856 const size_t n = evaluation_points.size();
860 return coefficients.
get(0);
871 size_t n_l = 1UL << (dim - 1);
874 auto tmp_ptr = _allocate_aligned_memory<Fr_>(n_l);
875 auto tmp = tmp_ptr.get();
878 if constexpr (is_native) {
885 Fr_ u_l = evaluation_points[0];
889 const size_t ALLOW_ONE_PAST_READ = 1;
890 for (
size_t i = 0; i < n_l; ++i) {
892 tmp[i] = coefficients.
get(i * 2 +
offset) +
893 u_l * (coefficients.
get(i * 2 + 1 +
offset, ALLOW_ONE_PAST_READ) - coefficients.
get(i * 2 +
offset));
897 for (
size_t l = 1; l < dim; ++l) {
898 n_l = 1UL << (dim - l - 1);
899 u_l = evaluation_points[l];
900 for (
size_t i = 0; i < n_l; ++i) {
901 tmp[i] = tmp[i * 2] + u_l * (tmp[(i * 2) + 1] - tmp[i * 2]);
907 for (
size_t i = dim; i < n; i++) {
908 result *= (Fr_(1) - evaluation_points[i]);
917template <
typename Fr_>
921 return _evaluate_mle(evaluation_points, coefficients,
false);
930 return os <<
"[ data " << p[0] <<
"]";
932 return os <<
"[ data\n"
933 <<
" " << p[0] <<
",\n"
934 <<
" " << p[1] <<
",\n"
936 <<
" " << p[p.
size() - 2] <<
",\n"
937 <<
" " << p[p.
size() - 1] <<
",\n"
941template <
typename Poly,
typename... Polys>
auto zip_polys(Poly&& poly, Polys&&... polys)
946 auto check_indices = [&](
const auto& other) {
951 (check_indices(polys), ...);
952 return zip_view(poly.indices(), poly.coeffs(), polys.coeffs()...);
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GTE(left, right,...)
#define BB_ASSERT_NO_WASM(expression,...)
#define BB_ASSERT_DEBUG(expression,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define BB_ASSERT_LTE(left, right,...)
#define BB_BENCH_NAME(name)
Polynomial(size_t size, size_t virtual_size, DontZeroMemory flag)
Polynomial shifted() const
Returns a Polynomial the left-shift of self.
size_t start_index() const
ScalarWriteProxy operator[](ScalarIndex ctx)
static Polynomial random(size_t size, size_t start_index=0)
ContiguousVectorWriteProxyT< typename U::Params > operator[](ContiguousVectorIndex< N > ctx)
static Polynomial shiftable(size_t size, size_t virtual_size, DontZeroMemory flag)
Overload of shiftable that leaves the backing memory uninitialized.
std::size_t virtual_size() const
Polynomial(Polynomial &&other) noexcept
VectorField< typename U::Params > operator[](VectorIndex< N > ctx) const
bool is_shiftable() const
Fr operator[](ScalarIndex ctx) const
SharedShiftedVirtualZeroesArray< Fr > coefficients_
Polynomial(const Polynomial &other)
void increase_virtual_size(const size_t size_in)
std::span< Fr > coeffs(size_t offset=0)
Strictly iterates the defined region of the polynomial. We keep this explicit, instead of having an i...
void copy_vector(const std::vector< T > &vec)
Copy over values from a vector that is of a convertible type.
Polynomial & operator*=(const Fr &scaling_factor)
sets this = p(X) to s⋅p(X)
auto indexed_values() const
void add_scaled(PolynomialSpan< const Fr > other, const Fr &scaling_factor)
adds the polynomial q(X) 'other', multiplied by a scaling factor.
void subtract_chunk(const ThreadChunk &chunk, PolynomialSpan< const Fr > other)
Polynomial & operator=(const Polynomial &other)
VectorWriteProxyT< typename U::Params > operator[](VectorIndex< N > ctx)
void add_scaled_chunk(const ThreadChunk &chunk, PolynomialSpan< const Fr > other, const Fr &scaling_factor)
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,...
void add_masking()
Write random ZK masking values at positions {1, 2, 3} (the disabled head region after the zero row).
Polynomial(const Polynomial &other, size_t target_size)
static Polynomial shiftable(size_t size, size_t virtual_size, bool masked=false)
Utility to create a shiftable polynomial of given size and virtual size.
static Polynomial shiftable(size_t virtual_size, bool masked=false)
Utility to create a shiftable polynomial of given virtual size.
const Fr & get(size_t i, size_t virtual_padding=0) const
Retrieves the value at the specified index.
Polynomial & operator-=(PolynomialSpan< const Fr > other)
subtracts the polynomial q(X) 'other'.
static Polynomial random(size_t size, size_t virtual_size, size_t start_index)
Polynomial reverse() const
Returns the polynomial equal to the reverse of self.
void add_chunk(const ThreadChunk &chunk, PolynomialSpan< const Fr > other)
Fr & at(size_t index)
Our mutable accessor, unlike operator[]. We abuse precedent a bit to differentiate at() and operator[...
bool operator==(Polynomial const &rhs) const
VectorField< typename U::Params > operator[](ContiguousVectorIndex< N > ctx) const
void shrink_end_index(const size_t new_end_index)
The end_index of the polynomial is decreased without any memory de-allocation. This is a very fast wa...
Polynomial & operator+=(PolynomialSpan< const Fr > other)
adds the polynomial q(X) 'other'.
const Fr & at(size_t index) const
Polynomial(size_t size, DontZeroMemory flag)
static Polynomial create_non_parallel_zero_init(size_t size, size_t virtual_size)
A factory to construct a polynomial where parallel initialization is not possible (e....
void factor_roots(const Fr &root)
Divides p(X) by (X-r) in-place. Assumes that p(rⱼ)=0 for all j.
void allocate_backing_memory(size_t size, size_t virtual_size, size_t start_index)
void set_if_valid_index(size_t index, const Fr &value)
Like setting with at(), but allows zeroes to result in no set.
bool is_zero() const
Check whether or not a polynomial is identically zero.
std::span< const Fr > coeffs(size_t offset=0) const
bool is_valid_set_index(size_t index) const
Is this index valid for a set? i.e. calling poly.at(index) = value.
const Fr & operator[](size_t i) const
Polynomial & operator=(Polynomial &&other) noexcept
void multiply_chunk(const ThreadChunk &chunk, const Fr &scaling_factor)
Polynomial full() const
Copys the polynomial, but with the whole address space usable. The value of the polynomial remains th...
const Fr & operator[](size_t i)
Polynomial(std::span< const Fr > coefficients)
constexpr T get_msb(const T in)
void factor_roots(std::span< Fr > polynomial, const Fr &root)
Divides p(X) by (X-r) in-place.
constexpr size_t ALWAYS_MULTITHREAD
constexpr size_t FF_ADDITION_COST
constexpr size_t FF_MULTIPLICATION_COST
Entry point for Barretenberg command-line interface.
std::ostream & operator<<(std::ostream &os, CircuitKind kind)
std::shared_ptr< Fr[]> _allocate_aligned_memory(size_t n_elements)
void add_scaled_batch(Polynomial< Fr > &dst, std::span< const PolynomialSpan< const Fr > > sources, std::span< const Fr > scalars)
Fused parallel batched add: dst += sum_i scalars[i] * sources[i].
constexpr size_t VECTOR_FIELD_WIDTH
auto zip_polys(Poly &&poly, Polys &&... polys)
void parallel_for_heuristic(size_t num_points, const std::function< void(size_t, size_t, size_t)> &func, size_t heuristic_cost)
Split a loop into several loops running in parallel based on operations in 1 iteration.
constexpr ScalarIndex shift(ScalarIndex ctx, size_t d)
Fr_ _evaluate_mle(std::span< const Fr_ > evaluation_points, const SharedShiftedVirtualZeroesArray< Fr_ > &coefficients, bool shift)
Internal implementation to support both native and stdlib circuit field types.
Fr_ generic_evaluate_mle(std::span< const Fr_ > evaluation_points, const SharedShiftedVirtualZeroesArray< Fr_ > &coefficients)
Static exposed implementation to support both native and stdlib circuit field types.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
#define BB_VECTOR_PROXY_BINARY_OPS(Proxy, Value, Scalar)
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
bb::VectorAffineElementPushSpan< BaseParams > rhs
A shared pointer array template that represents a virtual array filled with zeros up to virtual_size_...
const T & get(size_t index, size_t virtual_padding=0) const
Retrieves the value at the specified index, or 'zero'. Optimizes for e.g. 256-bit fields by storing a...
size_t virtual_size() const
size_t end_
The ending index of the memory-backed range.
ContiguousVectorWriteProxyT & operator=(const VectorField< Params_ > &v)
friend Fr operator*(const Fr &a, const ScalarWriteProxy &b) noexcept
friend Fr operator+(const ScalarWriteProxy &a, const ScalarWriteProxy &b) noexcept
friend Fr operator*(const ScalarWriteProxy &a, const Fr &b) noexcept
friend Fr operator+(const ScalarWriteProxy &a, const Fr &b) noexcept
friend Fr operator-(const ScalarWriteProxy &a, const Fr &b) noexcept
friend Fr operator-(const ScalarWriteProxy &a, const ScalarWriteProxy &b) noexcept
friend Fr operator*(const ScalarWriteProxy &a, const ScalarWriteProxy &b) noexcept
friend Fr operator+(const Fr &a, const ScalarWriteProxy &b) noexcept
ScalarWriteProxy & operator=(const Fr &v)
friend Fr operator-(const Fr &a, const ScalarWriteProxy &b) noexcept
VectorWriteProxyT & operator=(const VectorField< Params_ > &v)
std::array< size_t, 5 > idx
PolynomialSpan subspan(size_t offset, size_t length)
std::remove_const_t< Fr > element_type
Fr & operator[](size_t index)
VectorField< typename U::Params > operator[](ContiguousVectorIndex< N > ctx) const
PolynomialSpan(size_t start_index, std::span< Fr > span)
element_type operator[](ScalarIndex ctx) const
VectorField< typename U::Params > operator[](VectorIndex< N > ctx) const
const Fr & operator[](size_t index) const
auto range(size_t size, size_t offset=0) const
static VectorField gather(const Field *base, std::array< size_t, 5 > idx, size_t offset=0) noexcept
void store_to(Field *base) const noexcept
void scatter(Field *base, std::array< size_t, 5 > idx, size_t offset=0) const noexcept
std::array< size_t, N > idx
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr bool is_zero() const noexcept
void throw_or_abort(std::string const &err)