# HG changeset patch
# User JeanPierre Flori
# Date 1360334827 3600
# Node ID 0aaa71dda8af2bb4d05df41fe6df0fe4aa2eef10
# Parent 4cbd00666457bacdfc6afaec73bad96ad83d2e05
#8335: Doc fixes
diff git a/sage/categories/pushout.py b/sage/categories/pushout.py
 a/sage/categories/pushout.py
+++ b/sage/categories/pushout.py
@@ 2291,7 +2291,7 @@
...
TypeError: Could not find a mapping of the passed element to this ring.
"""
 rank = 7
+ rank = 4.5
def __init__(self, I, names=None, as_field=False):
"""
@@ 2348,23 +2348,27 @@
Note that the ``quo()`` method of a field used to return the
integer zero. That strange behaviour was removed in trac
 ticket #9138. It now returns a trivial quotient ring when
 applied to a field::
+ ticket :trac:`9138` to return a trivial quotient ring when
+ applied to a field. Note that since :trac:`8335` applying a
+ ``QuotientFunctor`` with arguments a field and a nontrivial ideal
+ will raise a ``CoercionException``::
sage: F = ZZ.quo([5]*ZZ).construction()[0]
 sage: F(QQ) is Integers(1)
 True
+ sage: F(QQ)
+ Traceback (most recent call last):
+ ...
+ CoercionException: Trivial quotient ring.
sage: QQ.quo(5)
Quotient of Rational Field by the ideal (1)

"""
I = self.I
from sage.all import QQ
if not I.is_zero():
from sage.categories.fields import Fields
if R in Fields():
 from sage.all import Integers
 return Integers(1)
+ raise CoercionException, "Trivial quotient ring."
+ #from sage.all import Integers
+ #return Integers(1)
if I.ring() != R:
if I.ring().has_coerce_map_from(R):
R = I.ring()
@@ 2493,7 +2497,7 @@
"""
rank = 3
 def __init__(self, polys, names, embeddings, cyclotomic=None, prefix=None):
+ def __init__(self, polys, names, embeddings, cyclotomic=None, conway=None, prefix=None):
"""
INPUT:
@@ 2508,6 +2512,9 @@
 ``cyclotomic``: optional integer. If it is provided,
application of the functor to the rational field yields
a cyclotomic field, rather than just a number field.
+  ``conway``: optional integer. If it is provided,
+ application of the functor to finite fields yields
+ pseudoConway extensions of the given degree.
 ``prefix``: optional string. If it is provided, it will
allow application of this functor to some finite fields to
function without providing a variable name
@@ 2575,6 +2582,8 @@
self.names = list(names)
self.embeddings = list(embeddings)
self.cyclotomic = int(cyclotomic) if cyclotomic is not None else None
+ from sage.rings.integer import Integer
+ self.conway = Integer(conway) if conway is not None else None
self.prefix = prefix
def _apply_functor(self, R):
@@ 2599,9 +2608,12 @@
return CyclotomicField(self.cyclotomic)
if R==ZZ:
return CyclotomicField(self.cyclotomic).maximal_order()
 if len(self.polys) == 1:
+ if len(self.polys) == 1 or self.conway is not None:
if is_FiniteField(R):
 return R.extension(self.polys[0], self.names[0], embedding=self.embeddings[0], prefix=self.prefix)
+ if self.conway is not None:
+ return R.extension(self.conway, None, embedding=self.embeddings[0], prefix=self.prefix)
+ else:
+ return R.extension(self.polys[0], self.names[0], embedding=self.embeddings[0], prefix=self.prefix)
else:
return R.extension(self.polys[0], self.names[0], embedding=self.embeddings[0])
return R.extension(self.polys, self.names, embedding=self.embeddings)
@@ 2643,7 +2655,7 @@
of the two embeddings is returned, provided that
it is a number field.
 If these two extensions are defined by Conway polynomials over finite fields
 (indicated by the fact that their ``poly`` fields are just integers),
+ (indicated by the fact that their ``conway`` fields are integers and not None),
merges them into a single extension of degree the product of the two degrees.
 Otherwise, None is returned.
@@ 2713,11 +2725,11 @@
# return other
# ... or we may use the given embeddings
from sage.rings.integer import Integer
 # finite fields use an integer to encode the pseudoConway extension that allows pushouts
 if isinstance(self.polys[0], Integer) and isinstance(other.polys[0], Integer) and self.prefix is not None and self.prefix == other.prefix:
+ # finite fields use an Integer to encode the pseudoConway extension that allows pushouts
+ if isinstance(self.conway, Integer) and isinstance(other.conway, Integer) and self.prefix is not None and self.prefix == other.prefix:
if self.embeddings != [None] or other.embeddings != [None]:
raise NotImplementedError
 return AlgebraicExtensionFunctor([self.polys[0]*other.polys[0]],[None],[None],prefix=self.prefix)
+ return AlgebraicExtensionFunctor(self.polys+other.polys,self.names+other.names,self.embeddings+other.embeddings,conway=self.conway*other.conway,prefix=self.prefix)
if self.embeddings!=[None] and other.embeddings!=[None]:
from sage.all import QQ
KS = self(QQ)
@@ 2789,7 +2801,7 @@
"""
if len(self.polys)==1:
return [self]
 return [AlgebraicExtensionFunctor([self.polys[i]], [self.names[i]], [self.embeddings[i]]) for i in range(len(self.polys))]
