예제 #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)))
    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

        .. 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)
            coeffs = elt._coefficients()
            return sum(c * self.gen(n,i) for i,c in enumerate(elt._coefficients()))
        else:
            raise TypeError("{} of type {} not valid to initialize an element of the universal cyclotomic field".format(elt, type(elt)))
예제 #3
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

        .. 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()))
        else:
            raise TypeError("{} of type {} not valid to initialize an element of the universal cyclotomic field".format(elt, type(elt)))
예제 #4
0
    def _element_constructor_(self, x, y=None, coerce=True):
        """
        Construct an element of this fraction field.

        EXAMPLES::

            sage: F = QQ['x,y'].fraction_field()
            sage: F._element_constructor_(1)
            1
            sage: F._element_constructor_(F.gen(0)/F.gen(1))
            x/y
            sage: F._element_constructor_('1 + x/y')
            (x + y)/y

        ::

            sage: K = ZZ['x,y'].fraction_field()
            sage: x,y = K.gens()

        ::

            sage: F._element_constructor_(x/y)
            x/y

        TESTS:

        The next example failed before :trac:`4376`::

            sage: K(pari((x + 1)/(x^2 + x + 1)))
            (x + 1)/(x^2 + x + 1)

        These examples failed before :trac:`11368`::

            sage: R.<x, y, z> = PolynomialRing(QQ)
            sage: S = R.fraction_field()
            sage: S(pari((x + y)/y))
            (x + y)/y

            sage: S(pari(x + y + 1/z))
            (x*z + y*z + 1)/z

        This example failed before :trac:`23664`::

            sage: P0.<x> = ZZ[]
            sage: P1.<y> = Frac(P0)[]
            sage: frac = (x/(x^2 + 1))*y + 1/(x^3 + 1)
            sage: Frac(ZZ['x,y'])(frac)
            (x^4*y + x^2 + x*y + 1)/(x^5 + x^3 + x^2 + 1)

        Test conversions where `y` is a string but `x` not::

            sage: K = ZZ['x,y'].fraction_field()
            sage: K._element_constructor_(2, 'x+y')
            2/(x + y)
            sage: K._element_constructor_(1, 'z')
            Traceback (most recent call last):
            ...
            TypeError: unable to evaluate 'z' in Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring

        Check that :trac:`17971` is fixed::

            sage: A.<a,c> = Frac(PolynomialRing(QQ,'a,c'))
            sage: B.<d,e> = PolynomialRing(A,'d,e')
            sage: R.<x> = PolynomialRing(B,'x')
            sage: (a*d*x^2+a+e+1).resultant(-4*c^2*x+1)
            a*d + 16*c^4*e + 16*a*c^4 + 16*c^4

        Check that :trac:`24539` is fixed::

            sage: tau = polygen(QQ, 'tau')
            sage: PolynomialRing(CyclotomicField(2), 'z').fraction_field()(tau/(1+tau))
            z/(z + 1)

        Check that :trac:`26150` is fixed::

            sage: z = SR.var('z')
            sage: CyclotomicField(2)['z'].fraction_field()(2*(4*z + 5)/((z + 1)*(z - 1)^4))
            (8*z + 10)/(z^5 - 3*z^4 + 2*z^3 + 2*z^2 - 3*z + 1)

        ::

            sage: T.<t> = ZZ[]
            sage: S.<s> = ZZ[]
            sage: S.fraction_field()(s/(s+1), (t-1)/(t+2))
            (s^2 + 2*s)/(s^2 - 1)
        """
        if y is None:
            if isinstance(x, Element) and x.parent() is self:
                return x
            ring_one = self.ring().one()
            try:
                return self._element_class(self, x, ring_one, coerce=coerce)
            except (TypeError, ValueError):
                pass
            y = self._element_class(self,
                                    ring_one,
                                    ring_one,
                                    coerce=False,
                                    reduce=False)
        else:
            try:
                return self._element_class(self, x, y, coerce=coerce)
            except (TypeError, ValueError):
                pass

        if isinstance(x, six.string_types):
            from sage.misc.sage_eval import sage_eval
            try:
                x = sage_eval(x, self.gens_dict_recursive())
            except NameError:
                raise TypeError("unable to evaluate {!r} in {}".format(
                    x, self))
        if isinstance(y, six.string_types):
            from sage.misc.sage_eval import sage_eval
            try:
                y = sage_eval(y, self.gens_dict_recursive())
            except NameError:
                raise TypeError("unable to evaluate {!r} in {}".format(
                    y, self))

        x = py_scalar_to_element(x)
        y = py_scalar_to_element(y)

        from sage.libs.pari.all import pari_gen
        if isinstance(x, pari_gen) and x.type() == 't_POL':
            # This recursive approach is needed because PARI
            # represents multivariate polynomials as iterated
            # univariate polynomials (see the above examples).
            # Below, v is the variable with highest priority,
            # and the x[i] are rational functions in the
            # remaining variables.
            v = self._element_class(self, x.variable(), 1)
            x = sum(self(x[i]) * v**i for i in range(x.poldegree() + 1))

        def resolve_fractions(x, y):
            xn = x.numerator()
            xd = x.denominator()
            yn = y.numerator()
            yd = y.denominator()
            try:
                return (xn * yd, yn * xd)
            except (AttributeError, TypeError, ValueError):
                pass
            try:
                P = yd.parent()
                return (P(xn) * yd, yn * P(xd))
            except (AttributeError, TypeError, ValueError):
                pass
            try:
                P = xd.parent()
                return (xn * P(yd), P(yn) * xd)
            except (AttributeError, TypeError, ValueError):
                pass
            raise TypeError

        while True:
            x0, y0 = x, y
            try:
                x, y = resolve_fractions(x0, y0)
            except (AttributeError, TypeError):
                raise TypeError(
                    "cannot convert {!r}/{!r} to an element of {}".format(
                        x0, y0, self))
            try:
                return self._element_class(self, x, y, coerce=coerce)
            except TypeError:
                if not x != x0:
                    raise
