Files
linea-monorepo/prover/symbolic/simplify/rmpolyeval.go
AlexandreBelling 7334693931 Prover(perf): faster global constraints compilation (#704)
* bench(global): adds a benchmark for the global constraint compiler

* perf(merging): accumulates the factors before creating the expression

* perf(product): computes the ESH without using a smart-vector

* perf(factor): preallocations in the factorization algorithm

* perf(removeZeroes): implements a lazy allocation mechanism in removeZeroCoeffs

* perfs(alloc): counts the ret elements before returning in expandTerms to minimze the number of allocations.

* perf(factor): use an integer map instead of a field.Element map when possible

* fixup(expands): fix the skip condition for term expansion

* perf(constructor): improves the immutable constructors to reduce the number of calls to NewProduct and NewLinComb

* feat(repr): adds a json repr function to help debugging

* test(constructor): cleans the test of the constructors

* perf(factor): address maps using the first limb of a field.Element instead of the full field.Element

* fixup(commit): adds missing file in previous commit

* perf(factor): reduce the number of calls to rankChildren

* perf(rmpolyeval): creates the equivalent expression more directly to save on unnecessary optims

* perf(factors): use a counter in getCommonProdParentOfCs

* perf(factor): remove map copy from findGdChildrenGroup and replace getCommonProdParent by a simpler function

* clean(factor): remove unneeded function and imports

* feat(utils): adds a generic sort interface implementation

* perf(rankChildren): lazy allocation of the map to save on allocations

* perf(factorize): reduces the loop-bound for factorizeExpression

* (chore): fix a missing argument and format gofmt

* feat: readd test

---------

Signed-off-by: AlexandreBelling <alexandrebelling8@gmail.com>
Co-authored-by: gusiri <dreamerty@postech.ac.kr>
2025-03-21 20:55:54 +09:00

45 lines
1.2 KiB
Go

package simplify
import (
sym "github.com/consensys/linea-monorepo/prover/symbolic"
)
// removePolyEval rewrites all the polyeval as an equivalent sums of products
func removePolyEval(e *sym.Expression) *sym.Expression {
constructor := func(oldExpr *sym.Expression, newChildren []*sym.Expression) *sym.Expression {
_, ok := oldExpr.Operator.(sym.PolyEval)
if !ok {
return oldExpr.SameWithNewChildren(newChildren)
}
x := newChildren[0]
cs := newChildren[1:]
if len(cs) == 0 {
return oldExpr // Handle edge case where there are no coefficients
}
// Precompute powers of x
monomialTerms := make([]any, len(cs))
for i := 0; i < len(cs); i++ {
// We don't use the default constructor because it will collapse the
// intermediate terms into a single term. The intermediates are useful because
// they tell the evaluator to reuse the intermediate terms instead of
// computing x^i for every term.
monomialTerms[i] = any(sym.NewProduct([]*sym.Expression{cs[i], x}, []int{1, i}))
}
acc := sym.Add(monomialTerms...)
if oldExpr.ESHash != acc.ESHash {
panic("ESH was altered")
}
return acc
}
return e.ReconstructBottomUp(constructor)
}