+ return [AlgebraicExtensionFunctor([self.polys[i]], [self.names[i]], [self.embeddings[i]], conway=[self.polys[i].degree()] if self.conway is not None else None, prefix=self.prefix) for i in range(len(self.polys))]
class AlgebraicClosureFunctor(ConstructionFunctor):
"""
@@ 3114,13 +3126,13 @@
S_tower = construction_tower(S)
Rs = [c[1] for c in R_tower]
Ss = [c[1] for c in S_tower]

+
if R in Ss:
return S
elif S in Rs:
return R
 if R_tower[1][1] in Ss:
+ if Rs[1] in Ss:
Rs, Ss = Ss, Rs
R_tower, S_tower = S_tower, R_tower
diff git a/sage/interfaces/singular.py b/sage/interfaces/singular.py
 a/sage/interfaces/singular.py
+++ b/sage/interfaces/singular.py
@@ 1430,7 +1430,7 @@
sage: singular.eval('minpoly = 1+z+z2+z3+z4')
'minpoly = 1+z+z2+z3+z4;'
sage: singular('r3').sage_global_ring()
 Multivariate Polynomial Ring in a, b, c over Univariate Quotient Polynomial Ring in z over Finite Field of size 3 with modulus z^4 + z^3 + z^2 + z + 1
+ Multivariate Polynomial Ring in a, b, c over Finite Field in z of size 3^4
Real and complex fields in both Singular and Sage are defined with a precision.
The precision in Singular is given in terms of digits, but in Sage it is given
@@ 1517,7 +1517,7 @@
singular.eval('short=%s'%is_short)
else:
minpoly = ZZ[charstr[1]](minpoly)
 BR = br.extension(minpoly)
+ BR = br.extension(minpoly,name=charstr[1])
else:
BR = br
@@ 1580,7 +1580,7 @@
'minpoly = 1+z+z2+z3+z4;'
sage: p = singular('z^4*a^3+z^2*a*b*c')
sage: p.sage_poly()
 (2*z^3 + 2*z^2 + 2*z + 2)*a^3 + z^2*a*b*c
+ (z^3  z^2  z  1)*a^3 + (z^2)*a*b*c
sage: singular('z^4')
(z3z2z1)
diff git a/sage/matrix/action.pyx b/sage/matrix/action.pyx
 a/sage/matrix/action.pyx
+++ b/sage/matrix/action.pyx
@@ 5,7 +5,7 @@
.. WARNING::
The class :class:`MatrixMulAction` and its descendants extends the class
 :class:`Action`. As a cosnequence objects from these classes only keep weak
+ :class:`Action`. As a consequence objects from these classes only keep weak
references to the underlying sets which are acted upon. This decision was
made in :trac:`715` in order to allow garbage collection within the coercion
framework, where actions are mainly used, and avoid memory leaks.
diff git a/sage/rings/finite_rings/constructor.py b/sage/rings/finite_rings/constructor.py
 a/sage/rings/finite_rings/constructor.py
+++ b/sage/rings/finite_rings/constructor.py
@@ 6,7 +6,6 @@
Sage for several sizes of primes `p`. These implementations
are

 ``sage.rings.finite_rings.integer_mod.IntegerMod_int``,
 ``sage.rings.finite_rings.integer_mod.IntegerMod_int64``, and
@@ 179,59 +178,57 @@
Return the globally unique finite field of given order with
generator labeled by the given name and possibly with given
modulus.

+
INPUT:


  ``order``  int

  ``name``  string; must be specified unless
  ``order`` is prime
  ``modulus`` is 'conway', in which case a name is generated
+
+  ``order``  int
+
+  ``name``  string; must be specified unless
+
+  ``order`` is prime
+  ``modulus`` is 'conway', in which case a name is generated
from the degree and the ``prefix`` string.

  ``modulus``  (optional) either a defining polynomial for the
 field, i.e., generator of the field will be a root of this
 polynomial; or a string:
  'conway': force the use of a pseudoConway polynomial.
 If a conway polynomial is found in the database, that is used.
 Otherwise, a polynomial is used with the same algebraic properties
 but without the lexicographic constraint implying uniqueness.
  'random': use a random irreducible polynomial;
  'default': a Conway polynomial is used if in the database. Otherwise
 a sparse polynomial is used for binary fields and a
 random polynomial is used for other characteristics.
  'first_lexicographic': uses the first irreducible polynomial.
+  ``modulus``  (optional) either a defining polynomial for the
+ field, i.e., generator of the field will be a root of this
+ polynomial; or a string:
 Other options might be available depending on the
 implementation.

  ``elem_cache``  cache all elements to avoid
 creation time (default: order < 500)

  ``check_irreducible``  verify that the polynomial
 modulus is irreducible
+  ``'conway'``: force the use of a pseudoConway polynomial.
+ If a conway polynomial is found in the database, that is used.
+ Otherwise, a polynomial is used with the same algebraic properties
+ but without the lexicographic constraint implying uniqueness.
+  ``'random'``: use a random irreducible polynomial.
+  ``'first_lexicographic'``: uses the first irreducible polynomial.
+  ``'default'``: a Conway polynomial is used if in the database.
+ Otherwise a sparse polynomial is used for binary fields and a
+ random polynomial is used for other characteristics.
+  Other options might be available depending on the implementation.
  ``prefix`` (default: 'z')  a string used to generate names
+  ``elem_cache``  cache all elements to avoid
+ creation time (default: order < 500)
+
+  ``check_irreducible``  verify that the polynomial
+ modulus is irreducible
+
+  ``prefix`` (default: ``'z'``)  a string used to generate names
for subfields and pushouts of this field (mainly for use with
pseudoConway polynomials).
  ``proof``  bool (default: True); if True use provable
+  ``proof``  bool (default: ``True``); if ``True`` use provable
primality test; otherwise only use pseudoprimality test.

  ``args``  additional parameters passed to finite
 field implementations

  ``kwds``  additional keyword parameters passed to
 finite field implementations


 ALIAS: You can also use GF instead of FiniteField  they are
 identical.
+
+  ``args``  additional parameters passed to finite
+ field implementations
+
+  ``kwds``  additional keyword parameters passed to
+ finite field implementations
+
+ ALIAS:
+
+ You can also use ``GF`` instead of ``FiniteField``  they are identical.
EXAMPLES::

+
sage: k. = FiniteField(9); k
Finite Field in a of size 3^2
sage: parent(a)
@@ 240,37 +237,40 @@
y^2 + 2*y + 2
sage: L = GF(27); L
Finite Field in z3 of size 3^3

+
We illustrate the proof flag. The following example would hang
 for a very long time if we didn't use proof=False. (NOTE: Magma
 only supports proof=False for making finite fields, so falsely
 appears to be faster than Sage  see Trac 10975.)::
+ for a very long time if we didn't use ``proof=False``.
+
+ .. NOTE::
+
+ Magma only supports ``proof=False`` for making finite fields,
+ so falsely appears to be faster than Sage  see :trac:10975.
+
+ ::
sage: k = FiniteField(10^1000 + 453, proof=False)
sage: k = FiniteField((10^1000 + 453)^2, 'a', proof=False) # long time  about 5 seconds
::

+
sage: F. = GF(5)[]
sage: K. = GF(5**5, name='a', modulus=x^5  x +1 )
sage: f = K.modulus(); f
x^5 + 4*x + 1
sage: type(f)

+
The modulus must be irreducible::

+
sage: K. = GF(5**5, name='a', modulus=x^5  x )
Traceback (most recent call last):
...
ValueError: finite field modulus must be irreducible but it is not.

+
You can't accidentally fool the constructor into thinking the modulus
is irreducible when it isn't mod p, since it actually tests
 irreducibility modulo p. Also, the modulus has to be of the right degree.

 ::

+ irreducibility modulo p. Also, the modulus has to be of the right degree::
+
sage: F. = QQ[]
sage: factor(x^5 + 2)
x^5 + 2
@@ 283,14 +283,12 @@
...
ValueError: The degree of the modulus does not correspond to the
cardinality of the field.

+
If you wish to live dangerously, you can tell the constructor not
to test irreducibility using check_irreducible=False, but this can
easily lead to crashes and hangs  so do not do it unless you know
 that the modulus really is irreducible and has the correct degree!

 ::

+ that the modulus really is irreducible and has the correct degree!::
+
sage: F. = GF(5)[]
sage: K. = GF(5**2, name='a', modulus=x^2 + 2, check_irreducible=False)
@@ 301,7 +299,7 @@
[0, a, 1, 2, 1, 2, 1, 2, 1]
The order of a finite field must be a prime power::

+
sage: GF(1)
Traceback (most recent call last):
...
@@ 310,21 +308,19 @@
Traceback (most recent call last):
...
ValueError: the order of a finite field must be a prime power.

+
Finite fields with explicit random modulus are not cached::

+
sage: k. = GF(5**10, modulus='random')
sage: n. = GF(5**10, modulus='random')
sage: n is k
False
sage: GF(5**10, 'a') is GF(5**10, 'a')
True

+
We check that various ways of creating the same finite field yield
 the same object, which is cached.

 ::

+ the same object, which is cached::
+
sage: K = GF(7, 'a')
sage: L = GF(7, 'b')
sage: K is L
@@ 337,23 +333,19 @@
sage: M = GF(4,'a', K.modulus().change_variable_name('y'))
sage: K is M
True

 You may print finite field elements as integers. This
 currently only works if the order of field is `<2^{16}`,
 though.

 ::

+
+ You may print finite field elements as integers. This currently only works
+ if the order of field is `< 2^{16}`, though::
+
sage: k. = GF(2^8, repr='int')
sage: a
2

"""
def create_key_and_extra_args(self, order, name=None, modulus=None, names=None,
impl=None, prefix='z', proof=None, **kwds):
"""
EXAMPLES::

+
sage: GF.create_key_and_extra_args(9, 'a')
((9, ('a',), 'conwayz', None, '{}', 3, 2, True), {})
sage: GF.create_key_and_extra_args(9, 'a', foo='value')
@@ 403,11 +395,15 @@
if isinstance(modulus, (list, tuple)):
modulus = FiniteField(p)['x'](modulus)
 # some classes use 'random' as the modulus to
 # generate a random modulus, but we don't want
 # to cache it
elif sage.rings.polynomial.polynomial_element.is_Polynomial(modulus):
+ # some classes use 'random' as the modulus to
+ # generate a random modulus, but we don't want
+ # to cache it
modulus = modulus.change_variable_name('x')
+ # We might need the following for compatibility with
+ # the extension method of CommutativeRing class
+ if name is None:
+ name = str(modulus.parent().gen(0))
elif not isinstance(modulus, str):
raise ValueError("Modulus parameter not understood.")
else: # Neither a prime, nor a prime power
@@ 551,48 +547,43 @@
return isinstance(x, FiniteField_prime_modn) or \
(isinstance(x, FiniteField_generic) and x.degree() == 1)

##################################################################

+
+
def conway_polynomial(p, n):
r"""
 Return the Conway polynomial of degree n over GF(p), which is
