# HG changeset patch
# User Nick Alexander <ncalexander@gmail.com>
# Date 1232762769 28800
# Node ID 868cc7270136161eaa5232dfc68d2bb2ad06698a
# Parent  cc37ebbf6f16cf2e14dd75dca03d9a25bf82ef83
[mq]: trac_5066_reorg.patch

diff -r cc37ebbf6f16 -r 868cc7270136 sage/rings/number_field/number_field.py
--- a/sage/rings/number_field/number_field.py	Fri Jan 23 00:55:58 2009 -0800
+++ b/sage/rings/number_field/number_field.py	Fri Jan 23 18:06:09 2009 -0800
@@ -59,7 +59,9 @@
 TESTS:
     sage: y = polygen(QQ,'y'); K.<beta> = NumberField([y^3 - 3, y^2 - 2])
     sage: K(y^10)
-    (-3024*beta1 + 1530)*beta0^2 + (-2320*beta1 + 5067)*beta0 - 3150*beta1 + 7592
+    27*beta0
+    sage: beta^10
+    27*beta0
 """
 
 #*****************************************************************************
@@ -798,569 +800,9 @@
         embedding = number_field_morphisms.create_embedding_from_approx(self, embedding)
         self._populate_coercion_lists_(embedding=embedding)
 
-    def _Hom_(self, codomain, cat=None):
-        """
-        Return homset of homomorphisms from self to the number field codomain.
-
-        The cat option is currently ignored.
-
-        EXAMPLES:
-        This function is implicitly called by the Hom method or function.
-            sage: K.<i> = NumberField(x^2 + 1); K
-            Number Field in i with defining polynomial x^2 + 1
-            sage: K.Hom(K)
-            Automorphism group of Number Field in i with defining polynomial x^2 + 1
-            sage: Hom(K, QuadraticField(-1, 'b'))
-            Set of field embeddings from Number Field in i with defining polynomial x^2 + 1 to Number Field in b with defining polynomial x^2 + 1
-        """
-        import morphism
-        return morphism.NumberFieldHomset(self, codomain)
-
-    def _set_structure(self, from_self, to_self, unsafe_force_change=False):
-        """
-        Internal function to set the structure fields of this number field.
-        """
-        # Note -- never call this on a cached number field, since
-        # that could eventually lead to problems.
-        if unsafe_force_change:
-            self.__from_self = from_self
-            self.__to_self = to_self
-            return
-        try:
-            self.__from_self
-        except AttributeError:
-            self.__from_self = from_self
-            self.__to_self = to_self
-        else:
-            raise ValueError, "number field structure is immutable."
-
-    def structure(self):
-        """
-        Return fixed isomorphism or embedding structure on self.
-
-        This is used to record various isomorphisms or embeddings
-        that arise naturally in other constructions.
-
-        EXAMPLES:
-            sage: K.<z> = NumberField(x^2 + 3)
-            sage: L.<a> = K.absolute_field(); L
-            Number Field in a with defining polynomial x^2 + 3
-            sage: L.structure()
-            (Isomorphism given by variable name change map:
-              From: Number Field in a with defining polynomial x^2 + 3
-              To:   Number Field in z with defining polynomial x^2 + 3,
-             Isomorphism given by variable name change map:
-              From: Number Field in z with defining polynomial x^2 + 3
-              To:   Number Field in a with defining polynomial x^2 + 3)
-        """
-        try:
-            if self.__to_self is not None:
-                return self.__from_self, self.__to_self
-            else:
-                return self.__from_self, self.__to_self
-        except AttributeError:
-            f = self.hom(self)
-            self._set_structure(f,f)
-            return f, f
-    
-    def completion(self, p, prec, extras={}):
-        """
-        Returns the completion of self at $p$ to the specified precision. 
-        Only implemented at archimedean places, and then only if an embedding
-        has been fixed.  
-        
-        EXAMPLES: 
-            sage: K.<a> = QuadraticField(2)
-            sage: K.completion(infinity, 100)
-            Real Field with 100 bits of precision
-            sage: K.<zeta> = CyclotomicField(12)
-            sage: K.completion(infinity, 53, extras={'type': 'RDF'})
-            Complex Double Field
-            sage: zeta + 1.5                            # implicit test
-            2.36602540378444 + 0.500000000000000*I
-        """
-        if p == infinity.infinity:
-            gen_image = self.gen_embedding()
-            if gen_image is not None:
-                if gen_image in RDF:
-                    return QQ.completion(p, prec, extras)
-                elif gen_image in CDF:
-                    return QQ.completion(p, prec, extras).algebraic_closure()
-            raise ValueError, "No embedding into the complex numbers has been specified."
-        else:
-            raise NotImplementedError
-
-    def primitive_element(self):
-        r"""
-        Return a primitive element for this field, i.e., an element
-        that generates it over $\QQ$.
-
-        EXAMPLES:
-            sage: K.<a> = NumberField(x^3 + 2)
-            sage: K.primitive_element()
-            a
-            sage: K.<a,b,c> = NumberField([x^2-2,x^2-3,x^2-5])
-            sage: K.primitive_element()
-            a - b + c
-            sage: alpha = K.primitive_element(); alpha
-            a - b + c
-            sage: alpha.minpoly()
-            x^2 + (2*b - 2*c)*x - 2*c*b + 6
-            sage: alpha.absolute_minpoly()
-            x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576
-        """
-        try:
-            return self.__primitive_element
-        except AttributeError:
-            pass
-        K = self.absolute_field('a')
-        from_K, to_K = K.structure()
-        self.__primitive_element = from_K(K.gen())
-        return self.__primitive_element
-
-    def random_element(self):
-        r"""
-        Return a random element of this number field.
-
-        EXAMPLES:
-            sage: K.<j> = NumberField(x^8+1)
-            sage: K.random_element()
-            1/2*j^7 - j^6 - 12*j^5 + 1/2*j^4 - 1/95*j^3 - 1/2*j^2 - 4
-
-            sage: K.<a,b,c> = NumberField([x^2-2,x^2-3,x^2-5])
-            sage: K.random_element()
-            ((-c + 1)*b - c + 2/3)*a - 5/2*b + 2/3*c - 1/4
-        """
-        return self(self.polynomial_quotient_ring().random_element())
-
-    def subfield(self, alpha, name=None):
-        r"""
-        Return an absolute number field K isomorphic to QQ(alpha) and
-        a map from K to self that sends the generator of K to alpha.
-
-        INPUT:
-            alpha -- an element of self, or something that coerces
-                     to an element of self.
-
-        OUTPUT:
-            K -- a number field
-            from_K -- a homomorphism from K to self that sends the
-                      generator of K to alpha.
-
-        EXAMPLES:
-            sage: K.<a> = NumberField(x^4 - 3); K
-            Number Field in a with defining polynomial x^4 - 3
-            sage: H, from_H = K.subfield(a^2, name='b')
-            sage: H
-            Number Field in b with defining polynomial x^2 - 3
-            sage: from_H(H.0)
-            a^2
-            sage: from_H
-            Ring morphism:
-              From: Number Field in b with defining polynomial x^2 - 3
-              To:   Number Field in a with defining polynomial x^4 - 3
-              Defn: b |--> a^2
-
-            sage: K.<z> = CyclotomicField(5)
-            sage: K.subfield(z-z^2-z^3+z^4)
-            (Number Field in z0 with defining polynomial x^2 - 5,
-            Ring morphism:
-            From: Number Field in z0 with defining polynomial x^2 - 5
-            To:   Cyclotomic Field of order 5 and degree 4
-            Defn: z0 |--> -2*z^3 - 2*z^2 - 1)
-
-        You can also view a number field as having a different
-        generator by just choosing the input to generate the
-        whole field; for that it is better to use
-        \code{self.change_generator}, which gives isomorphisms
-        in both directions.
-        """
-        if name is None:
-            name = self.variable_name() + '0'
-        beta = self(alpha)
-        f = beta.minpoly()
-        K = NumberField(f, names=name)
-        from_K = K.hom([beta])
-        return K, from_K
-
-    def change_generator(self, alpha, name=None):
-        r"""
-        Given the number field self, construct another isomorphic
-        number field $K$ generated by the element alpha of self, along
-        with isomorphisms from $K$ to self and from self to $K$.
-        
-        EXAMPLES:
-            sage: K.<i> = NumberField(x^2 + 1); K
-            Number Field in i with defining polynomial x^2 + 1
-            sage: L.<i> = NumberField(x^2 + 1); L
-            Number Field in i with defining polynomial x^2 + 1
-            sage: K, from_K, to_K = L.change_generator(i/2 + 3)
-            sage: K
-            Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
-            sage: from_K
-            Ring morphism:
-              From: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
-              To:   Number Field in i with defining polynomial x^2 + 1
-              Defn: i0 |--> 1/2*i + 3
-            sage: to_K
-            Ring morphism:
-              From: Number Field in i with defining polynomial x^2 + 1
-              To:   Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
-              Defn: i |--> 2*i0 - 6
-
-        We compute the image of the generator $\sqrt{-1}$ of $L$.
-            sage: to_K(L.0)
-            2*i0 - 6
-
-        Note that he image is indeed a square root of -1.
-            sage: to_K(L.0)^2
-            -1
-            sage: from_K(to_K(L.0))
-            i
-            sage: to_K(from_K(K.0))
-            i0
-        """
-        alpha = self(alpha)
-        K, from_K = self.subfield(alpha, name=name)
-        if K.degree() != self.degree():
-            raise ValueError, "alpha must generate a field of degree %s, but alpha generates a subfield of degree %s"%(self.degree(), K.degree())
-        # Now compute to_K, which is an isomorphism
-        # from self to K such that from_K(to_K(x)) == x for all x,
-        # and to_K(from_K(y)) == y.
-        # To do this, we must compute the image of self.gen()
-        # under to_K.   This means writing self.gen() as a
-        # polynomial in alpha, which is possible by the degree
-        # check above.  This latter we do by linear algebra.
-        phi = alpha.coordinates_in_terms_of_powers()
-        c = phi(self.gen())
-        to_K = self.hom([K(c)])
-        return K, from_K, to_K
-
-    def is_absolute(self):
-        """
-        Returns True if self is an absolute field.
-
-        This function will be implemented in the derived classes.
-        
-        EXAMPLES: 
-            sage: K = CyclotomicField(5)
-            sage: K.is_absolute()
-            True
-        """
-        raise NotImplementedError
-
-    def is_relative(self):
-        """
-        EXAMPLES:
-            sage: K.<a> = NumberField(x^10 - 2)
-            sage: K.is_absolute()
-            True
-            sage: K.is_relative()
-            False
-        """        
-        return not self.is_absolute()
-        
-    def absolute_field(self, names):
-        """
-        Returns self as an absolute extension over QQ. 
-
-        OUTPUT:
-            K -- this number field (since it is already absolute)
-
-        Also, \code{K.structure()} returns from_K and to_K, where
-        from_K is an isomorphism from K to self and to_K is an isomorphism
-        from self to K.
-
-        EXAMPLES: 
-            sage: K = CyclotomicField(5)
-            sage: K.absolute_field('a')
-            Number Field in a with defining polynomial x^4 + x^3 + x^2 + x + 1
-        """
-        try:
-            return self.__absolute_field[names]
-        except KeyError:
-            pass
-        except AttributeError:
-            self.__absolute_field = {}
-        K = NumberField(self.defining_polynomial(), names, cache=False)
-        K._set_structure(maps.NameChangeMap(K, self), maps.NameChangeMap(self, K))
-        self.__absolute_field[names] = K
-        return K
-
-    def is_isomorphic(self, other):
-        """
-        Return True if self is isomorphic as a number field to other.
-        
-        EXAMPLES:
-            sage: k.<a> = NumberField(x^2 + 1)
-            sage: m.<b> = NumberField(x^2 + 4)
-            sage: k.is_isomorphic(m)
-            True
-            sage: m.<b> = NumberField(x^2 + 5)
-            sage: k.is_isomorphic (m)
-            False
-
-            sage: k = NumberField(x^3 + 2, 'a')
-            sage: k.is_isomorphic(NumberField((x+1/3)^3 + 2, 'b'))
-            True
-            sage: k.is_isomorphic(NumberField(x^3 + 4, 'b'))
-            True
-            sage: k.is_isomorphic(NumberField(x^3 + 5, 'b'))
-            False            
-        """
-        if not isinstance(other, NumberField_generic):
-            raise ValueError, "other must be a generic number field."
-        t = self.pari_polynomial().nfisisom(other.pari_polynomial())
-        return t != 0
-
-    def is_totally_real(self):
-        """
-        Return True if self is totally real, and False otherwise.
-
-        Totally real means that every isomorphic embedding of self into the
-        complex numbers has image contained in the real numbers.
-
-        EXAMPLES:
-            sage: NumberField(x^2+2, 'alpha').is_totally_real()
-            False
-            sage: NumberField(x^2-2, 'alpha').is_totally_real()
-            True
-            sage: NumberField(x^4-2, 'alpha').is_totally_real()
-            False
-        """
-        return self.signature()[1] == 0
-
-    def is_totally_imaginary(self):
-        """
-        Return True if self is totally imaginary, and False otherwise.
-
-        Totally imaginary means that no isomorphic embedding of self into the
-        complex numbers has image contained in the real numbers.
-
-        EXAMPLES:
-            sage: NumberField(x^2+2, 'alpha').is_totally_imaginary()
-            True
-            sage: NumberField(x^2-2, 'alpha').is_totally_imaginary()
-            False
-            sage: NumberField(x^4-2, 'alpha').is_totally_imaginary()
-            False
-        """
-        return self.signature()[0] == 0
-
-    def complex_embeddings(self, prec=53):
-        r"""
-        Return all homomorphisms of this number field into the
-        approximate complex field with precision prec.
-
-        If prec is 53 (the default), then the complex double field is
-        used; otherwise the arbitrary precision (but slow) complex
-        field is used.  If you want 53-bit arbitrary precision then
-        do \code{self.embeddings(ComplexField(53))}.
-
-        EXAMPLES:
-            sage: k.<a> = NumberField(x^5 + x + 17)
-            sage: v = k.complex_embeddings()
-            sage: ls = [phi(k.0^2) for phi in v] ; ls # random order
-            [2.97572074038...,
-             -2.40889943716 + 1.90254105304*I,
-             -2.40889943716 - 1.90254105304*I,
-             0.921039066973 + 3.07553311885*I,
-             0.921039066973 - 3.07553311885*I]
-            sage: K.<a> = NumberField(x^3 + 2)
-            sage: ls = K.complex_embeddings() ; ls # random order
-            [
-            Ring morphism:
-              From: Number Field in a with defining polynomial x^3 + 2
-              To:   Complex Double Field
-              Defn: a |--> -1.25992104989...,
-            Ring morphism:
-              From: Number Field in a with defining polynomial x^3 + 2
-              To:   Complex Double Field
-              Defn: a |--> 0.629960524947 - 1.09112363597*I,
-            Ring morphism:
-              From: Number Field in a with defining polynomial x^3 + 2
-              To:   Complex Double Field
-              Defn: a |--> 0.629960524947 + 1.09112363597*I
-            ]
-        """
-        if prec == 53:
-            CC = sage.rings.complex_double.CDF
-        else:
-            CC = sage.rings.complex_field.ComplexField(prec)
-        return self.embeddings(CC)
-
-    def real_embeddings(self, prec=53):
-        r"""
-        Return all homomorphisms of this number field into the
-        approximate real field with precision prec.
-
-        If prec is 53 (the default), then the real double field is
-        used; otherwise the arbitrary precision (but slow) real field
-        is used.
-
-        EXAMPLES:
-            sage: K.<a> = NumberField(x^3 + 2)
-            sage: K.real_embeddings()
-            [
-            Ring morphism:
-              From: Number Field in a with defining polynomial x^3 + 2
-              To:   Real Double Field
-              Defn: a |--> -1.25992104989
-            ]
-             sage: K.real_embeddings(16)
-             [
-             Ring morphism:
-               From: Number Field in a with defining polynomial x^3 + 2
-               To:   Real Field with 16 bits of precision
-               Defn: a |--> -1.260
-             ]
-            sage: K.real_embeddings(100)
-            [
-            Ring morphism:
-              From: Number Field in a with defining polynomial x^3 + 2
-              To:   Real Field with 100 bits of precision
-              Defn: a |--> -1.2599210498948731647672106073
-            ]
-        """
-        if prec == 53:
-            K = sage.rings.real_double.RDF
-        else:
-            K = sage.rings.real_mpfr.RealField(prec)
-        return self.embeddings(K)
-
-    def specified_complex_embedding(self):
-        r"""
-        Returns the embedding of this field into the complex numbers 
-        has been specified. 
-        
-        Fields created with the \code{QuadraticField} or \code{CyclotomicField}
-        constructors come with an implicit embedding. To get one of these 
-        fields without the embedding, use the generic \code{NumberField} 
-        constructor.
-        
-        EXAMPLES: 
-            sage: QuadraticField(-1, 'I').specified_complex_embedding()
-            Generic morphism:
-              From: Number Field in I with defining polynomial x^2 + 1
-              To:   Complex Lazy Field
-              Defn: I -> 1*I
-              
-            sage: QuadraticField(3, 'a').specified_complex_embedding()
-            Generic morphism:
-              From: Number Field in a with defining polynomial x^2 - 3
-              To:   Real Lazy Field
-              Defn: a -> 1.732050807568878?
-              
-            sage: CyclotomicField(13).specified_complex_embedding()
-            Generic morphism:
-              From: Cyclotomic Field of order 13 and degree 12
-              To:   Complex Lazy Field
-              Defn: zeta13 -> 0.885456025653210? + 0.464723172043769?*I
-              
-        Most fields don't implicitly have embeddings unless explicitly specified:
-            sage: NumberField(x^2-2, 'a').specified_complex_embedding() is None
-            True
-            sage: NumberField(x^3-x+5, 'a').specified_complex_embedding() is None
-            True
-            sage: NumberField(x^3-x+5, 'a', embedding=2).specified_complex_embedding()
-            Generic morphism:
-              From: Number Field in a with defining polynomial x^3 - x + 5
-              To:   Real Lazy Field
-              Defn: a -> -1.904160859134921?
-            sage: NumberField(x^3-x+5, 'a', embedding=CDF.0).specified_complex_embedding()
-            Generic morphism:
-              From: Number Field in a with defining polynomial x^3 - x + 5
-              To:   Complex Lazy Field
-              Defn: a -> 0.952080429567461? + 1.311248044077123?*I
-              
-        This function only returns complex embeddings:
-            sage: K.<a> = NumberField(x^2-2, embedding=Qp(7)(2).sqrt())
-            sage: K.specified_complex_embedding() is None
-            True
-            sage: K.gen_embedding()
-            3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20)
-            sage: K.coerce_embedding()
-            Generic morphism:
-              From: Number Field in a with defining polynomial x^2 - 2
-              To:   7-adic Field with capped relative precision 20
-              Defn: a -> 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20)
-        """
-        embedding = self.coerce_embedding()
-        if embedding is not None:
-            from sage.rings.real_mpfr import mpfr_prec_min
-            from sage.rings.complex_field import ComplexField
-            if ComplexField(mpfr_prec_min()).has_coerce_map_from(embedding.codomain()):
-                return embedding
-                
-    def gen_embedding(self):
-        """
-        If an embedding has been specified, return the image of the generator 
-        under that embedding. Otherwise return None. 
-        
-        EXAMPLES:
-            sage: QuadraticField(-7, 'a').gen_embedding()
-            2.645751311064591?*I
-            sage: NumberField(x^2+7, 'a').gen_embedding() # None
-        """
-        embedding = self.coerce_embedding()
-        if embedding is None:
-            return None
-        else:
-            return embedding(self.gen())
-
-    def latex_variable_name(self, name=None):
-        """
-        Return the latex representation of the variable name for
-        this number field.
-
-        EXAMPLES:
-            sage: NumberField(x^2 + 3, 'a').latex_variable_name()
-            'a'
-            sage: NumberField(x^3 + 3, 'theta3').latex_variable_name()
-            '\\theta_{3}'
-            sage: CyclotomicField(5).latex_variable_name()
-            '\\zeta_{5}'
-        """
-        if name is None:
-            return self.__latex_variable_name
-        else:
-            self.__latex_variable_name = name
-
-    def _repr_(self):
-        """
-        Return string representation of this number field.
-
-        EXAMPLES:
-            sage: k.<a> = NumberField(x^13 - (2/3)*x + 3)
-            sage: k._repr_()
-            'Number Field in a with defining polynomial x^13 - 2/3*x + 3'        
-        """
-        return "Number Field in %s with defining polynomial %s"%(
-                   self.variable_name(), self.polynomial())
-
-    def _latex_(self):
-        r"""
-        Return latex representation of this number field.  This is viewed
-        as a polynomial quotient ring over a field.
-
-        EXAMPLES:
-            sage: k.<a> = NumberField(x^13 - (2/3)*x + 3)
-            sage: k._latex_()
-            '\\mathbf{Q}[a]/(a^{13} - \\frac{2}{3} a + 3)'
-            sage: latex(k)
-            \mathbf{Q}[a]/(a^{13} - \frac{2}{3} a + 3)
-
-        Numbered variables are often correctly typeset:
-            sage: k.<theta25> = NumberField(x^25+x+1)
-            sage: print k._latex_()
-            \mathbf{Q}[\theta_{25}]/(\theta_{25}^{25} + \theta_{25} + 1)            
-        """
-        return "%s[%s]/(%s)"%(latex(QQ), self.latex_variable_name(),
-                              self.polynomial()._latex_(self.latex_variable_name()))
-
     def _element_constructor_(self, x):
-        """
-        Coerce x into this number field.
+        r"""
+        Make x into an element of this relative number field, possibly not canonically.
 
         EXAMPLES:
             sage: K.<a> = NumberField(x^3 + 17)
@@ -1389,13 +831,15 @@
             return self._coerce_from_other_number_field(x)
         elif isinstance(x,str):
             return self._coerce_from_str(x)
-        elif isinstance(x, (sage.modules.vector_integer_dense.Vector_integer_dense,
-                            sage.modules.vector_rational_dense.Vector_rational_dense)):
+        elif isinstance(x, (tuple, list)) or \
+                (isinstance(x, sage.modules.free_module_element.FreeModuleElement) and
+                 self.base_ring().has_coerce_map_from(x.parent().base_ring())):
             if len(x) != self.degree():
-                raise ValueError, "vector must be of length equal to the degree of this number field"
+                raise ValueError, "Length must be equal to the degree of this number field"
             return sum([ x[i]*self.gen(0)**i for i in range(self.degree()) ])
         return self._coerce_non_number_field_element_in(x)
 
+
     def _coerce_from_str(self, x):
         """
         Coerce a string representation of an element of this
