github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-377/fr/polynomial/polynomial.go (about) 1 // Copyright 2020 Consensys Software Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Code generated by consensys/gnark-crypto DO NOT EDIT 16 17 package polynomial 18 19 import ( 20 "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" 21 "github.com/consensys/gnark-crypto/utils" 22 "strconv" 23 "strings" 24 ) 25 26 // Polynomial represented by coefficients in the field. 27 type Polynomial []fr.Element 28 29 // Degree returns the degree of the polynomial, which is the length of Data. 30 func (p *Polynomial) Degree() uint64 { 31 return uint64(len(*p) - 1) 32 } 33 34 // Eval evaluates p at v 35 // returns a fr.Element 36 func (p *Polynomial) Eval(v *fr.Element) fr.Element { 37 38 res := (*p)[len(*p)-1] 39 for i := len(*p) - 2; i >= 0; i-- { 40 res.Mul(&res, v) 41 res.Add(&res, &(*p)[i]) 42 } 43 44 return res 45 } 46 47 // Clone returns a copy of the polynomial 48 func (p *Polynomial) Clone() Polynomial { 49 _p := make(Polynomial, len(*p)) 50 copy(_p, *p) 51 return _p 52 } 53 54 // Set to another polynomial 55 func (p *Polynomial) Set(p1 Polynomial) { 56 if len(*p) != len(p1) { 57 *p = p1.Clone() 58 return 59 } 60 61 for i := 0; i < len(p1); i++ { 62 (*p)[i].Set(&p1[i]) 63 } 64 } 65 66 // AddConstantInPlace adds a constant to the polynomial, modifying p 67 func (p *Polynomial) AddConstantInPlace(c *fr.Element) { 68 for i := 0; i < len(*p); i++ { 69 (*p)[i].Add(&(*p)[i], c) 70 } 71 } 72 73 // SubConstantInPlace subs a constant to the polynomial, modifying p 74 func (p *Polynomial) SubConstantInPlace(c *fr.Element) { 75 for i := 0; i < len(*p); i++ { 76 (*p)[i].Sub(&(*p)[i], c) 77 } 78 } 79 80 // ScaleInPlace multiplies p by v, modifying p 81 func (p *Polynomial) ScaleInPlace(c *fr.Element) { 82 for i := 0; i < len(*p); i++ { 83 (*p)[i].Mul(&(*p)[i], c) 84 } 85 } 86 87 // Scale multiplies p0 by v, storing the result in p 88 func (p *Polynomial) Scale(c *fr.Element, p0 Polynomial) { 89 if len(*p) != len(p0) { 90 *p = make(Polynomial, len(p0)) 91 } 92 for i := 0; i < len(p0); i++ { 93 (*p)[i].Mul(c, &p0[i]) 94 } 95 } 96 97 // Add adds p1 to p2 98 // This function allocates a new slice unless p == p1 or p == p2 99 func (p *Polynomial) Add(p1, p2 Polynomial) *Polynomial { 100 101 bigger := p1 102 smaller := p2 103 if len(bigger) < len(smaller) { 104 bigger, smaller = smaller, bigger 105 } 106 107 if len(*p) == len(bigger) && (&(*p)[0] == &bigger[0]) { 108 for i := 0; i < len(smaller); i++ { 109 (*p)[i].Add(&(*p)[i], &smaller[i]) 110 } 111 return p 112 } 113 114 if len(*p) == len(smaller) && (&(*p)[0] == &smaller[0]) { 115 for i := 0; i < len(smaller); i++ { 116 (*p)[i].Add(&(*p)[i], &bigger[i]) 117 } 118 *p = append(*p, bigger[len(smaller):]...) 119 return p 120 } 121 122 res := make(Polynomial, len(bigger)) 123 copy(res, bigger) 124 for i := 0; i < len(smaller); i++ { 125 res[i].Add(&res[i], &smaller[i]) 126 } 127 *p = res 128 return p 129 } 130 131 // Sub subtracts p2 from p1 132 // TODO make interface more consistent with Add 133 func (p *Polynomial) Sub(p1, p2 Polynomial) *Polynomial { 134 if len(p1) != len(p2) || len(p2) != len(*p) { 135 return nil 136 } 137 for i := 0; i < len(*p); i++ { 138 (*p)[i].Sub(&p1[i], &p2[i]) 139 } 140 return p 141 } 142 143 // Equal checks equality between two polynomials 144 func (p *Polynomial) Equal(p1 Polynomial) bool { 145 if (*p == nil) != (p1 == nil) { 146 return false 147 } 148 149 if len(*p) != len(p1) { 150 return false 151 } 152 153 for i := range p1 { 154 if !(*p)[i].Equal(&p1[i]) { 155 return false 156 } 157 } 158 159 return true 160 } 161 162 func (p Polynomial) SetZero() { 163 for i := 0; i < len(p); i++ { 164 p[i].SetZero() 165 } 166 } 167 168 func (p Polynomial) Text(base int) string { 169 170 var builder strings.Builder 171 172 first := true 173 for d := len(p) - 1; d >= 0; d-- { 174 if p[d].IsZero() { 175 continue 176 } 177 178 pD := p[d] 179 pDText := pD.Text(base) 180 181 initialLen := builder.Len() 182 183 if pDText[0] == '-' { 184 pDText = pDText[1:] 185 if first { 186 builder.WriteString("-") 187 } else { 188 builder.WriteString(" - ") 189 } 190 } else if !first { 191 builder.WriteString(" + ") 192 } 193 194 first = false 195 196 if !pD.IsOne() || d == 0 { 197 builder.WriteString(pDText) 198 } 199 200 if builder.Len()-initialLen > 10 { 201 builder.WriteString("×") 202 } 203 204 if d != 0 { 205 builder.WriteString("X") 206 } 207 if d > 1 { 208 builder.WriteString( 209 utils.ToSuperscript(strconv.Itoa(d)), 210 ) 211 } 212 213 } 214 215 if first { 216 return "0" 217 } 218 219 return builder.String() 220 }