예제 #5
0
파일: fraction_field.py 프로젝트: yarv/sage
    def _element_constructor_(self, x, y=None, coerce=True):
        """
        Construct an element of this fraction field.

        EXAMPLES::

            sage: F = QQ['x,y'].fraction_field()
            sage: F._element_constructor_(1)
            1
            sage: F._element_constructor_(F.gen(0)/F.gen(1))
            x/y
            sage: F._element_constructor_('1 + x/y')
            (x + y)/y

        ::

            sage: K = ZZ['x,y'].fraction_field()
            sage: x,y = K.gens()

        ::

            sage: F._element_constructor_(x/y)
            x/y

        TESTS:

        The next example failed before :trac:`4376`::

            sage: K(pari((x + 1)/(x^2 + x + 1)))
            (x + 1)/(x^2 + x + 1)

        These examples failed before :trac:`11368`::

            sage: R.<x, y, z> = PolynomialRing(QQ)
            sage: S = R.fraction_field()
            sage: S(pari((x + y)/y))
            (x + y)/y

            sage: S(pari(x + y + 1/z))
            (x*z + y*z + 1)/z

        This example failed before :trac:`23664`::

            sage: P0.<x> = ZZ[]
            sage: P1.<y> = Frac(P0)[]
            sage: frac = (x/(x^2 + 1))*y + 1/(x^3 + 1)
            sage: Frac(ZZ['x,y'])(frac)
            (x^4*y + x^2 + x*y + 1)/(x^5 + x^3 + x^2 + 1)

        Test conversions where `y` is a string but `x` not::

            sage: K = ZZ['x,y'].fraction_field()
            sage: K._element_constructor_(2, 'x+y')
            2/(x + y)
            sage: K._element_constructor_(1, 'z')
            Traceback (most recent call last):
            ...
            TypeError: unable to evaluate 'z' in Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring

        Check that :trac:`17971` is fixed::

            sage: A.<a,c> = Frac(PolynomialRing(QQ,'a,c'))
            sage: B.<d,e> = PolynomialRing(A,'d,e')
            sage: R.<x> = PolynomialRing(B,'x')
            sage: (a*d*x^2+a+e+1).resultant(-4*c^2*x+1)
            a*d + 16*c^4*e + 16*a*c^4 + 16*c^4
        """
        if y is None:
            if isinstance(x, Element) and x.parent() is self:
                return x
            else:
                y = self.base_ring().one()

        try:
            return self._element_class(self, x, y, coerce=coerce)
        except (TypeError, ValueError):
            pass

        if isinstance(x, six.string_types):
            from sage.misc.sage_eval import sage_eval
            try:
                x = sage_eval(x, self.gens_dict_recursive())
            except NameError:
                raise TypeError("unable to evaluate {!r} in {}".format(
                    x, self))
        if isinstance(y, six.string_types):
            from sage.misc.sage_eval import sage_eval
            try:
                y = sage_eval(y, self.gens_dict_recursive())
            except NameError:
                raise TypeError("unable to evaluate {!r} in {}".format(
                    y, self))

        x = py_scalar_to_element(x)
        y = py_scalar_to_element(y)

        from sage.libs.pari.all import pari_gen
        if isinstance(x, pari_gen) and x.type() == 't_POL':
            # This recursive approach is needed because PARI
            # represents multivariate polynomials as iterated
            # univariate polynomials (see the above examples).
            # Below, v is the variable with highest priority,
            # and the x[i] are rational functions in the
            # remaining variables.
            v = self._element_class(self, x.variable(), 1)
            x = sum(self(x[i]) * v**i for i in range(x.poldegree() + 1))

        while True:
            x0, y0 = x, y
            try:
                x = x0.numerator() * y0.denominator()
                y = y0.numerator() * x0.denominator()
            except AttributeError:
                raise TypeError("cannot convert {!r}/{!r} to an element of {}",
                                x0, y0, self)
            try:
                return self._element_class(self, x, y, coerce=coerce)
            except TypeError:
                if not x != x0:
                    raise