@@ -1416,162 +860,571 @@
         """
         # provide string coercion, as
         # for finite fields
-        w = sage.misc.all.sage_eval(x,locals=\
-                                  {self.variable_name():self.gen()})
+        w = sage.misc.all.sage_eval(x,locals=self.gens_dict())
         if not (is_Element(w) and w.parent() is self):
             return self(w)
         else:
-            return w        
-
-    def _coerce_from_other_number_field(self, x):
-        """
-        Coerce a number field element x into this number field.
-
-        In most cases this currently doesn't work (since it is
-        barely implemented) -- it only works for constants.
-
-        INPUT:
-            x -- an element of some number field
+            return w
+
+    def _Hom_(self, codomain, cat=None):
+        """
+        Return homset of homomorphisms from self to the number field codomain.
+
+        The cat option is currently ignored.
+
+        EXAMPLES:
+        This function is implicitly called by the Hom method or function.
+            sage: K.<i> = NumberField(x^2 + 1); K
+            Number Field in i with defining polynomial x^2 + 1
+            sage: K.Hom(K)
+            Automorphism group of Number Field in i with defining polynomial x^2 + 1
+            sage: Hom(K, QuadraticField(-1, 'b'))
+            Set of field embeddings from Number Field in i with defining polynomial x^2 + 1 to Number Field in b with defining polynomial x^2 + 1
+        """
+        import morphism
+        return morphism.NumberFieldHomset(self, codomain)
+
+    def _set_structure(self, from_self, to_self, unsafe_force_change=False):
+        """
+        Internal function to set the structure fields of this number field.
+        """
+        # Note -- never call this on a cached number field, since
+        # that could eventually lead to problems.
+        if unsafe_force_change:
+            self.__from_self = from_self
+            self.__to_self = to_self
+            return
+        try:
+            self.__from_self
+        except AttributeError:
+            self.__from_self = from_self
+            self.__to_self = to_self
+        else:
+            raise ValueError, "number field structure is immutable."
+
+    def structure(self):
+        """
+        Return fixed isomorphism or embedding structure on self.
+
+        This is used to record various isomorphisms or embeddings
+        that arise naturally in other constructions.
+
+        EXAMPLES:
+            sage: K.<z> = NumberField(x^2 + 3)
+            sage: L.<a> = K.absolute_field(); L
+            Number Field in a with defining polynomial x^2 + 3
+            sage: L.structure()
+            (Isomorphism given by variable name change map:
+              From: Number Field in a with defining polynomial x^2 + 3
+              To:   Number Field in z with defining polynomial x^2 + 3,
+             Isomorphism given by variable name change map:
+              From: Number Field in z with defining polynomial x^2 + 3
+              To:   Number Field in a with defining polynomial x^2 + 3)
+        """
+        try:
+            if self.__to_self is not None:
+                return self.__from_self, self.__to_self
+            else:
+                return self.__from_self, self.__to_self
+        except AttributeError:
+            f = self.hom(self)
+            self._set_structure(f,f)
+            return f, f
+    
+    def completion(self, p, prec, extras={}):
+        """
+        Returns the completion of self at $p$ to the specified precision. 
+        Only implemented at archimedean places, and then only if an embedding
+        has been fixed.  
+        
+        EXAMPLES: 
+            sage: K.<a> = QuadraticField(2)
+            sage: K.completion(infinity, 100)
+            Real Field with 100 bits of precision
+            sage: K.<zeta> = CyclotomicField(12)
+            sage: K.completion(infinity, 53, extras={'type': 'RDF'})
+            Complex Double Field
+            sage: zeta + 1.5                            # implicit test
+            2.36602540378444 + 0.500000000000000*I
+        """
+        if p == infinity.infinity:
+            gen_image = self.gen_embedding()
+            if gen_image is not None:
+                if gen_image in RDF:
+                    return QQ.completion(p, prec, extras)
+                elif gen_image in CDF:
+                    return QQ.completion(p, prec, extras).algebraic_closure()
+            raise ValueError, "No embedding into the complex numbers has been specified."
+        else:
+            raise NotImplementedError
+
+    def primitive_element(self):
+        r"""
+        Return a primitive element for this field, i.e., an element
+        that generates it over $\QQ$.
 
         EXAMPLES:
             sage: K.<a> = NumberField(x^3 + 2)
-            sage: L.<b> = NumberField(x^2 + 1)
-            sage: K._coerce_from_other_number_field(L(2/3))
-            2/3        
-        """
-        f = x.polynomial()
-        if f.degree() <= 0:
-            return self._element_class(self, f[0])
-        # todo: more general coercion if embedding have been asserted
-        raise TypeError, "Cannot coerce element into this number field"
-    
-    def _coerce_non_number_field_element_in(self, x):
-        """
-        Coerce a non-number field element x into this number field.
-
-        INPUT:
-            x -- a non number field element x, e.g., a list, integer, 
-            rational, or polynomial.
-
-        EXAMPLES:
-            sage: K.<a> = NumberField(x^3 + 2/3)
-            sage: K._coerce_non_number_field_element_in(-7/8)
-            -7/8
-            sage: K._coerce_non_number_field_element_in([1,2,3])
-            3*a^2 + 2*a + 1
-
-        The list is just turned into a polynomial in the generator.
-            sage: K._coerce_non_number_field_element_in([0,0,0,1,1])
-            -2/3*a - 2/3
-
-        Any polynomial whose coefficients can be coerced to rationals will
-        coerce, e.g., this one in characteristic 7.
-            sage: f = GF(7)['y']([1,2,3]); f
-            3*y^2 + 2*y + 1
-            sage: K._coerce_non_number_field_element_in(f)
-            3*a^2 + 2*a + 1
- 
-        But not this one over a field of order 27.
-            sage: F27.<g> = GF(27)
-            sage: f = F27['z']([g^2, 2*g, 1]); f
-            z^2 + 2*g*z + g^2
-            sage: K._coerce_non_number_field_element_in(f)
-            Traceback (most recent call last):
-            ...
-            TypeError: <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
-
-        One can also coerce an element of the polynomial quotient ring
-        that's isomorphic to the number field: 
-            sage: K.<a> = NumberField(x^3 + 17)
-            sage: b = K.polynomial_quotient_ring().random_element()
-            sage: K(b)
-            -1/2*a^2 - 4
-        """
-        if isinstance(x, (int, long, rational.Rational,
-                              integer.Integer, pari_gen,
-                              list)):
-            return self._element_class(self, x)
-
-        if isinstance(x, sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement)\
-               and (x in self.polynomial_quotient_ring()):
-            y = self.polynomial_ring().gen()
-            return x.lift().subs({y:self.gen()})
-
-        try:
-            if isinstance(x, polynomial_element.Polynomial):
-                return self._element_class(self, x)
-            
-            return self._element_class(self, x._rational_())
-        except (TypeError, AttributeError), msg:
-            pass
-        raise TypeError, type(x)
-
-    def _coerce_map_from_(self, R):
-        """
-        Canonical coercion of x into self.
-
-        Currently integers, rationals, and this field itself coerce
-        canonical into this field. 
-
-        EXAMPLES:
-            sage: S.<y> = NumberField(x^3 + x + 1)
-            sage: S.coerce(int(4))
-            4
-            sage: S.coerce(long(7))
-            7
-            sage: S.coerce(-Integer(2))
-            -2
-            sage: z = S.coerce(-7/8); z, type(z)
-            (-7/8, <type 'sage.rings.number_field.number_field_element.NumberFieldElement_absolute'>)
-            sage: S.coerce(y) is y
-            True
-
-        Fields with embeddings into an ambient field coerce natrually.
-            sage: CyclotomicField(15).coerce(CyclotomicField(5).0 - 17/3)
-            zeta15^3 - 17/3
-            sage: K.<a> = CyclotomicField(16)
-            sage: K(CyclotomicField(4).0)
-            a^4
-            sage: QuadraticField(-3, 'a').coerce_map_from(CyclotomicField(3))
-            Generic morphism:
-              From: Cyclotomic Field of order 3 and degree 2
-              To:   Number Field in a with defining polynomial x^2 + 3
-              Defn: zeta3 -> 1/2*a - 1/2
-
-        There are situations for which one might imagine canonical
-        coercion could make sense (at least after fixing choices), but
-        which aren't yet implemented:
-            sage: K.<a> = QuadraticField(2)
-            sage: K.coerce(sqrt(2))
-            Traceback (most recent call last):
-            ...
-            TypeError: no cannonical coercion from Symbolic Ring to Number Field in a with defining polynomial x^2 - 2
-
-        TESTS:
-            sage: K.<a> = NumberField(polygen(QQ)^3-2)
-            sage: type(K.coerce_map_from(QQ))
-            <type 'sage.structure.coerce_maps.DefaultConvertMap_unique'>
-            
-        Make sure we still get our optimized morphisms for special fields:
-            sage: K.<a> = NumberField(polygen(QQ)^2-2)
-            sage: type(K.coerce_map_from(QQ))
-            <type 'sage.rings.number_field.number_field_element_quadratic.Q_to_quadratic_field_element'>
-        """
-        if R in [int, long, ZZ, QQ, self.base()]:
-            return self._generic_convert_map(R)
-        from sage.rings.number_field.order import is_NumberFieldOrder
-        if is_NumberFieldOrder(R) and R.number_field().has_coerce_map_from(self):
-            return self._generic_convert_map(R)
-        if is_NumberField(R) and R != QQ:
-            if R.coerce_embedding() is not None:
-                if self.coerce_embedding() is not None:
-                    try:
-                        from sage.categories.pushout import pushout
-                        ambient_field = pushout(R.coerce_embedding().codomain(), self.coerce_embedding().codomain())
-                        if ambient_field is not None:
-                            return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self)
-                    except (TypeError, ValueError):
-                        pass
+            sage: K.primitive_element()
+            a
+            sage: K.<a,b,c> = NumberField([x^2-2,x^2-3,x^2-5])
+            sage: K.primitive_element()
+            a - b + c
+            sage: alpha = K.primitive_element(); alpha
+            a - b + c
+            sage: alpha.minpoly()
+            x^2 + (2*b - 2*c)*x - 2*c*b + 6
+            sage: alpha.absolute_minpoly()
+            x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576
+        """
+        try:
+            return self.__primitive_element
+        except AttributeError:
+            pass
+        K = self.absolute_field('a')
+        from_K, to_K = K.structure()
+        self.__primitive_element = from_K(K.gen())
+        return self.__primitive_element
+
+    def random_element(self):
+        r"""
+        Return a random element of this number field.
+
+        EXAMPLES:
+            sage: K.<j> = NumberField(x^8+1)
+            sage: K.random_element()
+            1/2*j^7 - j^6 - 12*j^5 + 1/2*j^4 - 1/95*j^3 - 1/2*j^2 - 4
+
+            sage: K.<a,b,c> = NumberField([x^2-2,x^2-3,x^2-5])
+            sage: K.random_element()
+            ((-c + 1)*b - c + 2/3)*a - 5/2*b + 2/3*c - 1/4
+        """
+        return self(self.polynomial_quotient_ring().random_element())
+
+    def subfield(self, alpha, name=None):
+        r"""
+        Return an absolute number field K isomorphic to QQ(alpha) and
+        a map from K to self that sends the generator of K to alpha.
+
+        INPUT:
+            alpha -- an element of self, or something that coerces
+                     to an element of self.
+
+        OUTPUT:
+            K -- a number field
+            from_K -- a homomorphism from K to self that sends the
+                      generator of K to alpha.
+
+        EXAMPLES:
+            sage: K.<a> = NumberField(x^4 - 3); K
+            Number Field in a with defining polynomial x^4 - 3
+            sage: H, from_H = K.subfield(a^2, name='b')
+            sage: H
+            Number Field in b with defining polynomial x^2 - 3
+            sage: from_H(H.0)
+            a^2
+            sage: from_H
+            Ring morphism:
+              From: Number Field in b with defining polynomial x^2 - 3
+              To:   Number Field in a with defining polynomial x^4 - 3
+              Defn: b |--> a^2
+
+            sage: K.<z> = CyclotomicField(5)
+            sage: K.subfield(z-z^2-z^3+z^4)
+            (Number Field in z0 with defining polynomial x^2 - 5,
+            Ring morphism:
+            From: Number Field in z0 with defining polynomial x^2 - 5
+            To:   Cyclotomic Field of order 5 and degree 4
+            Defn: z0 |--> -2*z^3 - 2*z^2 - 1)
+
+        You can also view a number field as having a different
+        generator by just choosing the input to generate the
+        whole field; for that it is better to use
+        \code{self.change_generator}, which gives isomorphisms
+        in both directions.
+        """
+        if name is None:
+            name = self.variable_name() + '0'
+        beta = self(alpha)
+        f = beta.minpoly()
+        K = NumberField(f, names=name)
+        from_K = K.hom([beta])
+        return K, from_K
+
+    def change_generator(self, alpha, name=None):
+        r"""
+        Given the number field self, construct another isomorphic
+        number field $K$ generated by the element alpha of self, along
+        with isomorphisms from $K$ to self and from self to $K$.
+        
+        EXAMPLES:
+            sage: K.<i> = NumberField(x^2 + 1); K
+            Number Field in i with defining polynomial x^2 + 1
+            sage: L.<i> = NumberField(x^2 + 1); L
+            Number Field in i with defining polynomial x^2 + 1
+            sage: K, from_K, to_K = L.change_generator(i/2 + 3)
+            sage: K
+            Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
+            sage: from_K
+            Ring morphism:
+              From: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
+              To:   Number Field in i with defining polynomial x^2 + 1
+              Defn: i0 |--> 1/2*i + 3
+            sage: to_K
+            Ring morphism:
+              From: Number Field in i with defining polynomial x^2 + 1
+              To:   Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
+              Defn: i |--> 2*i0 - 6
+
+        We compute the image of the generator $\sqrt{-1}$ of $L$.
+            sage: to_K(L.0)
+            2*i0 - 6
+
+        Note that he image is indeed a square root of -1.
+            sage: to_K(L.0)^2
+            -1
+            sage: from_K(to_K(L.0))
+            i
+            sage: to_K(from_K(K.0))
+            i0
+        """
+        alpha = self(alpha)
+        K, from_K = self.subfield(alpha, name=name)
+        if K.degree() != self.degree():
+            raise ValueError, "alpha must generate a field of degree %s, but alpha generates a subfield of degree %s"%(self.degree(), K.degree())
+        # Now compute to_K, which is an isomorphism
+        # from self to K such that from_K(to_K(x)) == x for all x,
+        # and to_K(from_K(y)) == y.
+        # To do this, we must compute the image of self.gen()
+        # under to_K.   This means writing self.gen() as a
+        # polynomial in alpha, which is possible by the degree
+        # check above.  This latter we do by linear algebra.
+        phi = alpha.coordinates_in_terms_of_powers()
+        c = phi(self.gen())
+        to_K = self.hom([K(c)])
+        return K, from_K, to_K
+
+    def is_absolute(self):
+        """
+        Returns True if self is an absolute field.
+
+        This function will be implemented in the derived classes.
+        
+        EXAMPLES: 
+            sage: K = CyclotomicField(5)
+            sage: K.is_absolute()
+            True
+        """
+        raise NotImplementedError
+
+    def is_relative(self):
+        """
+        EXAMPLES:
+            sage: K.<a> = NumberField(x^10 - 2)
+            sage: K.is_absolute()
+            True
+            sage: K.is_relative()
+            False
+        """        
+        return not self.is_absolute()
+        
+    def absolute_field(self, names):
+        """
+        Returns self as an absolute extension over QQ. 
+
+        OUTPUT:
+            K -- this number field (since it is already absolute)
+
+        Also, \code{K.structure()} returns from_K and to_K, where
+        from_K is an isomorphism from K to self and to_K is an isomorphism
+        from self to K.
+
+        EXAMPLES: 
+            sage: K = CyclotomicField(5)
+            sage: K.absolute_field('a')
+            Number Field in a with defining polynomial x^4 + x^3 + x^2 + x + 1
+        """
+        try:
+            return self.__absolute_field[names]
+        except KeyError:
+            pass
+        except AttributeError:
+            self.__absolute_field = {}
+        K = NumberField(self.defining_polynomial(), names, cache=False)
+        K._set_structure(maps.NameChangeMap(K, self), maps.NameChangeMap(self, K))
+        self.__absolute_field[names] = K
+        return K
+
+    def is_isomorphic(self, other):
+        """
+        Return True if self is isomorphic as a number field to other.
+        
+        EXAMPLES:
+            sage: k.<a> = NumberField(x^2 + 1)
+            sage: m.<b> = NumberField(x^2 + 4)
+            sage: k.is_isomorphic(m)
+            True
+            sage: m.<b> = NumberField(x^2 + 5)
+            sage: k.is_isomorphic (m)
+            False
+
+            sage: k = NumberField(x^3 + 2, 'a')
+            sage: k.is_isomorphic(NumberField((x+1/3)^3 + 2, 'b'))
+            True
+            sage: k.is_isomorphic(NumberField(x^3 + 4, 'b'))
+            True
+            sage: k.is_isomorphic(NumberField(x^3 + 5, 'b'))
+            False            
+        """
+        if not isinstance(other, NumberField_generic):
+            raise ValueError, "other must be a generic number field."
+        t = self.pari_polynomial().nfisisom(other.pari_polynomial())
+        return t != 0
+
+    def is_totally_real(self):
+        """
+        Return True if self is totally real, and False otherwise.
+
+        Totally real means that every isomorphic embedding of self into the
+        complex numbers has image contained in the real numbers.
+
+        EXAMPLES:
+            sage: NumberField(x^2+2, 'alpha').is_totally_real()
+            False
+            sage: NumberField(x^2-2, 'alpha').is_totally_real()
+            True
+            sage: NumberField(x^4-2, 'alpha').is_totally_real()
+            False
+        """
+        return self.signature()[1] == 0
+
+    def is_totally_imaginary(self):
+        """
+        Return True if self is totally imaginary, and False otherwise.
+
+        Totally imaginary means that no isomorphic embedding of self into the
+        complex numbers has image contained in the real numbers.
+
+        EXAMPLES:
+            sage: NumberField(x^2+2, 'alpha').is_totally_imaginary()
+            True
+            sage: NumberField(x^2-2, 'alpha').is_totally_imaginary()
+            False
+            sage: NumberField(x^4-2, 'alpha').is_totally_imaginary()
+            False
+        """
+        return self.signature()[0] == 0
+
+    def complex_embeddings(self, prec=53):
+        r"""
+        Return all homomorphisms of this number field into the
+        approximate complex field with precision prec.
+
+        If prec is 53 (the default), then the complex double field is
+        used; otherwise the arbitrary precision (but slow) complex
+        field is used.  If you want 53-bit arbitrary precision then
+        do \code{self.embeddings(ComplexField(53))}.
+
+        EXAMPLES:
+            sage: k.<a> = NumberField(x^5 + x + 17)
+            sage: v = k.complex_embeddings()
+            sage: ls = [phi(k.0^2) for phi in v] ; ls # random order
+            [2.97572074038...,
+             -2.40889943716 + 1.90254105304*I,
+             -2.40889943716 - 1.90254105304*I,
+             0.921039066973 + 3.07553311885*I,
+             0.921039066973 - 3.07553311885*I]
+            sage: K.<a> = NumberField(x^3 + 2)
+            sage: ls = K.complex_embeddings() ; ls # random order
+            [
+            Ring morphism:
+              From: Number Field in a with defining polynomial x^3 + 2
+              To:   Complex Double Field
+              Defn: a |--> -1.25992104989...,
+            Ring morphism:
+              From: Number Field in a with defining polynomial x^3 + 2
+              To:   Complex Double Field
+              Defn: a |--> 0.629960524947 - 1.09112363597*I,
+            Ring morphism:
+              From: Number Field in a with defining polynomial x^3 + 2
+              To:   Complex Double Field
+              Defn: a |--> 0.629960524947 + 1.09112363597*I
+            ]
+        """
+        if prec == 53:
+            CC = sage.rings.complex_double.CDF
+        else:
+            CC = sage.rings.complex_field.ComplexField(prec)
+        return self.embeddings(CC)
+
+    def real_embeddings(self, prec=53):
+        r"""
+        Return all homomorphisms of this number field into the
+        approximate real field with precision prec.
+
+        If prec is 53 (the default), then the real double field is
+        used; otherwise the arbitrary precision (but slow) real field
+        is used.
+
+        EXAMPLES:
+            sage: K.<a> = NumberField(x^3 + 2)
+            sage: K.real_embeddings()
+            [
+            Ring morphism:
+              From: Number Field in a with defining polynomial x^3 + 2
+              To:   Real Double Field
+              Defn: a |--> -1.25992104989
+            ]
+             sage: K.real_embeddings(16)
+             [
+             Ring morphism:
+               From: Number Field in a with defining polynomial x^3 + 2
+               To:   Real Field with 16 bits of precision
+               Defn: a |--> -1.260
+             ]
+            sage: K.real_embeddings(100)
+            [
+            Ring morphism:
+              From: Number Field in a with defining polynomial x^3 + 2
+              To:   Real Field with 100 bits of precision
+              Defn: a |--> -1.2599210498948731647672106073
+            ]
+        """
+        if prec == 53:
+            K = sage.rings.real_double.RDF
+        else:
+            K = sage.rings.real_mpfr.RealField(prec)
+        return self.embeddings(K)
+
+    def specified_complex_embedding(self):
+        r"""
+        Returns the embedding of this field into the complex numbers 
+        has been specified. 
+        
+        Fields created with the \code{QuadraticField} or \code{CyclotomicField}
+        constructors come with an implicit embedding. To get one of these 
+        fields without the embedding, use the generic \code{NumberField} 
+        constructor.
+        
+        EXAMPLES: 
+            sage: QuadraticField(-1, 'I').specified_complex_embedding()
+            Generic morphism:
+              From: Number Field in I with defining polynomial x^2 + 1
+              To:   Complex Lazy Field
+              Defn: I -> 1*I
+              
+            sage: QuadraticField(3, 'a').specified_complex_embedding()
+            Generic morphism:
+              From: Number Field in a with defining polynomial x^2 - 3
+              To:   Real Lazy Field
+              Defn: a -> 1.732050807568878?
+              
+            sage: CyclotomicField(13).specified_complex_embedding()
+            Generic morphism:
+              From: Cyclotomic Field of order 13 and degree 12
+              To:   Complex Lazy Field
+              Defn: zeta13 -> 0.885456025653210? + 0.464723172043769?*I
+              
+        Most fields don't implicitly have embeddings unless explicitly specified:
+            sage: NumberField(x^2-2, 'a').specified_complex_embedding() is None
+            True
+            sage: NumberField(x^3-x+5, 'a').specified_complex_embedding() is None
+            True
+            sage: NumberField(x^3-x+5, 'a', embedding=2).specified_complex_embedding()
+            Generic morphism:
+              From: Number Field in a with defining polynomial x^3 - x + 5
+              To:   Real Lazy Field
+              Defn: a -> -1.904160859134921?
+            sage: NumberField(x^3-x+5, 'a', embedding=CDF.0).specified_complex_embedding()
+            Generic morphism:
+              From: Number Field in a with defining polynomial x^3 - x + 5
+              To:   Complex Lazy Field
+              Defn: a -> 0.952080429567461? + 1.311248044077123?*I
+              
+        This function only returns complex embeddings:
+            sage: K.<a> = NumberField(x^2-2, embedding=Qp(7)(2).sqrt())
+            sage: K.specified_complex_embedding() is None
+            True
+            sage: K.gen_embedding()
+            3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20)
+            sage: K.coerce_embedding()
+            Generic morphism:
+              From: Number Field in a with defining polynomial x^2 - 2
+              To:   7-adic Field with capped relative precision 20
+              Defn: a -> 3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8 + 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17 + 4*7^18 + 6*7^19 + O(7^20)
+        """
+        embedding = self.coerce_embedding()
+        if embedding is not None:
+            from sage.rings.real_mpfr import mpfr_prec_min
+            from sage.rings.complex_field import ComplexField
+            if ComplexField(mpfr_prec_min()).has_coerce_map_from(embedding.codomain()):
+                return embedding
+                
+    def gen_embedding(self):
+        """
+        If an embedding has been specified, return the image of the generator 
+        under that embedding. Otherwise return None. 
+        
+        EXAMPLES:
+            sage: QuadraticField(-7, 'a').gen_embedding()
+            2.645751311064591?*I
+            sage: NumberField(x^2+7, 'a').gen_embedding() # None
+        """
+        embedding = self.coerce_embedding()
+        if embedding is None:
+            return None
+        else:
+            return embedding(self.gen())
+
+    def latex_variable_name(self, name=None):
+        """
+        Return the latex representation of the variable name for
+        this number field.
+
+        EXAMPLES:
+            sage: NumberField(x^2 + 3, 'a').latex_variable_name()
+            'a'
+            sage: NumberField(x^3 + 3, 'theta3').latex_variable_name()
+            '\\theta_{3}'
+            sage: CyclotomicField(5).latex_variable_name()
+            '\\zeta_{5}'
+        """
+        if name is None:
+            return self.__latex_variable_name
+        else:
+            self.__latex_variable_name = name
+
+    def _repr_(self):
+        """
+        Return string representation of this number field.
+
+        EXAMPLES:
+            sage: k.<a> = NumberField(x^13 - (2/3)*x + 3)
+            sage: k._repr_()
+            'Number Field in a with defining polynomial x^13 - 2/3*x + 3'        
+        """
+        return "Number Field in %s with defining polynomial %s"%(
+                   self.variable_name(), self.polynomial())
+
+    def _latex_(self):
+        r"""
+        Return latex representation of this number field.  This is viewed
+        as a polynomial quotient ring over a field.
+
+        EXAMPLES:
+            sage: k.<a> = NumberField(x^13 - (2/3)*x + 3)
+            sage: k._latex_()
+            '\\mathbf{Q}[a]/(a^{13} - \\frac{2}{3} a + 3)'
+            sage: latex(k)
+            \mathbf{Q}[a]/(a^{13} - \frac{2}{3} a + 3)
+
+        Numbered variables are often correctly typeset:
+            sage: k.<theta25> = NumberField(x^25+x+1)
+            sage: print k._latex_()
+            \mathbf{Q}[\theta_{25}]/(\theta_{25}^{25} + \theta_{25} + 1)            
+        """
+        return "%s[%s]/(%s)"%(latex(QQ), self.latex_variable_name(),
+                              self.polynomial()._latex_(self.latex_variable_name()))
 
     def category(self):
         """
