github.com/consensys/gnark-crypto@v0.14.0/internal/generator/polynomial/template/polynomial.test.go.tmpl (about)

     1  import (
     2  	"math/big"
     3  	"testing"
     4  	"github.com/stretchr/testify/assert"
     5  	"{{.FieldPackagePath}}"
     6  )
     7  
     8  func TestPolynomialEval(t *testing.T) {
     9  
    10  	// build polynomial
    11  	f := make(Polynomial, 20)
    12  	for i := 0; i < 20; i++ {
    13  		f[i].SetOne()
    14  	}
    15  
    16  	// random value
    17  	var point {{.ElementType}}
    18  	point.SetRandom()
    19  
    20  	// compute manually f(val)
    21  	var expectedEval, one, den {{.ElementType}}
    22  	var expo big.Int
    23  	one.SetOne()
    24  	expo.SetUint64(20)
    25  	expectedEval.Exp(point, &expo).
    26  		Sub(&expectedEval, &one)
    27  	den.Sub(&point, &one)
    28  	expectedEval.Div(&expectedEval, &den)
    29  
    30  	// compute purported evaluation
    31  	purportedEval := f.Eval(&point)
    32  
    33  	// check
    34  	if !purportedEval.Equal(&expectedEval) {
    35  		t.Fatal("polynomial evaluation failed")
    36  	}
    37  }
    38  
    39  func TestPolynomialAddConstantInPlace(t *testing.T) {
    40  
    41  	// build polynomial
    42  	f := make(Polynomial, 20)
    43  	for i := 0; i < 20; i++ {
    44  		f[i].SetOne()
    45  	}
    46  
    47  	// constant to add
    48  	var c {{.ElementType}}
    49  	c.SetRandom()
    50  
    51  	// add constant
    52  	f.AddConstantInPlace(&c)
    53  
    54  	// check
    55  	var expectedCoeffs, one {{.ElementType}}
    56  	one.SetOne()
    57  	expectedCoeffs.Add(&one, &c)
    58  	for i := 0; i < 20; i++ {
    59  		if !f[i].Equal(&expectedCoeffs) {
    60  			t.Fatal("AddConstantInPlace failed")
    61  		}
    62  	}
    63  }
    64  
    65  func TestPolynomialSubConstantInPlace(t *testing.T) {
    66  
    67  	// build polynomial
    68  	f := make(Polynomial, 20)
    69  	for i := 0; i < 20; i++ {
    70  		f[i].SetOne()
    71  	}
    72  
    73  	// constant to sub
    74  	var c {{.ElementType}}
    75  	c.SetRandom()
    76  
    77  	// sub constant
    78  	f.SubConstantInPlace(&c)
    79  
    80  	// check
    81  	var expectedCoeffs, one {{.ElementType}}
    82  	one.SetOne()
    83  	expectedCoeffs.Sub(&one, &c)
    84  	for i := 0; i < 20; i++ {
    85  		if !f[i].Equal(&expectedCoeffs) {
    86  			t.Fatal("SubConstantInPlace failed")
    87  		}
    88  	}
    89  }
    90  
    91  func TestPolynomialScaleInPlace(t *testing.T) {
    92  
    93  	// build polynomial
    94  	f := make(Polynomial, 20)
    95  	for i := 0; i < 20; i++ {
    96  		f[i].SetOne()
    97  	}
    98  
    99  	// constant to scale by
   100  	var c {{.ElementType}}
   101  	c.SetRandom()
   102  
   103  	// scale by constant
   104  	f.ScaleInPlace(&c)
   105  
   106  	// check
   107  	for i := 0; i < 20; i++ {
   108  		if !f[i].Equal(&c) {
   109  			t.Fatal("ScaleInPlace failed")
   110  		}
   111  	}
   112  
   113  }
   114  
   115  func TestPolynomialAdd(t *testing.T) {
   116  
   117  	// build unbalanced polynomials
   118  	f1 := make(Polynomial, 20)
   119  	f1Backup := make(Polynomial, 20)
   120  	for i := 0; i < 20; i++ {
   121  		f1[i].SetOne()
   122  		f1Backup[i].SetOne()
   123  	}
   124  	f2 := make(Polynomial, 10)
   125  	f2Backup := make(Polynomial, 10)
   126  	for i := 0; i < 10; i++ {
   127  		f2[i].SetOne()
   128  		f2Backup[i].SetOne()
   129  	}
   130  
   131  	// expected result
   132  	var one, two {{.ElementType}}
   133  	one.SetOne()
   134  	two.Double(&one)
   135  	expectedSum := make(Polynomial, 20)
   136  	for i := 0; i < 10; i++ {
   137  		expectedSum[i].Set(&two)
   138  	}
   139  	for i := 10; i < 20; i++ {
   140  		expectedSum[i].Set(&one)
   141  	}
   142  
   143  	// caller is empty
   144  	var g Polynomial
   145  	g.Add(f1, f2)
   146  	if !g.Equal(expectedSum) {
   147  		t.Fatal("add polynomials fails")
   148  	}
   149  	if !f1.Equal(f1Backup) {
   150  		t.Fatal("side effect, f1 should not have been modified")
   151  	}
   152  	if !f2.Equal(f2Backup) {
   153  		t.Fatal("side effect, f2 should not have been modified")
   154  	}
   155  
   156  	// all operands are distinct
   157  	_f1 := f1.Clone()
   158  	_f1.Add(f1, f2)
   159  	if !_f1.Equal(expectedSum) {
   160  		t.Fatal("add polynomials fails")
   161  	}
   162  	if !f1.Equal(f1Backup) {
   163  		t.Fatal("side effect, f1 should not have been modified")
   164  	}
   165  	if !f2.Equal(f2Backup) {
   166  		t.Fatal("side effect, f2 should not have been modified")
   167  	}
   168  
   169  	// first operand = caller
   170  	_f1 = f1.Clone()
   171  	_f2 := f2.Clone()
   172  	_f1.Add(_f1, _f2)
   173  	if !_f1.Equal(expectedSum) {
   174  		t.Fatal("add polynomials fails")
   175  	}
   176  	if !_f2.Equal(f2Backup) {
   177  		t.Fatal("side effect, _f2 should not have been modified")
   178  	}
   179  
   180  	// second operand = caller
   181  	_f1 = f1.Clone()
   182  	_f2 = f2.Clone()
   183  	_f1.Add(_f2, _f1)
   184  	if !_f1.Equal(expectedSum) {
   185  		t.Fatal("add polynomials fails")
   186  	}
   187  	if !_f2.Equal(f2Backup) {
   188  		t.Fatal("side effect, _f2 should not have been modified")
   189  	}
   190  }
   191  
   192  func TestPolynomialText(t *testing.T) {
   193  	var one, negTwo {{.ElementType}}
   194  	one.SetOne()
   195  	negTwo.SetInt64(-2)
   196  
   197  	p := Polynomial{one, negTwo, one}
   198  
   199  	assert.Equal(t, "X² - 2X + 1", p.Text(10))
   200  }