+ Return the Conway polynomial of degree ``n`` over `F_p`, which is
loaded from a table.

+
If the requested polynomial is not known, this function raises a
 RuntimeError exception.

+ ``RuntimeError`` exception.
+
INPUT:


  ``p``  int

  ``n``  int


+
+  ``p``  int
+
+  ``n``  int
+
OUTPUT:


  ``Polynomial``  a polynomial over the prime finite
 field GF(p).


 .. note::
 The first time this function is called a table is read from
 disk, which takes a fraction of a second. Subsequent calls do
 not require reloading the table.

+  ``Polynomial``  a polynomial over the prime finite
+ field GF(p).
+
+ .. NOTE::
+
+ The first time this function is called a table is read from disk,
+ which takes a fraction of a second.
+ Subsequent calls do not require reloading the table.
+
See also the ``ConwayPolynomials()`` object, which is a
 table of Conway polynomials. For example, if
 ``c=ConwayPolynomials()``, then
+ table of Conway polynomials.
+ For example, if ``c=ConwayPolynomials()``, then
``c.primes()`` is a list of all primes for which the
polynomials are known, and for a given prime `p`,
``c.degree(p)`` is a list of all degrees for which the
Conway polynomials are known.

+
EXAMPLES::

+
sage: conway_polynomial(2,5)
x^5 + x^2 + 1
sage: conway_polynomial(101,5)
@@ 613,12 +604,12 @@
r"""
Return True if the Conway polynomial over `F_p` of degree
`n` is in the database and False otherwise.

+
If the Conway polynomial is in the database, to obtain it use the
command ``conway_polynomial(p,n)``.

+
EXAMPLES::

+
sage: exists_conway_polynomial(2,3)
True
sage: exists_conway_polynomial(2,1)
@@ 634,17 +625,32 @@
class PseudoConwayPolyTree(SageObject):
"""
 An object holding references to pseudoConway polynomials for divisors of the given degree, so that they aren't garbage collected.