@@ -2875,7 +2728,7 @@
                 B = f.nfbasis(p = m)
 
             R = self.polynomial().parent()
-            basis = [self(R(g).list()) for g in B]
+            basis = [ self(R(g)) for g in B]
             self._integral_basis_dict[v] = basis
             return basis
 
@@ -3686,6 +3539,180 @@
         self._zero_element = self(0)
         self._one_element =  self(1)
 
+    def _coerce_from_other_number_field(self, x):
+        """
+        Coerce a number field element x into this number field.
+
+        In most cases this currently doesn't work (since it is
+        barely implemented) -- it only works for constants.
+
+        INPUT:
+            x -- an element of some number field
+
+        EXAMPLES:
+            sage: K.<a> = NumberField(x^3 + 2)
+            sage: L.<b> = NumberField(x^2 + 1)
+            sage: K._coerce_from_other_number_field(L(2/3))
+            2/3        
+        """
+        f = x.polynomial()
+        if f.degree() <= 0:
+            return self._element_class(self, f[0])
+        # todo: more general coercion if embedding have been asserted
+        raise TypeError, "Cannot coerce element into this number field"
+    
+    def _coerce_non_number_field_element_in(self, x):
+        """
+        Coerce a non-number field element x into this number field.
+
+        INPUT:
+            x -- a non number field element x, e.g., a list, integer, 
+            rational, or polynomial.
+
+        EXAMPLES:
+            sage: K.<a> = NumberField(x^3 + 2/3)
+            sage: K._coerce_non_number_field_element_in(-7/8)
+            -7/8
+            sage: K._coerce_non_number_field_element_in([1,2,3])
+            3*a^2 + 2*a + 1
+
+        The list is just turned into a polynomial in the generator.
+            sage: K._coerce_non_number_field_element_in([0,0,0,1,1])
+            -2/3*a - 2/3
+
+        Any polynomial whose coefficients can be coerced to rationals will
+        coerce, e.g., this one in characteristic 7.
+            sage: f = GF(7)['y']([1,2,3]); f
+            3*y^2 + 2*y + 1
+            sage: K._coerce_non_number_field_element_in(f)
+            3*a^2 + 2*a + 1
+ 
+        But not this one over a field of order 27.
+            sage: F27.<g> = GF(27)
+            sage: f = F27['z']([g^2, 2*g, 1]); f
+            z^2 + 2*g*z + g^2
+            sage: K._coerce_non_number_field_element_in(f)
+            Traceback (most recent call last):
+            ...
+            TypeError: <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
+
+        One can also coerce an element of the polynomial quotient ring
+        that's isomorphic to the number field: 
+            sage: K.<a> = NumberField(x^3 + 17)
+            sage: b = K.polynomial_quotient_ring().random_element()
+            sage: K(b)
+            -1/2*a^2 - 4
+        """
+        if isinstance(x, (int, long, rational.Rational,
+                              integer.Integer, pari_gen,
+                              list)):
+            return self._element_class(self, x)
+
+        if isinstance(x, sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement)\
+               and (x in self.polynomial_quotient_ring()):
+            y = self.polynomial_ring().gen()
+            return x.lift().subs({y:self.gen()})
+
+        try:
+            if isinstance(x, polynomial_element.Polynomial):
+                return self._element_class(self, x)
+            
+            return self._element_class(self, x._rational_())
+        except (TypeError, AttributeError), msg:
+            pass
+        raise TypeError, type(x)
+
+    def _coerce_from_str(self, x):
+        r"""
+        Coerce a string representation of an element of this
+        number field into this number field.
+
+        INPUT:
+            x -- string
+
+        EXAMPLES:
+            sage: k.<theta25> = NumberField(x^3+(2/3)*x+1)
+            sage: k._coerce_from_str('theta25^3 + (1/3)*theta25')
+            -1/3*theta25 - 1
+
+        This function is called by the coerce method when it gets a string
+        as input:
+            sage: k('theta25^3 + (1/3)*theta25')
+            -1/3*theta25 - 1        
+        """
+        w = sage.misc.all.sage_eval(x,locals=self.gens_dict())
+        if not (is_Element(w) and w.parent() is self):
+            return self(w)
+        else:
+            return w        
+
+    def _coerce_map_from_(self, R):
+        """
+        Canonical coercion of x into self.
+
+        Currently integers, rationals, and this field itself coerce
+        canonical into this field. 
+
+        EXAMPLES:
+            sage: S.<y> = NumberField(x^3 + x + 1)
+            sage: S.coerce(int(4))
+            4
+            sage: S.coerce(long(7))
+            7
+            sage: S.coerce(-Integer(2))
+            -2
+            sage: z = S.coerce(-7/8); z, type(z)
+            (-7/8, <type 'sage.rings.number_field.number_field_element.NumberFieldElement_absolute'>)
+            sage: S.coerce(y) is y
+            True
+
+        Fields with embeddings into an ambient field coerce natrually.
+            sage: CyclotomicField(15).coerce(CyclotomicField(5).0 - 17/3)
+            zeta15^3 - 17/3
+            sage: K.<a> = CyclotomicField(16)
+            sage: K(CyclotomicField(4).0)
+            a^4
+            sage: QuadraticField(-3, 'a').coerce_map_from(CyclotomicField(3))
+            Generic morphism:
+              From: Cyclotomic Field of order 3 and degree 2
+              To:   Number Field in a with defining polynomial x^2 + 3
+              Defn: zeta3 -> 1/2*a - 1/2
+
+        There are situations for which one might imagine canonical
+        coercion could make sense (at least after fixing choices), but
+        which aren't yet implemented:
+            sage: K.<a> = QuadraticField(2)
+            sage: K.coerce(sqrt(2))
+            Traceback (most recent call last):
+            ...
+            TypeError: no cannonical coercion from Symbolic Ring to Number Field in a with defining polynomial x^2 - 2
+
+        TESTS:
+            sage: K.<a> = NumberField(polygen(QQ)^3-2)
+            sage: type(K.coerce_map_from(QQ))
+            <type 'sage.structure.coerce_maps.DefaultConvertMap_unique'>
+            
+        Make sure we still get our optimized morphisms for special fields:
+            sage: K.<a> = NumberField(polygen(QQ)^2-2)
+            sage: type(K.coerce_map_from(QQ))
+            <type 'sage.rings.number_field.number_field_element_quadratic.Q_to_quadratic_field_element'>
+        """
+        if R in [int, long, ZZ, QQ, self.base()]:
+            return self._generic_convert_map(R)
+        from sage.rings.number_field.order import is_NumberFieldOrder
+        if is_NumberFieldOrder(R) and R.number_field().has_coerce_map_from(self):
+            return self._generic_convert_map(R)
+        if is_NumberField(R) and R != QQ:
+            if R.coerce_embedding() is not None:
+                if self.coerce_embedding() is not None:
+                    try:
+                        from sage.categories.pushout import pushout
+                        ambient_field = pushout(R.coerce_embedding().codomain(), self.coerce_embedding().codomain())
+                        if ambient_field is not None:
+                            return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self)
+                    except (TypeError, ValueError):
+                        pass
+
     def _magma_init_(self, magma):
         """
         Return Magma version of this number field.
diff -r cc37ebbf6f16 -r 868cc7270136 sage/rings/number_field/number_field_element.pyx
--- a/sage/rings/number_field/number_field_element.pyx	Fri Jan 23 00:55:58 2009 -0800
+++ b/sage/rings/number_field/number_field_element.pyx	Fri Jan 23 18:06:09 2009 -0800
@@ -2100,6 +2100,26 @@
                 
 
 cdef class NumberFieldElement_relative(NumberFieldElement):
+    def __init__(self, parent, f):
+        r"""
+        """
+        # The current relative number field element implementation
+        # does everything in terms of absolute polynomials, but of
+        # course it's most natural to send in relative polynomials.
+        # So we convert from self.base_ring()['x'] to
+        # self.absolute_field()['x'] here.
+#         if isinstance(f, sage.rings.polynomial.polynomial_element.Polynomial):
+#             print "parent._gen_relative() =", parent._gen_relative()
+#             print "started with", f, ", f.parent() =", f.parent()
+#             g = parent.gen()
+#             print "g =", g, ", g.parent() =", g.parent()
+#             s = 0
+#             for i in range(f.degree()):
+#                 s += parent(f[i]) * g**i
+#             f = s.polynomial() # XXX should be absolute_polynomial()
+#             print "ended with", f, ", f.parent() =", f.parent()
+        NumberFieldElement.__init__(self, parent, f)
+
     def list(self):
         """
         Return list of coefficients of self written in terms of a
