Skip to content

Commit

Permalink
Trac #15552: enumerate_totallyreal_fields_prim does not return polyno…
Browse files Browse the repository at this point in the history
…mial as elements of a polynomial ring

The function `enumerate_totallyreal_fields_prim` is supposed to return,
according to its description,
{{{
   OUTPUT:

   the list of fields with entries "[d,f]", where "d" is the
   discriminant and "f" is a defining polynomial, sorted by
   discriminant.
}}}
Let us look at an output:
{{{
sage: E = enumerate_totallyreal_fields_prim(2, 10); E
[[5, x^2 - x - 1], [8, x^2 - 2]]
sage: E[0][1].parent()
Interface to the PARI C library
}}}
We notice from here that the polynomial does not actually belong to the
polynomial ring of `QQ`. In fact, there is no nice way to directly get
the polynomial, as in an element of `PolynomialRing(QQ)` from `E[0][1]`,
which can be then used to construct the number field.

The only way to do this is this lengthy and tedious procedure:
{{{
sage: Ecoef = [QQ(_) for _ in E[0][1].list()]
sage: x = polygen(QQ)
sage: Epol = sum(x**i * _ for i,_ in enumerate(Ecoef))
sage: Epol, Epol.parent()
(x^2 - x - 1, Univariate Polynomial Ring in x over Rational Field)
}}}

The output of the function itself should give back elements of the
polynomial ring, instead of giving us elements which are simply output
of pari.

----

Additionally,

1. the first entry of each list should belong to Sage's `Integer` ring
instead of being just a python `int`.
2. the functions `enumerate_totallyreal_fields_all` and
`enumerate_totallyreal_fields_rel` should get the same fix.

URL: http://trac.sagemath.org/15552
Reported by: ppurka
Ticket author(s): Punarbasu Purkayastha
Reviewer(s): Francis Clarke
  • Loading branch information
Release Manager authored and vbraun committed Mar 1, 2014
2 parents e1428e0 + 7e86783 commit fc66c5b
Show file tree
Hide file tree
Showing 2 changed files with 196 additions and 65 deletions.
76 changes: 53 additions & 23 deletions src/sage/rings/number_field/totallyreal.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.rings.integer import Integer
from sage.rings.integer cimport Integer
from sage.rings.integer_ring import IntegerRing
from sage.rings.all import ZZ
from sage.rings.all import ZZ, QQ
from sage.misc.misc import cputime

from sage.rings.number_field.totallyreal_data import tr_data, int_has_small_square_divisor
Expand All @@ -144,8 +144,9 @@ cpdef double odlyzko_bound_totallyreal(int n):
This function returns the unconditional Odlyzko bound for the root
discriminant of a totally real number field of degree n.
NOTE:
The bounds for n > 50 are not necessarily optimal.
.. note::
The bounds for n > 50 are not necessarily optimal.
INPUT:
Expand Down Expand Up @@ -184,7 +185,8 @@ cpdef double odlyzko_bound_totallyreal(int n):