예제 #6
0
    def _element_constructor_(self, x, y=None, coerce=True):
        """
        Construct an element of this fraction field.

        EXAMPLES::

            sage: F = QQ['x,y'].fraction_field()
            sage: F._element_constructor_(1)
            1
            sage: F._element_constructor_(F.gen(0)/F.gen(1))
            x/y
            sage: F._element_constructor_('1 + x/y')
            (x + y)/y

        ::

            sage: K = ZZ['x,y'].fraction_field()
            sage: x,y = K.gens()

        ::

            sage: F._element_constructor_(x/y)
            x/y

        TESTS:

        The next example failed before :trac:`4376`::

            sage: K(pari((x + 1)/(x^2 + x + 1)))
            (x + 1)/(x^2 + x + 1)

        These examples failed before :trac:`11368`::

            sage: R.<x, y, z> = PolynomialRing(QQ)
            sage: S = R.fraction_field()
            sage: S(pari((x + y)/y))
            (x + y)/y

            sage: S(pari(x + y + 1/z))
            (x*z + y*z + 1)/z

        This example failed before :trac:`23664`::

            sage: P0.<x> = ZZ[]
            sage: P1.<y> = Frac(P0)[]
            sage: frac = (x/(x^2 + 1))*y + 1/(x^3 + 1)
            sage: Frac(ZZ['x,y'])(frac)
            (x^4*y + x^2 + x*y + 1)/(x^5 + x^3 + x^2 + 1)

        Test conversions where `y` is a string but `x` not::

            sage: K = ZZ['x,y'].fraction_field()
            sage: K._element_constructor_(2, 'x+y')
            2/(x + y)
            sage: K._element_constructor_(1, 'z')
            Traceback (most recent call last):
            ...
            TypeError: unable to evaluate 'z' in Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring

        Check that :trac:`17971` is fixed::

            sage: A.<a,c> = Frac(PolynomialRing(QQ,'a,c'))
            sage: B.<d,e> = PolynomialRing(A,'d,e')
            sage: R.<x> = PolynomialRing(B,'x')
            sage: (a*d*x^2+a+e+1).resultant(-4*c^2*x+1)
            a*d + 16*c^4*e + 16*a*c^4 + 16*c^4

        Check that :trac:`24539` is fixed::

            sage: tau = polygen(QQ, 'tau')
            sage: R = PolynomialRing(CyclotomicField(2), 'z').fraction_field()(
            ....:     tau/(1+tau))
            Traceback (most recent call last):
            ...
            TypeError: cannot convert tau/(tau + 1)/1 to an element of Fraction
            Field of Univariate Polynomial Ring in z over Cyclotomic Field of
            order 2 and degree 1
        """
        if y is None:
            if isinstance(x, Element) and x.parent() is self:
                return x
            else:
                y = self.base_ring().one()

        try:
            return self._element_class(self, x, y, coerce=coerce)
        except (TypeError, ValueError):
            pass

        if isinstance(x, six.string_types):
            from sage.misc.sage_eval import sage_eval
            try:
                x = sage_eval(x, self.gens_dict_recursive())
            except NameError:
                raise TypeError("unable to evaluate {!r} in {}".format(x, self))
        if isinstance(y, six.string_types):
            from sage.misc.sage_eval import sage_eval
            try:
                y = sage_eval(y, self.gens_dict_recursive())
            except NameError:
                raise TypeError("unable to evaluate {!r} in {}".format(y, self))

        x = py_scalar_to_element(x)
        y = py_scalar_to_element(y)

        from sage.libs.pari.all import pari_gen
        if isinstance(x, pari_gen) and x.type() == 't_POL':
            # This recursive approach is needed because PARI
            # represents multivariate polynomials as iterated
            # univariate polynomials (see the above examples).
            # Below, v is the variable with highest priority,
            # and the x[i] are rational functions in the
            # remaining variables.
            v = self._element_class(self, x.variable(), 1)
            x = sum(self(x[i]) * v**i for i in range(x.poldegree() + 1))

        while True:
            x0, y0 = x, y
            try:
                x = x0.numerator()*y0.denominator()
                y = y0.numerator()*x0.denominator()
            except AttributeError:
                raise TypeError("cannot convert {!r}/{!r} to an element of {}".format(
                                x0, y0, self))
            try:
                return self._element_class(self, x, y, coerce=coerce)
            except TypeError:
                if not x != x0:
                    raise