diff -r cc37ebbf6f16 -r 868cc7270136 sage/rings/number_field/number_field_ideal_rel.py
--- a/sage/rings/number_field/number_field_ideal_rel.py	Fri Jan 23 00:55:58 2009 -0800
+++ b/sage/rings/number_field/number_field_ideal_rel.py	Fri Jan 23 18:06:09 2009 -0800
@@ -37,12 +37,16 @@
         Fractional ideal (38)
         
     WARNING: Ideals in relative number fields are broken:
-        sage: K.<a> = NumberField([x^2 + 1, x^2 + 2]); K
+        sage: K.<a0, a1> = NumberField([x^2 + 1, x^2 + 2]); K
         Number Field in a0 with defining polynomial x^2 + 1 over its base field
-        sage: i = K.ideal([a+1]); i
-        Traceback (most recent call last):
-        ...
-        TypeError: Unable to coerce -a1 to a rational
+        sage: i = K.ideal([a0+1]); i # random
+        Fractional ideal (-a1*a0)
+        sage: (g, ) = i.gens_reduced(); g # random
+        -a1*a0
+        sage: (g / (a0 + 1)).is_integral()
+        True
+        sage: ((a0 + 1) / g).is_integral()
+        True
     """
     def pari_rhnf(self):
         """
@@ -77,6 +81,20 @@
             self.__absolute_ideal = L.ideal(genlist)
             return self.__absolute_ideal
 
