Esempio n. 1
0
    def _element_constructor_(self, elt):
        r"""
        TESTS::

            sage: UCF = UniversalCyclotomicField()
            sage: UCF(3)
            3
            sage: UCF(3/2)
            3/2

            sage: C = CyclotomicField(13)
            sage: UCF(C.gen())
            E(13)
            sage: UCF(C.gen() - 3*C.gen()**2 + 5*C.gen()**5)
            E(13) - 3*E(13)^2 + 5*E(13)^5

            sage: C = CyclotomicField(12)
            sage: zeta12 = C.gen()
            sage: a = UCF(zeta12 - 3* zeta12**2)
            sage: a
            -E(12)^7 + 3*E(12)^8
            sage: C(_) == a
            True

            sage: UCF('[[0, 1], [0, 2]]')
            Traceback (most recent call last):
            ...
            TypeError: [ [ 0, 1 ], [ 0, 2 ] ]
            of type <type 'sage.libs.gap.element.GapElement_List'> not valid
            to initialize an element of the universal cyclotomic field

        Some conversions from symbolic functions are possible::

            sage: UCF = UniversalCyclotomicField()
            sage: [UCF(sin(pi/k, hold=True)) for k in range(1,10)]
            [0,
             1,
             -1/2*E(12)^7 + 1/2*E(12)^11,
             1/2*E(8) - 1/2*E(8)^3,
             -1/2*E(20)^13 + 1/2*E(20)^17,
             1/2,
             -1/2*E(28)^19 + 1/2*E(28)^23,
             1/2*E(16)^3 - 1/2*E(16)^5,
             -1/2*E(36)^25 + 1/2*E(36)^29]
            sage: [UCF(cos(pi/k, hold=True)) for k in range(1,10)]
            [-1,
             0,
             1/2,
             1/2*E(8) - 1/2*E(8)^3,
             -1/2*E(5)^2 - 1/2*E(5)^3,
             -1/2*E(12)^7 + 1/2*E(12)^11,
             -1/2*E(7)^3 - 1/2*E(7)^4,
             1/2*E(16) - 1/2*E(16)^7,
             -1/2*E(9)^4 - 1/2*E(9)^5]

        .. TODO::

            Implement conversion from QQbar (and as a consequence from the
            symbolic ring)
        """
        elt = py_scalar_to_element(elt)

        if isinstance(elt, (Integer, Rational)):
            return self.element_class(self, libgap(elt))
        elif isinstance(
                elt,
            (GapElement_Integer, GapElement_Rational, GapElement_Cyclotomic)):
            return self.element_class(self, elt)
        elif not elt:
            return self.zero()

        obj = None
        if isinstance(elt, gap.GapElement):
            obj = libgap(elt)
        elif isinstance(elt, gap3.GAP3Element):
            obj = libgap.eval(str(elt))
        elif isinstance(elt, str):
            obj = libgap.eval(elt)
        if obj is not None:
            if not isinstance(obj, (GapElement_Integer, GapElement_Rational,
                                    GapElement_Cyclotomic)):
                raise TypeError(
                    "{} of type {} not valid to initialize an element of the universal cyclotomic field"
                    .format(obj, type(obj)))
            return self.element_class(self, obj)

        # late import to avoid slowing down the above conversions
        from sage.rings.number_field.number_field_element import NumberFieldElement
        from sage.rings.number_field.number_field import NumberField_cyclotomic, CyclotomicField
        P = parent(elt)
        if isinstance(elt, NumberFieldElement) and isinstance(
                P, NumberField_cyclotomic):
            n = P.gen().multiplicative_order()
            elt = CyclotomicField(n)(elt)
            return sum(c * self.gen(n, i)
                       for i, c in enumerate(elt._coefficients()))

        if hasattr(elt, '_algebraic_'):
            return elt._algebraic_(self)

        raise TypeError(
            "{} of type {} not valid to initialize an element of the universal cyclotomic field"
            .format(elt, type(elt)))