def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False,
phc=False, keep_fields=False, t_2=False,
just_print=False):
just_print=False,
return_pari_objects=True):
r"""
This function enumerates primitive totally real fields of degree
`n>1` with discriminant `d \leq B`; optionally one can specify the
Expand All @@ -203,24 +205,29 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False
INPUT:
- ``n`` (integer): the degree
- ``B`` (integer): the discriminant bound
- ``a`` (list, default: []): the coefficient list to begin with
- ``verbose`` (integer or string, default: 0): if ``verbose == 1``
- ``n`` -- (integer) the degree
- ``B`` -- (integer) the discriminant bound
- ``a`` -- (list, default: []) the coefficient list to begin with
- ``verbose`` -- (integer or string, default: 0) if ``verbose == 1``
(or ``2``), then print to the screen (really) verbosely; if verbose is
a string, then print verbosely to the file specified by verbose.
- ``return_seqs`` (boolean, default False)If ``return_seqs``, then return
- ``return_seqs`` -- (boolean, default False) If ``True``, then return
the polynomials as sequences (for easier exporting to a file).
- ``phc`` -- boolean or integer (default: False)
- ``keep_fields`` (boolean or integer, default: False) If ``keep_fields`` is True,
then keep fields up to ``B*log(B)``; if ``keep_fields`` is an integer, then
keep fields up to that integer.
- ``t_2`` (boolean or integer, default: False) If ``t_2 = T``, then keep
only polynomials with t_2 norm >= T.
- ``just_print`` (boolean, default: False): if ``just_print`` is not False,
instead of creating a sorted list of totally real number fields, we simply
write each totally real field we find to the file whose filename is given by
``just_print``. In this case, we don't return anything.
- ``keep_fields`` -- (boolean or integer, default: False) If
``keep_fields`` is True, then keep fields up to ``B*log(B)``; if
``keep_fields`` is an integer, then keep fields up to that integer.
- ``t_2`` -- (boolean or integer, default: False) If ``t_2 = T``, then
keep only polynomials with t_2 norm >= T.
- ``just_print`` -- (boolean, default: False): if ``just_print`` is not
False, instead of creating a sorted list of totally real number
fields, we simply write each totally real field we find to the file
whose filename is given by ``just_print``. In this case, we don't
return anything.
- ``return_pari_objects`` -- (boolean, default: True) if
both ``return_seqs`` and ``return_pari_objects`` are ``False`` then
it returns the elements as Sage objects; otherwise it returns pari
objects.
OUTPUT:
Expand Down Expand Up @@ -248,6 +255,21 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False
2720
sage: len(enumerate_totallyreal_fields_prim(5,5**8)) # long time
103
Each of the outputs must be elements of Sage if ``return_pari_objects``
is set to ``False``::
sage: enumerate_totallyreal_fields_prim(2, 10)
[[5, x^2 - x - 1], [8, x^2 - 2]]
sage: enumerate_totallyreal_fields_prim(2, 10)[0][1].parent()
Interface to the PARI C library
sage: enumerate_totallyreal_fields_prim(2, 10, return_pari_objects=False)[0][0].parent()
Integer Ring
sage: enumerate_totallyreal_fields_prim(2, 10, return_pari_objects=False)[0][1].parent()
Univariate Polynomial Ring in x over Rational Field
sage: enumerate_totallyreal_fields_prim(2, 10, return_seqs=True)[1][0][1][0].parent()
Rational Field
"""

cdef pari_gen B_pari, d, d_poly, keepB, nf, t2val, ngt2, ng
Expand All @@ -270,7 +292,6 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False

# Initialize
n_int = int(n)
T = tr_data(n_int,B,a)
S = []
lenS = 0

Expand Down Expand Up @@ -336,8 +357,11 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False
sage_free(f_out)
if return_seqs:
return [[0,0,0,0],[[1,[-1,1]]]]
else:
elif return_pari_objects:
return [[1,pari('x-1')]]
else:
Px = PolynomialRing(QQ, 'x')
return [[ZZ(1), Px.gen()-1]]

if verbose:
verb_int = 1
Expand All @@ -349,6 +373,7 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False
else:
verb_int = 0

T = tr_data(n_int,B,a)
if verb_int == 2:
T.incr(f_out,verb_int,0,phc_flag)
else:
Expand Down Expand Up @@ -472,11 +497,16 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False
sys.stdout = saveout

sage_free(f_out)
# Make sure to return elements that belong to Sage
if return_seqs:
return [[ counts[i] for i in range(4) ],
[[s[0],s[1].reverse().Vec()] for s in S]]
else:
return [[ZZ(counts[i]) for i in range(4)],
[[ZZ(s[0]), map(QQ, s[1].reverse().Vec())] for s in S]]
elif return_pari_objects:
return S
else:
Px = PolynomialRing(QQ, 'x')
return [[ZZ(s[0]), Px(map(QQ, s[1].list()))]
for s in S]

def weed_fields(S, Py_ssize_t lenS=0):
r"""
Expand Down

0 comments on commit fc66c5b

Please sign in to comment.