+    def _from_absolute_ideal(self, id):
+        L = self.number_field()
+        K = L.absolute_field('a')
+        K_to_L, L_to_K = K.structure()
+        rnf = L.pari_rnf()
+        nf_zk = id.number_field().pari_nf().getattr('zk')
+        gens_in_K = [ QQ['x'](x) for x in nf_zk * id.pari_hnf()]
+        # each gen is now a polynomial giving an element of the absolute number field
+        gens_in_L = [ L(K(x)) for x in gens_in_K ]
+        return L.ideal( gens_in_L )
+
+    def free_module(self):
+        return self.absolute_ideal().free_module()
+
     def gens_reduced(self):
         try:
             return self.__reduced_generators
@@ -87,10 +105,8 @@
             S = L['x']
             gens = L.pari_rnf().rnfidealtwoelt(self.pari_rhnf())
             gens = [ L(R(x.lift().lift())) for x in gens ]
-            ## Make sure that gens[1] is in L, not K
-            Lcoeff = [ L(x) for x in list(gens[1].polynomial()) ]
-            gens[1] = S.hom([L.gen()])(S(Lcoeff))
 
+            # pari always returns two elements, even if only one is needed!
             if gens[1] in L.ideal([ gens[0] ]):
                 gens = [ gens[0] ]
             elif gens[0] in L.ideal([ gens[1] ]):
