@@ -251,9 +251,9 @@ def quadratic_non_residue(self):
251251 r"""
252252 Returns a random non square element of the finite field
253253
254- OUTPUTS :
255- - a non-square element of the finite field; raises an error if
256- the finite field is of even order
254+ OUTPUT :
255+ A non-square element of the finite field; raises an error if
256+ the finite field is of even order.
257257
258258 EXAMPLES::
259259
@@ -266,27 +266,25 @@ def quadratic_non_residue(self):
266266 sage: k.quadratic_non_residue()
267267 Traceback (most recent call last):
268268 ...
269- ValueError: There are no non-squares in finite fields of even order
269+ ValueError: there are no non-squares in finite fields of even order
270270 """
271271 # if the order is an even power of two
272272 # then every element is a square
273273 if self .characteristic () == 2 :
274- raise ValueError ("There are no non-squares in finite fields of even order" )
274+ raise ValueError ("there are no non-squares in finite fields of even order" )
275275 # uniformly randomly select elements for a non-square
276276 # with probability 1/2 for a non-square
277- element = self .random_element ()
278- while element .is_square ():
279- element = self .random_element ()
280- return element
277+ for element in self :
278+ if not element .is_square ():
279+ return element
281280
282281 class ElementMethods :
283282 def is_square (self ) -> bool :
284283 r"""
285284 Tests if the element is a square or has
286- a square root element
285+ a square root element.
287286
288- OUTPUT:
289- - ``True`` if the element is a square ``False`` if not
287+ OUTPUT: ``True`` if the element is a square ``False`` if not
290288
291289 EXAMPLES::
292290
@@ -312,11 +310,10 @@ def is_square(self) -> bool:
312310 def _tonelli (self ):
313311 r"""
314312 Returns a square root of the element if it exists
315- using Tonelli's algorithm
316-
317- OUTPUT:
313+ using Tonelli's algorithm, only works for finite fields
314+ of odd characteristic.
318315
319- - A square root of the element; raises an error
316+ OUTPUT: A square root of the element; raises an error
320317 if the element is not a square
321318
322319 EXAMPLES::
@@ -329,11 +326,11 @@ def _tonelli(self):
329326 sage: k.quadratic_non_residue()._tonelli()
330327 Traceback (most recent call last):
331328 ...
332- ValueError: Element is not a square
329+ ValueError: element is not a square
333330 """
334331 q = self .parent ().cardinality ()
335332 if not self .is_square ():
336- raise ValueError ("Element is not a square" )
333+ raise ValueError ("element is not a square" )
337334 g = self .parent ().quadratic_non_residue ()
338335 even_exp , odd_order = (q - ZZ .one ()).val_unit (2 )
339336 e = 0
@@ -351,11 +348,10 @@ def _cipolla(self):
351348 r"""
352349 Returns a square root of the element if it exists
353350 using Cipolla's algorithm, more suited if order - 1
354- is highly divisible by 2
355-
356- OUTPUT:
351+ is highly divisible by 2. Only works for finite fields
352+ of odd characteristic.
357353
358- - A square root of the element; raises an error
354+ OUTPUT: A square root of the element; raises an error
359355 if the element is not a square
360356
361357 EXAMPLES::
@@ -368,12 +364,12 @@ def _cipolla(self):
368364 sage: k.quadratic_non_residue()._cipolla()
369365 Traceback (most recent call last):
370366 ...
371- ValueError: Element is not a square
367+ ValueError: element is not a square
372368 """
373369 parent = self .parent ()
374370 q = parent .cardinality ()
375371 if not self .is_square ():
376- raise ValueError ("Element is not a square" )
372+ raise ValueError ("element is not a square" )
377373 t = parent .random_element ()
378374 root = t ** 2 - 4 * self
379375 while root .is_square ():
@@ -387,7 +383,7 @@ def _cipolla(self):
387383
388384 def sqrt (self , all : bool = False , algorithm : str = 'tonelli' ):
389385 r"""
390- Returns the square root of the element if it exists
386+ Returns the square root of the element if it exists.
391387
392388 INPUT:
393389
@@ -430,18 +426,30 @@ def sqrt(self, all: bool = False, algorithm: str = 'tonelli'):
430426 sage: k.quadratic_non_residue().sqrt()
431427 Traceback (most recent call last):
432428 ...
433- ValueError: Element is not a square
429+ ValueError: element is not a square
434430 sage: k.quadratic_non_residue().sqrt(all=True)
435431 ()
436432
433+ Here is an example where changing the algorithm results
434+ in a faster square root::
435+
436+ sage: p = 141 * 2^141 + 1
437+ sage: S.<x> = GF(p)[]
438+ sage: f = S.irreducible_element(2)
439+ sage: k.<y> = S.quotient_ring(f)
440+ sage: k in Fields()
441+ True
442+ sage: k(2).sqrt(algorithm="cipolla")^2 == k(2)
443+ True
444+
437445 ALGORITHM:
438446
439447 The algorithms used come from chapter 7 of [BS1996]_.
440448 Let `q = p^n` be the order of the finite field, let `a` be the finite field element
441449 that we wish to find the square root of.
442450
443- - If `p = 2` then `a` is always a square, and the square root of `\sqrt{a} = a^{( q / 2) }`.
444- - If `q \equiv 3 \pmod{4}` then if `a` is a square `\sqrt{a} = {a^(( q+1) / 4) }`
451+ - If `p = 2` then `a` is always a square, and the square root of `\sqrt{a} = a^{q / 2}`.
452+ - If `q \equiv 3 \pmod{4}` then if `a` is a square `\sqrt{a} = a^{\frac{ q+1}{4} }`
445453 - For all other cases we use the algorithm given by the ``algorithm`` parameter.
446454 """
447455 cardinality = self .parent ().order ()
@@ -457,7 +465,7 @@ def sqrt(self, all: bool = False, algorithm: str = 'tonelli'):
457465 if all :
458466 return ()
459467 else :
460- raise ValueError ("Element is not a square" )
468+ raise ValueError ("element is not a square" )
461469 if cardinality % 4 == 3 :
462470 square_root = self ** ((cardinality + 1 )// 4 )
463471 elif algorithm == 'tonelli' :
0 commit comments