+ An object holding references to pseudoConway polynomials for divisors
+ of the given degree, so that they aren't garbage collected.
"""
def __init__(self, p, n, nodes_dict, f):
"""
 INPUT::
+ INPUT:
  p  The prime for which this defines an extension of GF(p).
  n  The degree of the extension.
  nodes_dict  (dict or bool). A dictionary of PseudoConwayPolyTrees, indexed by prime divisors of n. The entry for q corresponds to the pseudoConway extension of degree n//q.
 OR a boolean. If True, then this polynomial is actually in the Conway polynomials database, and no references to other PCPTs are stored. If False, then n is prime and no references are stored (since there is no compatiblity condition).
  f  The polynomial defining this extension.
+  ``p``  The prime for which this defines an extension of `F_p`.
+
+  ``n``  The degree of the extension.
+
+  ``nodes_dict``  dict or bool:
+
+  Either a dictionary of ``PseudoConwayPolyTrees``, indexed by prime
+ divisors of ``n``.
+ The entry for `q` corresponds to the pseudoConway extension of
+ degree `n/q`.
+  Or a boolean:
+
+  If ``True``, then this polynomial is actually in the Conway
+ polynomials database, and no references to other PCPTs are
+ stored.
+  If ``False``, then ``n`` is prime and no references are stored
+ (since there is no compatiblity condition).
+
+  ``f``  The polynomial defining this extension.
EXAMPLES::
@@ 657,13 +663,14 @@
self.n = n
self.nodes_dict = nodes_dict
self.f = f

+
def get_pseudo_conway_poly(self, m):
"""
 Returns the pseudoConway polynomial associated to a divisor of the degree of this tree.
+ Returns the pseudoConway polynomial associated to a divisor of the
+ degree of this tree.
EXAMPLES::

+
sage: from sage.rings.finite_rings.constructor import find_pseudo_conway_polynomial_tree
sage: PCPT = find_pseudo_conway_polynomial_tree(2, 6, False)
sage: PCPT.get_pseudo_conway_poly(3)
@@ 681,10 +688,11 @@
return pseudo_conway_poly[self.p][m]().f
except (KeyError, AttributeError):
return conway_polynomial(self.p, m)

+
def check_consistency(self):
"""
 Checks that the pseudoConway polynomials dividing the degree of this tree satisfy the required compatibility conditions.
+ Checks that the pseudoConway polynomials dividing the degree of this
+ tree satisfy the required compatibility conditions.
EXAMPLES::
@@ 702,29 +710,42 @@
def find_pseudo_conway_polynomial_tree(p, n, use_database=True):
"""
 Returns an object holding references to a set of consistent pseudoConway polynomials for degrees dividing n.
+ Returns an object holding references to a set of consistent pseudoConway
+ polynomials for degrees dividing ``n``.
 A Conway polynomial `f \in \Bold{F}_p` of degree `n` satisfies the following three conditions:

+ A Conway polynomial `f \in \Bold{F}_p` of degree `n` satisfies the
+ following three conditions:
+
 `f` is irreducible.
  In the quotient field `\Bold{F}_p[x]/(f)`, the indeterminant `x` is a multiplicative generator.
  In this same quotient field, the minimal polynomial of `x^{\frac{p^n1}{p^m1}}` is the Conway polynomial of degree `m` for every divisor `m` of `n`.
  `f` is lexicographically least among all such polynomials, under a certain ordering.
+  In the quotient field `\Bold{F}_p[x]/(f)`, the indeterminant `x` is a
+ multiplicative generator.
+  In this same quotient field, the minimal polynomial of
+ `x^{\frac{p^n1}{p^m1}}` is the Conway polynomial of degree `m`
+ for every divisor `m` of `n`.
+  `f` is lexicographically least among all such polynomials,
+ under a certain ordering.
 The final condition is needed only in order to make the Conway polynomial unique. We define a pseudoConway polynomial to be one satisfying the first three conditions.
+ The final condition is needed only in order to make the Conway polynomial
+ unique.
+ We define a pseudoConway polynomial to be one satisfying the first three
+ conditions.
INPUT:
  `p`  a prime.
  `n`  an integer greater than 1.
  `use_database`  whether to use the Conway polynomials database if the Conway polynomial for `p, n` exists within it (versus computing a pseudoConway polynomial)
+  ``p``  a prime.
+
+  ``n``  an integer greater than 1.
+
+  ``use_database``  whether to use the Conway polynomials database if
+ the Conway polynomial for `p, n` exists within it (versus computing a
+ pseudoConway polynomial)
EXAMPLES::
sage: from sage.rings.finite_rings.constructor import find_pseudo_conway_polynomial_tree
sage: PCPT = find_pseudo_conway_polynomial_tree(2, 12, False)
sage: PCPT.f
 x^12 + x^10 + x^9 + x^8 + x^4 + x^2 + 1
+ x^12 + x^11 + x^10 + x^4 + 1
"""
if not pseudo_conway_poly.has_key(p):
pseudo_conway_poly[p] = {}
@@ 753,13 +774,17 @@
INPUT:
  `p`  a prime.
+  ``p``  a prime.
+
 ``field_degree``  a positive integer
  `x`  an element of a field `K` of characeristic p so that the multiplicative order of `x` is ``p^field_degree``.
  `y`  an element of `K` with the same minimal polynomial.

+
+  ``x``  an element of a field `K` of characeristic p so that the
+ multiplicative order of `x` is ``p^field_degree``.
+
+  ``y``  an element of `K` with the same minimal polynomial.
+
OUTPUT:

+
An element `i` of ``Integers(field_degree)`` so that `x = y^{p^i}`
EXAMPLES::
@@ 784,7 +809,8 @@
def _crt_non_coprime(running, a):
"""
 Extends the ``crt`` method of IntegerMod to the case of nonrelatively prime modulus.
+ Extends the ``crt`` method of IntegerMod to the case of nonrelatively
+ prime modulus.
EXAMPLES::
@@ 816,9 +842,14 @@
def _frobenius_shift(K, generators, check_only=False):
"""
 Given a field `K` of degree `n` over ``GF(p)`` and a dictionary holding, for each divisor `q` of `n`, an element with minimal polynomial a pseudoConway polynomial of degree `n/q`, modifies these generators into a compatibile system.