@@ -112,13 +128,7 @@
         """
         if self.is_zero():
             raise ZeroDivisionError
-        L = self.number_field()
-        R = QQ['x']
-        rnf = L.pari_rnf()
-        inverse = self.absolute_ideal().__invert__()
-        nf_zk = inverse.number_field().pari_nf().getattr('zk')
-        genlist = [L(R(x)) for x in nf_zk * inverse.pari_hnf()]
-        return L.ideal(genlist)
+        return self._from_absolute_ideal( self.absolute_ideal().__invert__() )
 
     def is_principal(self):
         return self.absolute_ideal().is_principal()
diff -r cc37ebbf6f16 -r 868cc7270136 sage/rings/number_field/number_field_rel.py
--- a/sage/rings/number_field/number_field_rel.py	Fri Jan 23 00:55:58 2009 -0800
+++ b/sage/rings/number_field/number_field_rel.py	Fri Jan 23 18:06:09 2009 -0800
@@ -50,7 +50,7 @@
 TESTS:
     sage: y = polygen(QQ,'y'); K.<beta> = NumberField([y^3 - 3, y^2 - 2])
     sage: K(y^10)
-    (-3024*beta1 + 1530)*beta0^2 + (-2320*beta1 + 5067)*beta0 - 3150*beta1 + 7592
+    27*beta0
 """
 
 #*****************************************************************************
