Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libiop/algebra/exponentiation.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ std::vector<FieldT> subspace_to_power_of_two(const affine_subspace<FieldT> &S,
el = libiop::power(el, power_of_two);
}

const FieldT offset_power = libiop::power(S.offset(), power_of_two);
return all_subset_sums<FieldT>(basis_powers, offset_power);
const FieldT shift_power = libiop::power(S.shift(), power_of_two);
return all_subset_sums<FieldT>(basis_powers, shift_power);
}

template<typename FieldT>
Expand Down
6 changes: 3 additions & 3 deletions libiop/algebra/fft.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ std::vector<FieldT> additive_FFT(const std::vector<FieldT> &poly_coeffs,
size_t recursed_betas_ptr = 0;

std::vector<FieldT> betas2(domain.basis());
FieldT shift2 = domain.offset();
FieldT shift2 = domain.shift();
for (size_t j = 0; j < m; ++j)
{
FieldT beta = betas2[m-1-j];
Expand Down Expand Up @@ -135,7 +135,7 @@ std::vector<FieldT> additive_IFFT(const std::vector<FieldT> &evals,
std::vector<FieldT> recursed_twists(m, FieldT(0));

std::vector<FieldT> betas2(domain.basis());
FieldT shift2 = domain.offset();
FieldT shift2 = domain.shift();
for (size_t j = 0; j < m; ++j)
{
const FieldT beta = betas2[m-1-j];
Expand Down Expand Up @@ -439,7 +439,7 @@ std::vector<FieldT> IFFT_of_known_degree_over_field_subset(
field_subset<FieldT> domain)
{
/** We do an IFFT over the minimal subgroup needed for this known degree.
* We take the subgroup with the coset's offset as an element.
* We take the subgroup with the coset's shift as an element.
* The evaluations in this coset are every nth element of the evaluations
* over the entire domain, where n = |domain| / |degree|
*/
Expand Down
1 change: 0 additions & 1 deletion libiop/algebra/field_subset/field_subset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ class field_subset {

FieldT generator() const;

const FieldT& offset() const;
const FieldT shift() const;
const std::vector<FieldT>& basis() const;

Expand Down
14 changes: 3 additions & 11 deletions libiop/algebra/field_subset/field_subset.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ field_subset<FieldT> field_subset<FieldT>::get_subset_of_order(const std::size_t
input_subspace_basis.resize(subset_dim);
return field_subset<FieldT>(
affine_subspace<FieldT>(input_subspace_basis,
this->offset()));
this->shift()));
}
case multiplicative_coset_type:
// Assumes this subgroup's generator is the default generator for a subgroup of that order.
Expand Down Expand Up @@ -288,20 +288,12 @@ FieldT field_subset<FieldT>::generator() const
return this->coset_->generator();
}

template<typename FieldT>
const FieldT& field_subset<FieldT>::offset() const
{
assert(this->type_ == affine_subspace_type);

return this->subspace_->offset();
}

template<typename FieldT>
const FieldT field_subset<FieldT>::shift() const
{
assert(this->type_ == multiplicative_coset_type);

return this->coset_->shift();
return this->type_ == multiplicative_coset_type?
this->coset_->shift() : this->subspace_->shift();
}

template<typename FieldT>
Expand Down
2 changes: 1 addition & 1 deletion libiop/algebra/field_subset/subgroup.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ std::size_t multiplicative_subgroup_base<FieldT>::reindex_by_subgroup(const std:
/** Let x be the number of elements in G \ S, for every element in S. Then x = (|G|/|S| - 1).
* At index i in G \ S, the number of elements in S that appear before the index in G to which
* i corresponds to, is floor(i / x) + 1.
* The +1 is because index 0 of G is S_0, so the position is offset by at least one.
* The +1 is because index 0 of G is S_0, so the position is shift by at least one.
* The floor(i / x) term is because after x elements in G \ S, there is one more element from S
* that will have appeared in G. */
const std::size_t x = order_g_over_s - 1;
Expand Down
12 changes: 6 additions & 6 deletions libiop/algebra/field_subset/subspace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ class linear_subspace {
template<typename FieldT>
class affine_subspace : public linear_subspace<FieldT> {
protected:
FieldT offset_;
FieldT shift_;

public:
affine_subspace() = default;
affine_subspace(const std::vector<FieldT> &basis, const FieldT &offset = FieldT(0));
affine_subspace(const linear_subspace<FieldT> &base_space, const FieldT &offset = FieldT(0));
affine_subspace(linear_subspace<FieldT> &&base_space, const FieldT &offset = FieldT(0));
affine_subspace(const std::vector<FieldT> &basis, const FieldT &shift = FieldT(0));
affine_subspace(const linear_subspace<FieldT> &base_space, const FieldT &shift = FieldT(0));
affine_subspace(linear_subspace<FieldT> &&base_space, const FieldT &shift = FieldT(0));

const FieldT& offset() const;
const FieldT shift() const;

std::vector<FieldT> all_elements() const;
FieldT element_by_index(const std::size_t index) const;
Expand All @@ -68,7 +68,7 @@ class affine_subspace : public linear_subspace<FieldT> {

static affine_subspace<FieldT> shifted_standard_basis(
const std::size_t dimension,
const FieldT& offset);
const FieldT& shift);
static affine_subspace<FieldT> random_affine_subspace(const std::size_t dimension);

bool operator==(const affine_subspace<FieldT> &other) const;
Expand Down
42 changes: 21 additions & 21 deletions libiop/algebra/field_subset/subspace.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -128,72 +128,72 @@ bool linear_subspace<FieldT>::operator!=(const linear_subspace<FieldT> &other) c

template<typename FieldT>
affine_subspace<FieldT>::affine_subspace(const std::vector<FieldT> &basis,
const FieldT &offset) :
linear_subspace<FieldT>(basis), offset_(offset)
const FieldT &shift) :
linear_subspace<FieldT>(basis), shift_(shift)
{
}

template<typename FieldT>
affine_subspace<FieldT>::affine_subspace(
const linear_subspace<FieldT> &base_space,
const FieldT &offset) :
const FieldT &shift) :
linear_subspace<FieldT>(base_space),
offset_(offset)
shift_(shift)
{
}

template<typename FieldT>
affine_subspace<FieldT>::affine_subspace(
linear_subspace<FieldT> &&base_space,
const FieldT &offset) :
const FieldT &shift) :
linear_subspace<FieldT>(std::move(base_space)),
offset_(offset)
shift_(shift)
{
}

template<typename FieldT>
const FieldT& affine_subspace<FieldT>::offset() const
const FieldT affine_subspace<FieldT>::shift() const
{
return this->offset_;
return this->shift_;
}

template<typename FieldT>
std::vector<FieldT> affine_subspace<FieldT>::all_elements() const
{
return all_subset_sums<FieldT>(this->basis_, this->offset_);
return all_subset_sums<FieldT>(this->basis_, this->shift_);
}

template<typename FieldT>
FieldT affine_subspace<FieldT>::element_by_index(const std::size_t index) const
{
return (this->offset_ + (linear_subspace<FieldT>::element_by_index(index)));
return (this->shift_ + (linear_subspace<FieldT>::element_by_index(index)));
}


template<typename FieldT>
bool internal_element_in_subset(const typename libiop::enable_if<is_multiplicative<FieldT>::value, FieldT>::type x,
FieldT offset, size_t dimension)
FieldT shift, size_t dimension)
{
throw std::invalid_argument("subspace.element_in_subset() is only supported for binary fields");
}

template<typename FieldT>
bool internal_element_in_subset(const typename libiop::enable_if<is_additive<FieldT>::value, FieldT>::type x,
FieldT offset, size_t dimension)
FieldT shift, size_t dimension)
{
/** TODO: Implement this case */
if (dimension > 64)
{
throw std::invalid_argument(
"subspace.element_in_subset() is currently unimplimented for basis of dimension greater than 64");
}
/** We first remove the offset, and then test if an element is in the standard basis.
/** We first remove the shift, and then test if an element is in the standard basis.
* It is in the standard basis if for all i >= basis.dimension(), the coefficient of x^i is 0.
* Due to the representation of field elements,
* this corresponds to all but the first basis.dimension() bits being 0.
* (using little endian ordering)
*/
const std::vector<uint64_t> words = (x + offset).as_words();
const std::vector<uint64_t> words = (x + shift).as_words();
/* Check that all but the least significant 64 bits are 0 */
for (size_t i = 1; i < words.size(); i++)
{
Expand All @@ -211,7 +211,7 @@ bool affine_subspace<FieldT>::element_in_subset(const FieldT x) const
{
if (this->is_standard_basis_)
{
return internal_element_in_subset(x, this->offset_, this->dimension());
return internal_element_in_subset(x, this->shift_, this->dimension());
}
throw std::invalid_argument("subspace.element_in_subset() is only supported for standard basis");
}
Expand All @@ -221,7 +221,7 @@ FieldT affine_subspace<FieldT>::element_outside_of_subset() const
{
if (this->is_standard_basis_)
{
return this->offset() + FieldT(1ull << this->dimension());
return this->shift() + FieldT(1ull << this->dimension());
}
throw std::invalid_argument("subspace.element_outside_of_subset() is only supported for standard basis");
}
Expand Down Expand Up @@ -255,26 +255,26 @@ linear_subspace<FieldT> standard_basis(const std::size_t dimension)
template<typename FieldT>
affine_subspace<FieldT> affine_subspace<FieldT>::shifted_standard_basis(
const std::size_t dimension,
const FieldT& offset)
const FieldT& shift)
{
const linear_subspace<FieldT> basis =
linear_subspace<FieldT>::standard_basis(dimension);
return affine_subspace<FieldT>(std::move(basis), offset);
return affine_subspace<FieldT>(std::move(basis), shift);
}

template<typename FieldT>
affine_subspace<FieldT> affine_subspace<FieldT>::random_affine_subspace(const std::size_t dimension)
{
const linear_subspace<FieldT> basis =
linear_subspace<FieldT>::standard_basis(dimension);
const FieldT offset = FieldT::random_element();
return affine_subspace<FieldT>(std::move(basis), offset);
const FieldT shift = FieldT::random_element();
return affine_subspace<FieldT>(std::move(basis), shift);
}

template<typename FieldT>
bool affine_subspace<FieldT>::operator==(const affine_subspace<FieldT> &other) const
{
return linear_subspace<FieldT>::operator==(other) && this->offset_ == other->offset_;
return linear_subspace<FieldT>::operator==(other) && this->shift_ == other->shift_;
}

} // namespace libiop
8 changes: 4 additions & 4 deletions libiop/algebra/lagrange.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ std::vector<FieldT> lagrange_cache<FieldT>::subspace_coefficients_for(
* This already has c cached, which allows the shifted V to be calculated directly in one pass. */
const FieldT k = this->vp_.evaluation_at_point(interpolation_point) * this->c_;
const std::vector<FieldT> V =
all_subset_sums<FieldT>(this->domain_.basis(), interpolation_point + this->domain_.offset());
all_subset_sums<FieldT>(this->domain_.basis(), interpolation_point + this->domain_.shift());
// Handle check if interpolation point is in domain
if (this->interpolation_domain_intersects_domain_ && k == FieldT::zero()) {
std::vector<FieldT> result(this->domain_.num_elements(), FieldT::zero());
Expand Down Expand Up @@ -230,21 +230,21 @@ std::vector<FieldT> lagrange_coefficients(const affine_subspace<FieldT> &domain,
Our computation below computes:

k = (\prod_{i} \alpha - V[i]) = Zero_V(\alpha)
c = 1/{\prod_{j > 0} (V[j] - domain.offset()) = 1 / (Z_{V - offset} / X)(0)
c = 1/{\prod_{j > 0} (V[j] - domain.shift()) = 1 / (Z_{V - shift} / X)(0)

and inverses of (\alpha - V[0]), ..., (\alpha - V[2^n-1])

Then L[j] = k * c / (\alpha - V[j]).
*/

vanishing_polynomial<FieldT> Z(domain);
/* (Z_{V - offset} / X)(0) is the formal derivative of Z_V,
/* (Z_{V - shift} / X)(0) is the formal derivative of Z_V,
* as the affine shift only affects the constant coefficient. */
const FieldT c = Z.formal_derivative_at_point(FieldT::zero()).inverse();
const FieldT k = Z.evaluation_at_point(interpolation_point);

std::vector<FieldT> V =
all_subset_sums<FieldT>(domain.basis(), interpolation_point + domain.offset());
all_subset_sums<FieldT>(domain.basis(), interpolation_point + domain.shift());

const std::vector<FieldT> V_inv = batch_inverse_and_mul<FieldT>(V, c * k);

Expand Down
2 changes: 1 addition & 1 deletion libiop/algebra/polynomials/lagrange_polynomial.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ std::vector<FieldT> lagrange_polynomial<FieldT>::evaluations_over_field_subset(
* The additive case admits a faster method to create it, hence the separation */
if (this->S_.type() == affine_subspace_type)
{
denominator = all_subset_sums<FieldT>(evaldomain.basis(), this->x_ + evaldomain.offset());
denominator = all_subset_sums<FieldT>(evaldomain.basis(), this->x_ + evaldomain.shift());
}
else if (this->S_.type() == multiplicative_coset_type)
{
Expand Down
22 changes: 11 additions & 11 deletions libiop/algebra/polynomials/linearized_polynomial.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@ std::vector<FieldT> linearized_polynomial<FieldT>::evaluations_over_subspace(con

Therefore, evaluating over subspace below, we subtract constant
term from evaluations over the basis, but include the constant
term in the offset calculation. */
term in the shift calculation. */

std::vector<FieldT> eval_at_basis(S.basis());
std::for_each(eval_at_basis.begin(), eval_at_basis.end(),
[this](FieldT &el) {
el = (this->evaluation_at_point(el) -
this->constant_coefficient());
});
const FieldT offset = this->evaluation_at_point(S.offset());
const FieldT shift = this->evaluation_at_point(S.shift());

return all_subset_sums<FieldT>(eval_at_basis, offset);
return all_subset_sums<FieldT>(eval_at_basis, shift);
}

template<typename FieldT>
Expand Down Expand Up @@ -191,17 +191,17 @@ bool linearized_polynomial<FieldT>::operator!=(const linearized_polynomial<Field
}

template<typename FieldT>
void add_scalar_multiple_at_offset(std::vector<FieldT> &result,
void add_scalar_multiple_at_shift(std::vector<FieldT> &result,
const std::vector<FieldT> &p,
const FieldT &factor,
const size_t offset) {
const size_t shift) {
// This is a helper method for linearized polynomial * polynomial
// It adds factor * p to result, starting at offset
// It adds factor * p to result, starting at shift
if (factor == FieldT::zero()) {
return;
}
for (std::size_t i = 0; i < p.size(); i++) {
result[i + offset] += p[i] * factor;
result[i + shift] += p[i] * factor;
}
}

Expand All @@ -212,16 +212,16 @@ polynomial<FieldT> linearized_polynomial<FieldT>::operator*(const polynomial<Fie
// which is L[0] * p + L[1] * p * x + L[2] * p * x^2 + L[3] * p * x^4 + ...
// The polynomial coefficient representation has the constant term on the left,
// and higher degrees growing towards the right.
// This adds each term progressively, using add_scalar_multiple_at_offset
// This adds each term progressively, using add_scalar_multiple_at_shift

// Set num elements in result correctly
std::vector<FieldT> result(p.degree() + 1 + this->degree(), FieldT::zero());
const std::vector<FieldT> p_coeff = p.coefficients();
// set result to be L[0] * p
add_scalar_multiple_at_offset(result, p_coeff, this->coefficients_[0], 0);
add_scalar_multiple_at_shift(result, p_coeff, this->coefficients_[0], 0);
for (std::size_t i = 1; i < this->coefficients_.size(); i++) {
std::size_t offset = 1 << (i - 1);
add_scalar_multiple_at_offset(result, p_coeff, this->coefficients_[i], offset);
std::size_t shift = 1 << (i - 1);
add_scalar_multiple_at_shift(result, p_coeff, this->coefficients_[i], shift);
}
return polynomial<FieldT>(std::move(result));
}
Expand Down
2 changes: 1 addition & 1 deletion libiop/algebra/polynomials/vanishing_polynomial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class vanishing_polynomial : public polynomial_base<FieldT> {
// subspace type
linearized_polynomial<FieldT> linearized_polynomial_;
// multiplicative coset type
FieldT vp_offset_; /* offset^|H| for cosets, 1 for subgroups */
FieldT vp_shift_; /* shift^|H| for cosets, 1 for subgroups */

public:
explicit vanishing_polynomial() {};
Expand Down
Loading