+ Given a field `K` of degree `n` over `F_p` and a dictionary holding,
+ for each divisor `q` of `n`, an element with minimal polynomial a
+ pseudoConway polynomial of degree `n/q`, modifies these generators into a
+ compatibile system.
 Such a system of generators is said to be compatible if for each pair of prime divisors `q_1` and `q_2` and each common divisor `m` of `n/q_1` and `n/q_2`, the equality
+ Such a system of generators is said to be compatible if for each pair of
+ prime divisors `q_1` and `q_2` and each common divisor `m` of `n/q_1` and
+ `n/q_2`, the equality
``generators[q1]^((p^(n/q1)1)/(p^m1)) == generators[q2]^((p^(n/q2)1)/(p^m1))``
@@ 826,9 +857,14 @@
INPUT:
  K  a finite field of degree n
  generators  a dictionary, indexed by prime divisors `q` of `n`, whose entries are elements of `K` satisfying the `n/q` pseudoConway polynomial.
  check_only  if True, just asserts that the generators given form a compatible system.
+  ``K``  a finite field of degree n
+
+  ``generators``  a dictionary, indexed by prime divisors `q` of `n`,
+ whose entries are elements of `K` satisfying the `n/q` pseudoConway
+ polynomial.
+
+  ``check_only``  if ``True``, just asserts that the generators given
+ form a compatible system.
EXAMPLES::
@@ 979,58 +1015,71 @@
"""
Computes a pseudoConway polynomial over the prime `p` of degree `n`.
 A Conway polynomial `f \in \Bold{F}_p` of degree `n` satisfies the following three conditions:

+ A Conway polynomial `f \in \Bold{F}_p` of degree `n` satisfies the
+ following three conditions:
+
 `f` is irreducible.
  In the quotient field `\Bold{F}_p[x]/(f)`, the indeterminant `x` is a multiplicative generator.
  In this same quotient field, the minimal polynomial of `x^{\frac{p^n1}{p^m1}}` is the Conway polynomial of degree `m` for every divisor `m` of `n`.
  `f` is lexicographically least among all such polynomials, under a certain ordering.
+  In the quotient field `\Bold{F}_p[x]/(f)`, the indeterminant `x` is a
+ multiplicative generator.
+  In this same quotient field, the minimal polynomial of
+ `x^{\frac{p^n1}{p^m1}}` is the Conway polynomial of degree `m`
+ for every divisor `m` of `n`.
+  `f` is lexicographically least among all such polynomials,
+ under a certain ordering.
 The final condition is needed only in order to make the Conway polynomial unique. We define a pseudoConway polynomial to be one satisfying the first three conditions.
+ The final condition is needed only in order to make the Conway polynomial
+ unique. We define a pseudoConway polynomial to be one satisfying the
+ first three conditions.
INPUT:

  `p`  a prime
  `n`  a positive integer
  ``nodes``  None (in the case that `n` is prime) or a dictionary of PseudoConwayPolyTree objects, indexed by prime divisors `q` of `n` with entries corresponding to pseudoConway polynomials of degree `n/q`.
+
+  ``p``  a prime
+
+  ``n``  a positive integer
+
+  ``nodes``  None (in the case that `n` is prime) or a dictionary
+ of PseudoConwayPolyTree objects, indexed by prime divisors `q` of `n`
+ with entries corresponding to pseudoConway polynomials of degree `n/q`.
OUTPUT:
A pseudoConway polynomial over the prime `p` of degree `n`.
ALGORITHM:

 Uses an algorithm described in [HL99]_, modified to find pseudoConway polynomials rather than Conway polynomials. The major modification was the addition of the function _frobenius_shift.
+
+ Uses an algorithm described in [HL99]_, modified to find pseudoConway
+ polynomials rather than Conway polynomials.
+ The major modification was the addition of the function ``_frobenius_shift``.
REFERENCE:
 .. [HL99] Heath L. and Loehr N. (1999).
+ .. [HL99] Heath L. and Loehr N. (1999).
New algorithms for generating Conway polynomials over finite fields.
 Proceedings of the tenth annual ACMSIAM symposium on Discrete algorithms, pp. 429437.
+ Proceedings of the tenth annual ACMSIAM symposium on Discrete
+ algorithms, pp. 429437.
EXAMPLES::
sage: from sage.rings.finite_rings.constructor import compute_pseudo_conway_polynomial, find_pseudo_conway_polynomial_tree
sage: compute_pseudo_conway_polynomial(next_prime(10000),11,None) # long because the arithmetic in FiniteField_ext_pari fields is slow.
 x^11 + x + 7
+ x^11 + x + 24
sage: PCPT30 = find_pseudo_conway_polynomial_tree(2, 30, False)
sage: PCPT20 = find_pseudo_conway_polynomial_tree(2, 20, False)
sage: PCPT12 = find_pseudo_conway_polynomial_tree(2, 12, False)
sage: compute_pseudo_conway_polynomial(2, 60, {2:PCPT30,3:PCPT20,5:PCPT12})
 x^60 + x^59 + x^56 + x^53 + x^49 + x^45 + x^43 + x^42 + x^41 + x^40 + x^39 + x^37 + x^36 + x^34 + x^31 + x^30 + x^27 + x^26 + x^25 + x^23 + x^21 + x^19 + x^17 + x^15 + x^14 + x^11 + x^9 + x^8 + x^7 + x^6 + x^5 + x^2 + 1
+ x^60 + x^58 + x^56 + x^55 + x^52 + x^51 + x^50 + x^47 + x^44 + x^39 + x^36 + x^33 + x^31 + x^28 + x^27 + x^25 + x^23 + x^21 + x^17 + x^15 + x^14 + x^13 + x^11 + x^10 + x^9 + x^8 + x^7 + x^4 + 1
"""
k = GF(p)
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
R = PolynomialRing(k, names='x')
if n == 1:
return R([k.multiplicative_generator(), 1])
 if nodes is None:
 # n is prime. We require only that the chosen generator (x) be a multiplicative generator for the units.
 if p in [2,3,5,7,11]: # here we have Cunningham data
 from sage.rings.factorint import factor_cunningham
 F = [(p**n1)//a for a, e in factor_cunningham(n)]
 else:
 F = (p**n1).prime_factors() # could be VERY expensive
+ if nodes is None:
+ # n is prime.
+ # We only require that the chosen generator (x) is a multiplicative
+ # generator for the units.
+ q = p**n  1
+ F = [q//m for m in q.prime_factors()] # could be VERY expensive
x = R.gen()
from sage.rings.arith import power_mod
for f in R.polynomials(of_degree=n):
@@ 1045,7 +1094,7 @@
return f
# Our strategy is as follows:
# Work in an arbitrary field K of order p**n.
 # We're looking for a multiplicative generator of K whose
+ # We're looking for a multiplicative generator of K whose
K = GF(p**n, modulus="first_lexicographic", names='a')
r = p**n  1
xi = {}
@@ 1053,7 +1102,7 @@
#print nodes[q].f.degree(), n//q
xi[q] = nodes[q].f.any_root(K, n//q, True)
_frobenius_shift(K, xi)

+
q, x = xi.popitem()
v = p**(n//q)  1
for q, xitem in xi.iteritems():
@@ 1063,7 +1112,9 @@
v = v.lcm(fi)
g = r // v
#print g, n, g.divides(p**n1)
 z = x.nth_root(g, cunningham=(p in [2,3,5,7,11]))
+ # The following could be useful if #7240 is merged but #12125 is not.
+ #z = x.nth_root(g, cunningham=(p in [2,3,5,7,11]))
+ z = x.nth_root(g)
groot1 = K.multiplicative_generator()**v
while z.multiplicative_order() != r:
z *= groot1
diff git a/sage/rings/finite_rings/element_base.pyx b/sage/rings/finite_rings/element_base.pyx
 a/sage/rings/finite_rings/element_base.pyx
+++ b/sage/rings/finite_rings/element_base.pyx
@@ 32,12 +32,13 @@
cdef class FiniteRingElement(CommutativeRingElement):
def _nth_root_common(self, n, all, algorithm, cunningham):
"""
 This function exists to reduce code duplication between finite field nth roots and integer_mod nth roots.

+ This function exists to reduce code duplication between finite field
+ nth roots and integer_mod nth roots.
+
The inputs are described there.

+
TESTS::

+
sage: a = Zmod(17)(13)
sage: a._nth_root_common(4, True, "Johnston", False)
[3, 5, 14, 12]
@@ 545,7 +546,7 @@
 ``all``  bool (default: ``False``); if ``True``, return all `n`\th
roots of ``self``, instead of just one.
  ``algorithm``  string (default: ``None``); 'Johnston' is the only
+  ``algorithm``  string (default: ``None``); 'Johnston' is the only
currently supported option. For IntegerMod elements, the problem
is reduced to the prime modulus case using CRT and `p`adic logs,
and then this algorithm used.
@@ 553,13 +554,13 @@
OUTPUT:
If self has an `n`\th root, returns one (if ``all`` is ``False``) or a
 list of all of them (if ``all`` is ``True``). Otherwise, raises a
 ValueError (if ``extend`` is ``False``) or a ``NotImplementedError`` (if
 ``extend`` is ``True``).
+ list of all of them (if ``all`` is ``True``).
+ Otherwise, raises a ``ValueError`` (if ``extend`` is ``False``)
+ or a ``NotImplementedError`` (if ``extend`` is ``True``).
.. warning::

 The 'extend' option is not implemented (yet).
+
+ The ``extend`` option is not implemented (yet).
EXAMPLES::
diff git a/sage/rings/finite_rings/finite_field_base.pyx b/sage/rings/finite_rings/finite_field_base.pyx
 a/sage/rings/finite_rings/finite_field_base.pyx
+++ b/sage/rings/finite_rings/finite_field_base.pyx
@@ 551,11 +551,7 @@
[2^4 * 3]
"""
if self.__factored_unit_order is None:
 if self.characteristic() in []: # want to be [2,3,5,7,11] once #7240 is finished.
 from sage.rings.factorint import factor_cunningham
 self.__factored_unit_order = [factor_cunningham(self.order()1)]
 else:
 self.__factored_unit_order = [(self.order()1).factor()]
+ self.__factored_unit_order = [(self.order()1).factor()]
return self.__factored_unit_order
def cardinality(self):
@@ 748,14 +744,15 @@
def construction(self):
"""
 Returns the construction of this finite field, as a ConstructionFunctor and the base field.
+ Return the construction of this finite field, as a ``ConstructionFunctor``
+ and the base field.
EXAMPLES::

+
sage: v = GF(3^3).construction(); v
(AlgebraicExtensionFunctor, Finite Field of size 3)
sage: v[0].polys[0]
 3
+ z3^3 + 2*z3 + 1
sage: v = GF(2^1000,'a').construction(); v[0].polys[0]
a^1000 + a^5 + a^4 + a^3 + 1
"""
@@ 763,53 +760,65 @@
if self.degree() == 1:
# this is not of type FiniteField_prime_modn
from sage.rings.integer import Integer
 return AlgebraicExtensionFunctor([Integer(1)], [None],[None]), self.base_ring()
+ return AlgebraicExtensionFunctor([self.polynomial()],[None],[None],conway=1), self.base_ring()
elif hasattr(self, '_PCPT') and self._PCPT is not None:
 return AlgebraicExtensionFunctor([self.degree()], [self.variable_name()],[None],prefix=self._prefix), self.base_ring()
+ return AlgebraicExtensionFunctor([self.polynomial()],[self.variable_name()],[None],conway=self.degree(),prefix=self._prefix), self.base_ring()
else:
 return AlgebraicExtensionFunctor([self.polynomial()], [self.variable_name()],[None]), self.base_ring()
+ return AlgebraicExtensionFunctor([self.polynomial()],[self.variable_name()],[None]), self.base_ring()
 def extension(self, modulus, name=None, names=None, embedding=None, prefix='z'):
+ def extension(self, modulus, name=None, names=None, embedding=None, conway=None, prefix='z'):
"""
 Returns an extension of this finite field.
+ Return an extension of this finite field.
 INPUT::
+ INPUT:
  modulus  either a polynomial with coefficients in this field or an integer.
 If an integer, returns the pseudoConway extension of this field of that degree.
  name  the name of the generator in the new extension
  embedding  currently not used; for compatibility with other AlgebraicExtensionFunctor calls.
  prefix  Passed on to the finite field constructor. See the documentation of
 ``GF`` in ``sage.rings.finite_rings.constructor``
+  ``modulus``  either a polynomial with coefficients in this field or
+ an integer.
+ If an Integer, returns the pseudoConway extension of this field of
+ that degree.
 OUTPUT::

 An extension of the given modulus, or pseudoConway of the given degree if the modulus is just an integer.

+  ``name``  the name of the generator in the new extension
+
+  ``embedding``  currently not used; for compatibility with other
+ ``AlgebraicExtensionFunctor`` calls.
+
+  ``conway``  currently not used; None or an ``Integer`` used to indicate
+ that the extension is pseudoConway of the given degree.
+
+  ``prefix``  Passed on to the finite field constructor.
+ See the documentation of ``GF`` in ``sage.rings.finite_rings.constructor``
+
+ OUTPUT:
+
+ An extension of the given modulus, or pseudoConway of the given degree
+ if ``conway`` is an integer.
+
EXAMPLES::
+ sage: k = GF(2)
+ sage: R. = k[]
+ sage: k.extension(x^1000 + x^5 + x^4 + x^3 + 1, 'a')
+ Finite Field in a of size 2^1000
sage: k = GF(3^4)
+ sage: R. = k[]
sage: k.extension(3)
Finite Field in z12 of size 3^12
 sage: R. = GF(2)[]
 sage: GF(2).extension(x^1000 + x^5 + x^4 + x^3 + 1,'a')
 Finite Field in a of size 2^1000
 sage: R. = GF(3)[]
 Extensions of nonprime finite fields by polynomials are not yet supported: we fall back to generic code.
+ Extensions of nonprime finite fields by polynomials are not yet
+ supported: we fall back to generic code::
sage: k.extension(x^5 + x^2 + x  1)
Univariate Quotient Polynomial Ring in x over Finite Field in z4 of size 3^4 with modulus x^5 + x^2 + x + 2
"""
from constructor import GF
+ from sage.rings.polynomial.all import is_Polynomial
from sage.rings.integer import Integer
 from sage.rings.polynomial.all import is_Polynomial
if name is None and names is not None:
name = names
if self.degree() == 1:
if isinstance(modulus, Integer):
return GF(self.characteristic()**modulus, modulus='conway', name=name, prefix=prefix)
 if isinstance(modulus, (list, tuple)):
+ elif isinstance(modulus, (list, tuple)):
return GF(self.characteristic()**(len(modulus)  1), name=name, modulus=modulus, prefix=prefix)
elif is_Polynomial(modulus):
if modulus.change_ring(self).is_irreducible():
@@ 823,30 +832,38 @@
def subfields(self, degree=0, name=None):
"""
 Return all proper subfields of self of the given degree,
 or of all possible degrees if degree is 0.
+ Return all proper subfields of ``self`` of the given ``degree``,
+ or of all possible degrees if ``degree`` is `0`.
 The subfields are returned as
 absolute fields together with an embedding into self.
+ The subfields are returned as absolute fields together with
+ an embedding into ``self``.
 INPUT::
+ INPUT:
  degree  (default 0) An integer.
  name  A string, a dictionary or None.
 If degree is nonzero, name must be a string (or None, if this is a pseudoConway extension), and will be the variable name of the returned field.
 If degree is zero, the dictionary should have keys the divisors of the degree of this field, with the desired variable name for the field of that degree as an entry.
 As a shortcut, you can provide a string and the degree of each subfield will be appended for the variable name of that subfield.
 If None, uses the prefix of this field.

 OUTPUT::
+  ``degree``  (default: `0`) an integer
 A list of pairs (K, e), where K ranges over the subfields of this field and e gives an embedding of K into this field.
+  ``name``  a string, a dictionary or ``None``:
+
+  If ``degree`` is nonzero, ``name`` must be a string
+ (or ``None``, if this is a pseudoConway extension),
+ and will be the variable name of the returned field.
+  If ``degree`` is zero, the dictionary should have keys the divisors
+ of the degree of this field, with the desired variable name for the
+ field of that degree as an entry.
+  As a shortcut, you can provide a string and the degree of each
+ subfield will be appended for the variable name of that subfield.
+  If ``None``, uses the prefix of this field.
+
+ OUTPUT:
+
+ A list of pairs ``(K, e)``, where ``K`` ranges over the subfields of
+ this field and ``e`` gives an embedding of ``K`` into this field.
EXAMPLES::
sage: k. = GF(2^21)
sage: k.subfields()
 [(Finite Field of size 2,
+ [(Finite Field of size 2,
Conversion map:
From: Finite Field of size 2
To: Finite Field in a of size 2^21),
@@ 923,7 +940,7 @@
This is not yet implemented for finite fields.
EXAMPLES::

+
sage: GF(5).algebraic_closure()
Traceback (most recent call last):
...
@@ 947,7 +964,7 @@
r"""
Used to unpickle finite prime fields. Now superseded (hence no doctest),
but kept around for backward compatibility.

+
EXAMPLE::
sage: # not tested
@@ 974,4 +991,3 @@
False
"""
return IS_INSTANCE(x, FiniteField)

diff git a/sage/rings/finite_rings/finite_field_givaro.py b/sage/rings/finite_rings/finite_field_givaro.py
 a/sage/rings/finite_rings/finite_field_givaro.py
+++ b/sage/rings/finite_rings/finite_field_givaro.py
@@ 27,7 +27,7 @@
 ``name``  (default: ``'a'``) variable used for
:meth:`~sage.rings.finite_rings.element_givaro.FiniteField_givaroElement.poly_repr()`
  ``modulus``  (default: ``conway``, a conway polynomial is used if in
+  ``modulus``  (default: ``'conway'``, a conway polynomial is used if in
the database, otherwise a pseudoConway polynomial is generated)
A minimal polynomial to use for reduction or ``'random'`` to force a
random irreducible polynomial.
diff git a/sage/rings/finite_rings/integer_mod.pyx b/sage/rings/finite_rings/integer_mod.pyx
 a/sage/rings/finite_rings/integer_mod.pyx
+++ b/sage/rings/finite_rings/integer_mod.pyx
@@ 2038,6 +2038,9 @@
IntegerMod_abstract.__init__(self, parent)
if empty:
return
+ if self.__modulus.int32 == 1:
+ self.ivalue = 0
+ return
cdef long x
if PY_TYPE_CHECK(value, int):
x = value
diff git a/sage/rings/finite_rings/integer_mod_ring.py b/sage/rings/finite_rings/integer_mod_ring.py
 a/sage/rings/finite_rings/integer_mod_ring.py
+++ b/sage/rings/finite_rings/integer_mod_ring.py
@@ 395,6 +395,13 @@
"""
return True
+ def extension(self, poly, name=None, names=None, embedding=None):
+ if self.modulus() == 1:
+ return self
+ else:
+ from sage.rings.ring import CommutativeRing
+ return CommutativeRing.extension(self, poly, name, names, embedding)
+
@cached_method
def is_prime_field(self):
"""
diff git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
 a/sage/rings/polynomial/polynomial_element.pyx
+++ b/sage/rings/polynomial/polynomial_element.pyx
@@ 5367,14 +5367,27 @@
Returns a root of this polynomial in the given ring.
INPUT:

  ``ring``  The ring in which a root is sought. By default this is the coefficient ring.

  ``degree`` (None or nonzero integer)  Used for polynomials over finite fields. Returns a root of degree ``abs(degree)`` over the ground field. If negative, also assumes that all factors of this polynomial are of degree ``abs(degree)``. If None, returns a root of minimal degree contained within the given ring.

  ``assume_squarefree`` (bool)  Used for polynomials over finite fields. If True, this polynomial is assumed to be squarefree.

  ``extend``  Used for polynomials over finite fields. If ``ring is None`` and ``extend`` is true, finds a root in the smallest extension of the base ring over which this polynomial has a root. If ``ring is None`` and ``extend`` is false, only looks for a root in the base ring. If ``ring`` is specified, then extend=True allows a root to lie in an extension of the given ring.
+
+  ``ring``  The ring in which a root is sought.
+ By default this is the coefficient ring.
+
+  ``degree`` (None or nonzero integer)  Used for polynomials over
+ finite fields. Returns a root of degree ``abs(degree)`` over the
+ ground field. If negative, also assumes that all factors of this
+ polynomial are of degree ``abs(degree)``. If ``None``, returns a root
+ of minimal degree contained within the given ring.
+
+  ``assume_squarefree`` (bool)  Used for polynomials over
+ finite fields. If ``True``, this polynomial is assumed to be
+ squarefree.
+
+  ``extend``  Used for polynomials over finite fields.
+ If ``ring`` is ``None`` and ``extend`` is ``True``, finds a root in
+ the smallest extension of the base ring over which this polynomial
+ has a root. If ``ring`` is ``None`` and ``extend`` is ``False``, only
+ looks for a root in the base ring. If ``ring`` is specified, then
+ ``extend=True`` allows a root to lie in an extension of the given
+ ring.
EXAMPLES::
diff git a/sage/rings/polynomial/polynomial_quotient_ring.py b/sage/rings/polynomial/polynomial_quotient_ring.py
 a/sage/rings/polynomial/polynomial_quotient_ring.py
+++ b/sage/rings/polynomial/polynomial_quotient_ring.py
@@ 53,7 +53,7 @@
 ``ring``  a univariate polynomial ring in one
variable.
  ``polynomial``  element
+  ``polynomial``  element with unit leading coefficient
 ``names``  (optional) name for the variable
diff git a/sage/rings/polynomial/polynomial_quotient_ring_element.py b/sage/rings/polynomial/polynomial_quotient_ring_element.py
 a/sage/rings/polynomial/polynomial_quotient_ring_element.py
+++ b/sage/rings/polynomial/polynomial_quotient_ring_element.py
@@ 130,7 +130,7 @@
raise TypeError, "polynomial must be in the polynomial ring of the parent"
f = parent.modulus()
 if polynomial.degree() >= f.degree():
+ if polynomial.degree() >= f.degree() and polynomial.degree() >= 0:
try:
polynomial %= f
except AttributeError:
@@ 143,7 +143,7 @@
while R.degree() >= B.degree():
S = P((R.leading_coefficient()/B.leading_coefficient())) * X**(R.degree()B.degree())
Q = Q + S
 R = R  S*B
+ R = R  S*B
polynomial = R
self._polynomial = polynomial
diff git a/sage/rings/polynomial/polynomial_ring.py b/sage/rings/polynomial/polynomial_ring.py
 a/sage/rings/polynomial/polynomial_ring.py
+++ b/sage/rings/polynomial/polynomial_ring.py
@@ 181,6 +181,7 @@
from polynomial_real_mpfr_dense import PolynomialRealDense
from sage.rings.polynomial.polynomial_singular_interface import PolynomialRing_singular_repr
from sage.rings.fraction_field_element import FractionFieldElement
+from sage.rings.finite_rings.element_base import FiniteRingElement
from polynomial_element import PolynomialBaseringInjection
@@ 417,12 +418,16 @@
x = x.numerator() * x.denominator().inverse_of_unit()
else:
raise TypeError, "denominator must be a unit"

elif isinstance(x, pari_gen):
if x.type() == 't_RFRAC':
raise TypeError, "denominator must be a unit"
if x.type() != 't_POL':
x = x.Polrev()
+ elif isinstance(x, FiniteRingElement):
+ try:
+ return self(x.polynomial())
+ except AttributeError:
+ pass
return C(self, x, check, is_gen, construct=construct, **kwds)
def is_integral_domain(self, proof = True):