@@ -510,8 +510,158 @@
         return "( %s )[%s]/(%s)"%(latex(self.base_field()), self.latex_variable_name(),
                               self.polynomial()._latex_(self.latex_variable_name()))
 
-    def _element_constructor_(self, x):
+    def _coerce_from_other_number_field(self, x):
         """
+        Coerce a number field element x into this number field.
+
+        In most cases this currently doesn't work (since it is
+        barely implemented) -- it only works for constants.
+
+        INPUT:
+            x -- an element of some number field
+
+        EXAMPLES:
+            sage: K.<a> = NumberField(x^3 + 2)
+            sage: L.<b> = NumberField(x^2 + 1)
+            sage: K._coerce_from_other_number_field(L(2/3))
+            2/3
+        """
+        if x.parent() is self.base_ring() or x.parent() == self.base_ring():
+            return self.__base_inclusion(x)
+
+        f = x.polynomial()
+        if f.degree() <= 0:
+            return self._element_class(self, f[0])
+        # todo: more general coercion if embedding have been asserted
+        raise TypeError, "Cannot coerce element into this number field"
+    
+    def _coerce_non_number_field_element_in(self, x):
+        """
+        Coerce a non-number field element x into this number field.
+
+        INPUT:
+            x -- a non number field element x, e.g., a list, integer, 
+            rational, or polynomial.
+
+        EXAMPLES:
+            sage: K.<a> = NumberField(x^3 + 2/3)
+            sage: K._coerce_non_number_field_element_in(-7/8)
+            -7/8
+            sage: K._coerce_non_number_field_element_in([1,2,3])
+            3*a^2 + 2*a + 1
+
+        The list is just turned into a polynomial in the generator.
+            sage: K._coerce_non_number_field_element_in([0,0,0,1,1])
+            -2/3*a - 2/3
+
+        Any polynomial whose coefficients can be coerced to rationals will
+        coerce, e.g., this one in characteristic 7.
+            sage: f = GF(7)['y']([1,2,3]); f
+            3*y^2 + 2*y + 1
+            sage: K._coerce_non_number_field_element_in(f)
+            3*a^2 + 2*a + 1
+ 
+        But not this one over a field of order 27.
+            sage: F27.<g> = GF(27)
+            sage: f = F27['z']([g^2, 2*g, 1]); f
+            z^2 + 2*g*z + g^2
+            sage: K._coerce_non_number_field_element_in(f)
+            Traceback (most recent call last):
+            ...
+            TypeError: <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
+
+        One can also coerce an element of the polynomial quotient ring
+        that's isomorphic to the number field: 
+            sage: K.<a> = NumberField(x^3 + 17)
+            sage: b = K.polynomial_quotient_ring().random_element()
+            sage: K(b)
+            -1/2*a^2 - 4
+        """
+        if isinstance(x, (int, long, rational.Rational,
+                              integer.Integer, pari_gen,
+                              list)):
+            return self._element_class(self, x)
+        elif isinstance(x, sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement)\
+               and (x in self.polynomial_quotient_ring()):
+            y = self.polynomial_ring().gen()
+            return x.lift().subs({y:self.gen()})
+        elif isinstance(x, polynomial_element.Polynomial):
+            # we have been given a polynomial over our base field;
+            # change it to an absolute polynomial
+            f = x.change_ring(self)( self.gen() ).polynomial()
+            return self._element_class(self, f)
+        else:
+            return self._element_class(self, x._rational_())
+
+    def _coerce_map_from_(self, R):
+        """
+        Canonical coercion of x into this relative number field.
+
+        Currently integers, rationals, the base field, and this field
+        itself coerce canonical into this field.
+
+        EXAMPLES:
+            sage: S.<y> = NumberField(x^3 + x + 1)
+            sage: S.coerce(int(4))
+            4
+            sage: S.coerce(long(7))
+            7
+            sage: S.coerce(-Integer(2))
+            -2
+            sage: z = S.coerce(-7/8); z, type(z)
+            (-7/8, <type 'sage.rings.number_field.number_field_element.NumberFieldElement_absolute'>)
+            sage: S.coerce(y) is y
+            True
+
+        Fields with embeddings into an ambient field coerce natrually.
+            sage: CyclotomicField(15).coerce(CyclotomicField(5).0 - 17/3)
+            zeta15^3 - 17/3
+            sage: K.<a> = CyclotomicField(16)
+            sage: K(CyclotomicField(4).0)
+            a^4
+            sage: QuadraticField(-3, 'a').coerce_map_from(CyclotomicField(3))
+            Generic morphism:
+              From: Cyclotomic Field of order 3 and degree 2
+              To:   Number Field in a with defining polynomial x^2 + 3
+              Defn: zeta3 -> 1/2*a - 1/2
+
+        There are situations for which one might imagine canonical
+        coercion could make sense (at least after fixing choices), but
+        which aren't yet implemented:
+            sage: K.<a> = QuadraticField(2)
+            sage: K.coerce(sqrt(2))
+            Traceback (most recent call last):
+            ...
+            TypeError: no cannonical coercion from Symbolic Ring to Number Field in a with defining polynomial x^2 - 2
+
+        TESTS:
+            sage: K.<a> = NumberField(polygen(QQ)^3-2)
+            sage: type(K.coerce_map_from(QQ))
+            <type 'sage.structure.coerce_maps.DefaultConvertMap_unique'>
+            
+        Make sure we still get our optimized morphisms for special fields:
+            sage: K.<a> = NumberField(polygen(QQ)^2-2)
+            sage: type(K.coerce_map_from(QQ))
+            <type 'sage.rings.number_field.number_field_element_quadratic.Q_to_quadratic_field_element'>
+        """
+        if R in [self, int, long, ZZ, QQ, self.base_field()]:
+            return self._generic_convert_map(R)
+        from sage.rings.number_field.order import is_NumberFieldOrder
+        if is_NumberFieldOrder(R) and R.number_field().has_coerce_map_from(self):
+            return self._generic_convert_map(R)
+        if is_NumberField(R) and R != QQ:
+            if R.coerce_embedding() is not None:
+                if self.coerce_embedding() is not None:
+                    try:
+                        from sage.categories.pushout import pushout
+                        ambient_field = pushout(R.coerce_embedding().codomain(), self.coerce_embedding().codomain())
+                        if ambient_field is not None:
+                            return number_field_morphisms.EmbeddedNumberFieldMorphism(R, self)
+                    except (TypeError, ValueError):
+                        pass
+
+    def XXX_XXX(self, x):
+        r"""
         Coerce x into this relative number field.
 
         EXAMPLES:
@@ -549,24 +699,7 @@
             sage: L(b)
             -1/2*a
         """
