github.com/consensys/gnark-crypto@v0.14.0/internal/generator/iop/template/expressions.go.tmpl (about) 1 import ( 2 "math/bits" 3 "errors" 4 "github.com/consensys/gnark-crypto/internal/parallel" 5 "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" 6 ) 7 8 // Expression represents a multivariate polynomial. 9 type Expression func(i int, x ...fr.Element) fr.Element 10 11 // Evaluate evaluates f on each entry of x. The returned value is 12 // the vector of evaluations of e on x. 13 // The form of the result is form. 14 // if r is provided (not nil), it is used as the result vector, 15 // that is the memory space for the coefficients of the resulting polynomial. 16 // The Size field of the result is the same as the one of x[0]. 17 // The blindedSize field of the result is the same as Size. 18 // The Shift field of the result is 0. 19 func Evaluate(f Expression, r []fr.Element, form Form, x ...*Polynomial) (*Polynomial, error) { 20 if len(x) == 0 { 21 return nil, errors.New("need at lest one input") 22 } 23 24 // check that the sizes are consistent 25 n := x[0].coefficients.Len() 26 m := len(x) 27 for i := 1; i < m; i++ { 28 if n != x[i].coefficients.Len() { 29 return nil, ErrInconsistentSize 30 } 31 } 32 33 // check result len 34 if r == nil { 35 r = make([]fr.Element, n) 36 } else if len(r) != n { 37 return nil, ErrInconsistentSize 38 } 39 40 // result coefficients 41 idx := func(i int) int { 42 return i 43 } 44 if form.Layout != Regular { 45 nn := uint64(64 - bits.TrailingZeros(uint(n))) 46 idx = func(i int) int { 47 return int(bits.Reverse64(uint64(i)) >> nn) 48 } 49 } 50 51 parallel.Execute(n, func(start, end int) { 52 vx := make([]fr.Element, m) 53 for i := start; i < end; i++ { 54 for j := 0; j < m; j++ { 55 vx[j] = x[j].GetCoeff(i) 56 } 57 r[idx(i)] = f(i, vx...) 58 } 59 }) 60 61 res := NewPolynomial(&r, form) 62 res.size = x[0].size 63 res.blindedSize = x[0].size 64 res.shift = 0 65 66 return res, nil 67 }