github.com/consensys/gnark-crypto@v0.14.0/internal/generator/polynomial/template/multilin.test.go.tmpl (about) 1 import ( 2 "{{.FieldPackagePath}}" 3 "github.com/leanovate/gopter" 4 "github.com/leanovate/gopter/gen" 5 "github.com/leanovate/gopter/prop" 6 "github.com/stretchr/testify/assert" 7 "testing" 8 ) 9 10 //TODO: Property based tests? 11 func TestFoldBilinear(t *testing.T) { 12 13 for i := 0; i < 100; i++ { 14 15 // f = c₀ + c₁ X₁ + c₂ X₂ + c₃ X₁ X₂ 16 var coefficients [4]{{.ElementType}} 17 for i := 0; i < 4; i++ { 18 if _, err := coefficients[i].SetRandom(); err != nil { 19 t.Error(err) 20 } 21 } 22 23 var r {{.ElementType}} 24 if _, err := r.SetRandom(); err != nil { 25 t.Error(err) 26 } 27 28 // interpolate at {0,1}²: 29 m := make(MultiLin, 4) 30 m[0] = coefficients[0] 31 m[1].Add(&coefficients[0], &coefficients[2]) 32 m[2].Add(&coefficients[0], &coefficients[1]) 33 m[3]. 34 Add(&m[1], &coefficients[1]). 35 Add(&m[3], &coefficients[3]) 36 37 m.Fold(r) 38 39 // interpolate at {r}×{0,1}: 40 var expected0, expected1 {{.ElementType}} 41 expected0. 42 Mul(&r, &coefficients[1]). 43 Add(&expected0, &coefficients[0]) 44 45 expected1. 46 Mul(&r, &coefficients[3]). 47 Add(&expected1, &coefficients[2]). 48 Add(&expected0, &expected1) 49 50 if !m[0].Equal(&expected0) || !m[1].Equal(&expected1) { 51 t.Fail() 52 } 53 } 54 } 55 56 func TestPrecomputeLagrange(t *testing.T) { 57 58 testForDomainSize := func(domainSize uint8) bool { 59 polys := computeLagrangeBasis(domainSize) 60 61 for l := uint8(0); l < domainSize; l++ { 62 for i := uint8(0); i < domainSize; i++ { 63 var I {{.ElementType}} 64 I.SetUint64(uint64(i)) 65 y := polys[l].Eval(&I) 66 67 if i == l && !y.IsOne() || i != l && !y.IsZero() { 68 t.Errorf("domainSize = %d: p_%d(%d) = %s", domainSize, l, i, y.Text(10)) 69 return false 70 } 71 } 72 } 73 return true 74 } 75 76 t.Parallel() 77 parameters := gopter.DefaultTestParameters() 78 79 parameters.MinSuccessfulTests = int(maxLagrangeDomainSize) 80 81 properties := gopter.NewProperties(parameters) 82 83 properties.Property("l'th lagrange polynomials must evaluate to 1 on l and 0 on other values in the domain", prop.ForAll( 84 testForDomainSize, 85 gen.UInt8Range(2, maxLagrangeDomainSize), 86 )) 87 88 properties.TestingRun(t, gopter.ConsoleReporter(false)) 89 } 90 91 // TODO: Benchmark folding? Algorithms is pretty straightforward; unless we want to measure how well memory management is working 92 93 func TestFoldedEqTable(t *testing.T) { 94 q := make([]{{.ElementType}}, 2) 95 q[0].SetInt64(2) 96 q[1].SetInt64(3) 97 98 m := make(MultiLin, 4) 99 m[0].SetOne() 100 m.Eq(q) 101 102 eq := make([]{{.ElementType}}, 4) 103 p := make([]{{.ElementType}}, 2) 104 105 var one {{.ElementType}} 106 one.SetOne() 107 108 for p0 := 0; p0 < 2; p0++ { 109 p[1].SetZero() 110 for p1 := 0; p1 < 2; p1++ { 111 eq[p0*2+p1] = EvalEq(q, p) 112 p[1].Add(&p[1], &one) 113 } 114 p[0].Add(&p[0], &one) 115 } 116 117 for i := 0; i < 4; i++ { 118 assert.Equal(t, eq[i], m[i], "folded table disagrees with EqEval", i) 119 } 120 121 }