-        if isinstance(x, number_field_element.NumberFieldElement):
-            P = x.parent()
-            from sage.rings.number_field.order import is_NumberFieldOrder
-            if P is self:
-                return x
-            elif is_NumberFieldOrder(P) and P.number_field() is self:
-                return self._element_class(self, x.polynomial())
-            elif P == self:
-                return self._element_class(self, x.polynomial())
-            return self.__base_inclusion(self.base_field()(x))
-
-        if not isinstance(x, (int, long, rational.Rational,
-                              integer.Integer, pari_gen,
-                              polynomial_element.Polynomial,
-                              list)):
-            return self.base_field()(x)
-        
-        return self._element_class(self, x)
+        raise RuntimeError
 
     def _coerce_map_from_(self, R):
         """
@@ -630,7 +763,10 @@
         expr_x = self.pari_rnf().rnfeltreltoabs(f._pari_())
         # Convert to a SAGE polynomial, then to one in gen(), and return it
         R = self.polynomial_ring()
-        return self(R(expr_x))
+        # We do NOT call self(...) because this code is called by
+        # __init__ before we initialize self.gens(), and self(...)
+        # uses self.gens()
+        return self._element_class(self, R(expr_x))
 
     def _fractional_ideal_class_(self):
         """
diff -r cc37ebbf6f16 -r 868cc7270136 sage/rings/polynomial/polynomial_quotient_ring_element.py
--- a/sage/rings/polynomial/polynomial_quotient_ring_element.py	Fri Jan 23 00:55:58 2009 -0800
+++ b/sage/rings/polynomial/polynomial_quotient_ring_element.py	Fri Jan 23 18:06:09 2009 -0800
@@ -61,6 +61,7 @@
 
 import sage.rings.commutative_ring_element as commutative_ring_element
 import sage.rings.number_field.number_field as number_field
+import sage.rings.number_field.number_field_rel as number_field_rel
 
 
 class PolynomialQuotientRingElement(commutative_ring_element.CommutativeRingElement):
@@ -373,7 +374,7 @@
         
 	f = R.hom([alpha], F, check=False)
 
-        if number_field.is_RelativeNumberField(F):
+        if number_field_rel.is_RelativeNumberField(F):
 
             base_hom = F.base_field().hom([R.base_ring().gen()])
             g = F.Hom(R)(x, base_hom)
