pub struct FactoredMultilinear<P: PackedField, Data: BufferData<P> = Vec<P>> { /* private fields */ }Expand description
A multilinear that factorizes across disjoint runs of its variables.
Some weights are a product of small pieces rather than one table. An equality indicator over several axes factorizes across them, for instance.
Storing such a weight whole costs the product of the pieces’ lengths. Storing the pieces costs their sum.
whole: 2^(n_1 + n_2 + n_3) entries
factors: 2^n_1 + 2^n_2 + 2^n_3 entriesThe saving is what lets a sumcheck range over a space far too large to materialize, so long as nothing ever asks for the whole table at once.
§Variable order
Factors are held lowest run first.
A factor over n variables owns the next n bits of the index, above the bits the factors
before it own. So the last factor owns the highest variables, and is the one a fold consumes
first.
index = [ factor 0 bits | factor 1 bits | ... | last factor bits ]
lowest highest§Examples
// A weight over an operand axis, a shift axis, and a value axis.
let mut weight = FactoredMultilinear::new(vec![operand, shift, value]);
let at_index = weight.get(index);
weight.fold_highest_var(challenge);Where the factors’ packed words live.
Defaults to the heap, and the point of the parameter is that it need not be.
A caller proving out of an arena hands over arena-backed factors. This holds them as they are, rather than forcing a copy onto the heap.
Implementations§
Source§impl<P: PackedField, Data: BufferData<P>> FactoredMultilinear<P, Data>
impl<P: PackedField, Data: BufferData<P>> FactoredMultilinear<P, Data>
Sourcepub fn new(factors: impl IntoIterator<Item = FieldBuffer<P, Data>>) -> Self
pub fn new(factors: impl IntoIterator<Item = FieldBuffer<P, Data>>) -> Self
Builds a multilinear from its factors, lowest variable run first.
A factor with no variables is folded straight into the bound product rather than kept, since it holds a value and no axis.
Sourcepub fn get(&self, index: usize) -> P::Scalar
pub fn get(&self, index: usize) -> P::Scalar
The value at one vertex of the hypercube over the free variables.
Each factor reads the bits it owns, and the results multiply. So a lookup costs one multiplication per factor rather than one per variable.
§Panics
Panics if the index does not fit the free variables.
Sourcepub fn fold_highest_var(&mut self, challenge: P::Scalar)
pub fn fold_highest_var(&mut self, challenge: P::Scalar)
Fixes the highest free variable to a value.
The highest variable belongs to the last factor, so that is the factor this folds. A factor whose variables are all bound holds one value, which moves into the bound product.
§Panics
Panics if no variable is free.
Trait Implementations§
Source§impl<P: Clone + PackedField, Data: Clone + BufferData<P>> Clone for FactoredMultilinear<P, Data>
impl<P: Clone + PackedField, Data: Clone + BufferData<P>> Clone for FactoredMultilinear<P, Data>
Source§fn clone(&self) -> FactoredMultilinear<P, Data>
fn clone(&self) -> FactoredMultilinear<P, Data>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl<P, Data> Freeze for FactoredMultilinear<P, Data>
impl<P, Data> RefUnwindSafe for FactoredMultilinear<P, Data>
impl<P, Data> Send for FactoredMultilinear<P, Data>where
Data: Send,
impl<P, Data> Sync for FactoredMultilinear<P, Data>where
Data: Sync,
impl<P, Data> Unpin for FactoredMultilinear<P, Data>
impl<P, Data> UnsafeUnpin for FactoredMultilinear<P, Data>
impl<P, Data> UnwindSafe for FactoredMultilinear<P, Data>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more