def __cmp__(self, other):
        r"""
        Comparison (using the complex embedding).

        TESTS::

            sage: UCF = UniversalCyclotomicField()
            sage: l = [UCF.gen(3), UCF.gen(3)+1, UCF.gen(5), UCF.gen(5,2),
            ....:      UCF.gen(4), 2*UCF.gen(4), UCF.gen(5)-22/3]
            sage: lQQbar = map(QQbar,l)
            sage: lQQbar.sort()
            sage: l.sort()
            sage: lQQbar == map(QQbar,l)
            True

            sage: for i in range(len(l)):
            ....:     assert l[i] >= l[i] and l[i] <= l[i]
            ....:     for j in range(i):
            ....:         assert l[i] > l[j] and l[j] < l[i]
        """
        if self._obj == other._obj:
            return 0
        else:
            from sage.rings.qqbar import QQbar
            return cmp(QQbar(self), QQbar(other))
    def _call_(self, x):
        r"""
        TESTS::

            sage: UCF = UniversalCyclotomicField()
            sage: UCFtoQQbar = UCF.coerce_embedding()
            sage: UCFtoQQbar(UCF.gen(3))  # indirect doctest
            -0.500000000000000? + 0.866025403784439?*I
        """
        obj = x._obj
        QQbar = self.codomain()
        if obj.IsRat():
            return QQbar(obj.sage())
        k = obj.Conductor().sage()
        coeffs = obj.CoeffsCyc(k).sage()
        zeta = QQbar.zeta(k)
        return QQbar(sum(coeffs[a] * zeta**a for a in range(1, k)))
Beispiel #3
0
    def sqrt(self):
        """
        Return a square root of ``self`` as an algebraic number.

        EXAMPLES::

            sage: f = E(33)
            sage: f.sqrt()
            0.9954719225730846? + 0.0950560433041827?*I
            sage: f.sqrt()**2 == f
            True
        """
        return QQbar(self).sqrt()
Beispiel #4
0
    def _algebraic_(self, R):
        r"""
        TESTS::

            sage: UCF = UniversalCyclotomicField()
            sage: AA(UCF.gen(5) + UCF.gen(5,4))
            0.618033988749895?
            sage: AA(UCF.gen(5))
            Traceback (most recent call last):
            ...
            ValueError: Cannot coerce algebraic number with non-zero imaginary
            part to algebraic real
        """
        return R(QQbar(self))
    def _mpfr_(self, R):
        r"""
        TESTS::

            sage: RR(E(7) + E(7,6))
            1.24697960371747
            sage: 2*cos(2*pi/7).n()
            1.24697960371747
        """
        if not self.is_real():
            raise TypeError("self is not real")

        from sage.rings.qqbar import QQbar, AA
        return AA(QQbar(self))._mpfr_(R)
Beispiel #6
0
def generalized_series_term_valuation(z, i, j, iota=None):
    r"""
    Given z, i, j, return the valuation of the term x^(z+i) log(x)^j
    """
    try:
        z = QQbar(z)
    except ValueError:
        # FIXME: It would be great if we could show the warning once per
        # relevant field
        warn(
            "Choosing an arbitrary complex embedding for {}.\n"
            "To avoid it, extend the coefficients of the base ring.".format(
                z.parent()), RuntimeWarning)
        z = z.parent().embeddings(QQbar)[0](z)
    if iota is None:
        iota = generalized_series_default_iota
    return ZZ(z + i - iota(z, j))
Beispiel #7
0
    def closed_form(self, n='n'):
        r"""
        Return a symbolic expression in ``n``, which equals the n-th term of
        the sequence.

        It is a well-known property of C-finite sequences ``a_n`` that they
        have a closed form of the type:

        .. MATH::

            a_n = \sum_{i=1}^d c_i(n) \cdot r_i^n,

        where ``r_i`` are the roots of the characteristic equation and
        ``c_i(n)`` is a polynomial (whose degree equals the multiplicity of
        ``r_i`` minus one).  This is a natural generalization of Binet's
        formula for Fibonacci numbers.  See, for instance, [KP2011, Theorem 4.1].

        Note that if the o.g.f. has a polynomial part, that is, if the
        numerator degree is not strictly less than the denominator degree,
        then this closed form holds only when ``n`` exceeds the degree of that
        polynomial part.  In that case, the returned expression will differ
        from the sequence for small ``n``.

        EXAMPLES::

            sage: CFiniteSequence(1/(1-x)).closed_form()
            1
            sage: CFiniteSequence(x^2/(1-x)).closed_form()
            1
            sage: CFiniteSequence(1/(1-x^2)).closed_form()
            1/2*(-1)^n + 1/2
            sage: CFiniteSequence(1/(1+x^3)).closed_form()
            1/3*(-1)^n + 1/3*(1/2*I*sqrt(3) + 1/2)^n + 1/3*(-1/2*I*sqrt(3) + 1/2)^n
            sage: CFiniteSequence(1/(1-x)/(1-2*x)/(1-3*x)).closed_form()
            9/2*3^n - 4*2^n + 1/2

        Binet's formula for the Fibonacci numbers::

            sage: CFiniteSequence(x/(1-x-x^2)).closed_form()
            sqrt(1/5)*(1/2*sqrt(5) + 1/2)^n - sqrt(1/5)*(-1/2*sqrt(5) + 1/2)^n
            sage: [_.subs(n=k).full_simplify() for k in range(6)]
            [0, 1, 1, 2, 3, 5]

            sage: CFiniteSequence((4*x+3)/(1-2*x-5*x^2)).closed_form()
            1/2*(sqrt(6) + 1)^n*(7*sqrt(1/6) + 3) - 1/2*(-sqrt(6) + 1)^n*(7*sqrt(1/6) - 3)

        Examples with multiple roots::

            sage: CFiniteSequence(x*(x^2+4*x+1)/(1-x)^5).closed_form()
            1/4*n^4 + 1/2*n^3 + 1/4*n^2
            sage: CFiniteSequence((1+2*x-x^2)/(1-x)^4/(1+x)^2).closed_form()
            1/12*n^3 - 1/8*(-1)^n*(n + 1) + 3/4*n^2 + 43/24*n + 9/8
            sage: CFiniteSequence(1/(1-x)^3/(1-2*x)^4).closed_form()
            4/3*(n^3 - 3*n^2 + 20*n - 36)*2^n + 1/2*n^2 + 19/2*n + 49
            sage: CFiniteSequence((x/(1-x-x^2))^2).closed_form()
            1/5*(n - sqrt(1/5))*(1/2*sqrt(5) + 1/2)^n + 1/5*(n + sqrt(1/5))*(-1/2*sqrt(5) + 1/2)^n
        """
        from sage.arith.all import binomial
        from sage.rings.qqbar import QQbar

        from sage.symbolic.ring import SR
        n = SR(n)
        expr = SR.zero()

        R = FractionField(PolynomialRing(QQbar, self.parent().variable_name()))
        ogf = R(self.ogf())

        __, parts = ogf.partial_fraction_decomposition(decompose_powers=False)
        for part in parts:
            denom = part.denominator().factor()
            denom_base, denom_exp = denom[0]

            # denominator is of the form (x+b)^{m+1}
            m = denom_exp - 1
            b = denom_base.constant_coefficient()
            # check that the partial fraction decomposition was indeed done correctly
            # (that is, there is only one factor, of degree 1, and monic)
            assert len(denom) == 1 and len(denom_base.list(
            )) == 2 and denom_base[1] == 1 and denom.unit() == 1

            r = SR((-1 / b).radical_expression())
            c = SR.zero()
            for k, a in enumerate(part.numerator()):
                a = -QQbar(a) if k % 2 else QQbar(a)
                bino = binomial(n + m - k, m)
                c += bino * SR((a * b**(k - m - 1)).radical_expression())

            expr += c.expand() * r**n

        return expr
Beispiel #8
0
def lie_algebra_isomorphism_classes(F, dim):
    r"""
    Return a list of isomorphism classes of Lie algebras.

    INPUT:

    - ``F`` -- the base field of the Lie algebras
    - ``dim`` -- the dimension of Lie algebras to list

    The full listing is implemented for the fields of rationals ``QQ``
    and algebraic numbers ``QQbar`` up to dimension 6.

    For dimension 7, the returned list is incomplete due to existence
    of one parameter families of Lie algebras, but contains at least one
    representative from each family.
    """
    if F not in [QQ, QQbar]:
        return NotImplemented

    if dim == 1:
        return [L1_1(F)]
    if dim == 2:
        return [L2_1(F)]
    if dim == 3:
        return [L3_1(F), L3_2(F)]
    if dim == 4:
        return [L4_1(F), L4_2(F), L4_3(F)]
    if dim == 5:
        return [L5_1(F), L5_2(F), L5_3(F), L5_4(F), L5_5(F),
                L5_6(F), L5_7(F), L5_8(F), L5_9(F)]
    if dim == 6:
        l = [L6_1(F), L6_2(F), L6_3(F), L6_4(F), L6_5(F), L6_6(F), L6_7(F),
             L6_8(F), L6_9(F), L6_10(F), L6_11(F), L6_12(F), L6_13(F),
             L6_14(F), L6_15(F), L6_16(F), L6_17(F), L6_18(F), L6_19(F, -1)]
        if F == QQ:
            l += [L6_19(F, 1)]
        l += [L6_20(F), L6_21(F, -1)]
        if F == QQ:
            l += [L6_21(F, 1)]
        l += [L6_22(F, 0), L6_22(F, 1)]
        if F == QQ:
            l += [L6_22(F, -1)]
        l += [L6_23(F)]
        l += [L6_24(F, 0), L6_24(F, 1)]
        if F == QQ:
            l += [L6_24(F, -1)]
        l += [L6_25(F), L6_26(F), L6_27(F), L6_28(F)]
        return l

    if dim == 7:
        if F == QQ:
            return NotImplemented

        i = QQbar.gens()[0]

        l = [L37A(F), L37B(F), L37C(F), L37D(F)]
        l += [L357A(F), L357B(F), L357C(F)]
        l += [L27A(F), L27B(F)]
        l += [L257A(F), L257B(F), L257C(F), L257D(F), L257E(F), L257F(F),
              L257G(F), L257H(F), L257I(F), L257J(F), L257K(F), L257L(F)]
        l += [L247A(F), L247B(F), L247C(F), L247D(F), L247E(F), L247F(F),
              L247G(F), L247H(F), L247I(F), L247J(F), L247K(F), L247L(F),
              L247M(F), L247N(F), L247O(F), L247P(F), L247Q(F), L247R(F)]
        l += [L2457A(F), L2457B(F), L2457C(F), L2457D(F), L2457E(F),
              L2457F(F), L2457G(F), L2457H(F), L2457I(F),
              L2457J(F), L2457K(F), L2457L(F), L2457M(F)]
        l += [L2357A(F), L2357B(F), L2357C(F), L2357D(F)]
        l += [L23457A(F), L23457B(F), L23457C(F), L23457D(F),
              L23457E(F), L23457F(F), L23457G(F)]
        l += [L17(F)]
        l += [L157(F)]

        # 147 has a family
        # 147C = 147E(0) = 147E(1) = 247P
        l += [L147A(F), L147B(F), L147D(F)]
        l += [L147E(F, 2)]  # singular value 147E(2)=147E(1/2)=147E(-1)
        # complex singular value same as 1/2-sqrt(3)/2*i
        l += [L147E(F, QQbar(1) / 2 + QQbar(sqrt(3)) / 2 * i)]
        # non-singular value
        # 147E(3)=147E(1/3)=147E(2/3)=147E(3/2)= 147E(-1/2)=147E(-2)
        l += [L147E(F, 3)]
        # non-singular value
        # 147E(5)=147E(1/5)=147E(4/5)=147E(5/4)= 147E(-1/4)=147E(-4)
        l += [L147E(F, 5)]

        l += [L1457A(F), L1457B(F)]
        l += [L137A(F), L137B(F), L137C(F), L137D(F)]

        # 1357 has a family
        l += [L1357A(F), L1357B(F), L1357C(F), L1357D(F), L1357E(F), L1357F(F),
              L1357G(F), L1357H(F), L1357I(F), L1357J(F), L1357K(F), L1357L(F)]
        # 1357M(a)=1357M(a') iff a=a'
        # 1357M(0)=2357B
        l += [L1357M(F, 1)]  # singular value
        l += [L1357M(F, 2)]  # singular value
        l += [L1357M(F, -1)]  # singular value
        # l += [L1357M(F, QQbar(1) / 2)]  # singular value, same as 1357K
        l += [L1357M(F, -QQbar(1) / 3)]  # singular value
        # complex singular value
        l += [L1357M(F, QQbar(1) / 2 - QQbar(sqrt(3)) / 2 * i)]
        # complex singular value
        l += [L1357M(F, QQbar(1) / 2 + QQbar(sqrt(3)) / 2 * i)]
        l += [L1357M(F, 3)]  # non singular value
        l += [L1357M(F, 5)]  # non singular value
        # 1357N(a)=1357N(a') iff a=a'
        l += [L1357N(F, 0)]  # singular value
        l += [L1357N(F, 1)]  # singular value
        l += [L1357N(F, 3)]  # non singular value
        l += [L1357N(F, 5)]  # non singular value
        l += [L1357O(F), L1357P(F), L1357Q(F), L1357R(F)]
        # 1357S(a)=1357S(a') iff a*a'=1
        # 1357S(1)=2357D
        l += [L1357S(F, 0)]  # singular value
        l += [L1357S(F, QQbar(1) / 2)]  # singular value
        l += [L1357S(F, -1)]  # singular value
        # complex singular value
        l += [L1357S(F, QQbar(1) / 2 - QQbar(sqrt(3)) / 2 * i)]
        # complex singular value
        l += [L1357S(F, QQbar(1) / 2 + QQbar(sqrt(3)) / 2 * i)]
        l += [L1357S(F, 3)]  # non singular value
        l += [L1357S(F, 5)]  # non singular value

        # 13457
        # 13457H in Seeley is not a Lie algebra
        l += [L13457A(F), L13457B(F), L13457C(F), L13457D(F),
              L13457E(F), L13457F(F), L13457G(F), L13457I(F)]

        # 12457 has a family
        l += [L12457A(F), L12457B(F), L12457C(F), L12457D(F), L12457E(F),
              L12457F(F), L12457G(F), L12457H(F), L12457I(F),
              L12457J(F), L12457K(F), L12457L(F), L12457M(F)]
        # 12457N(a)=12457N(a') iff a=a' or a=-a'
        # l += [L12457N(F, 0)]  # singular value, same as 12457M
        l += [L12457N(F, 1)]  # non singular value
        l += [L12457N(F, 3)]  # non singular value
        l += [L12457N(F, 5)]  # non singular value

        l += [L12357A(F), L12357B(F), L12357C(F)]

        # 123457 has a family
        l += [L123457A(F), L123457B(F), L123457C(F), L123457D(F),
              L123457E(F), L123457F(F), L123457G(F), L123457H(F)]
        # 123457I(a)=123457I(a') iff a=a'
        l += [L123457I(F, 0)]  # non singular value
        #l += [L123457I(F, 1)]  # singular value, same as 123457G
        l += [L123457I(F, 2)]  # singular value
        l += [L123457I(F, 3)]  # singular value
        l += [L123457I(F, -1)]  # singular value
        # complex singular value
        l += [L123457I(F, QQbar(1) / 2 - QQbar(sqrt(3)) / 2 * i)]
        # complex singular value
        l += [L123457I(F, QQbar(1) / 2 + QQbar(sqrt(3)) / 2 * i)]
        return l

    return NotImplemented
Beispiel #9
0
    def sqrt(self, extend=True, all=False):
        """
        Return a square root of ``self``.

        With default options, the output is an element of the universal
        cyclotomic field when this element is expressed via a single root
        of unity (including rational numbers). Otherwise, return an algebraic
        number.

        INPUT:

        -  ``extend`` -- bool (default: ``True``); if ``True``, might return a
           square root in the algebraic closure of the rationals. If false,
           return a square root in the universal cyclotomic field or raises
           an error.

        -  ``all`` -- bool (default: ``False``); if ``True``, return a
           list of all square roots.

        EXAMPLES::

            sage: UCF = UniversalCyclotomicField()
            sage: UCF(3).sqrt()
            E(12)^7 - E(12)^11
            sage: (UCF(3).sqrt())**2
            3

            sage: r = UCF(-1400 / 143).sqrt()
            sage: r**2
            -1400/143

            sage: E(33).sqrt()
            -E(33)^17
            sage: E(33).sqrt() ** 2
            E(33)

            sage: (3 * E(5)).sqrt()
            -E(60)^11 + E(60)^31
            sage: (3 * E(5)).sqrt() ** 2
            3*E(5)

        Setting ``all=True`` you obtain the two square roots in a list::

            sage: UCF(3).sqrt(all=True)
            [E(12)^7 - E(12)^11, -E(12)^7 + E(12)^11]
            sage: (1 + UCF.zeta(5)).sqrt(all=True)
            [1.209762576525833? + 0.3930756888787117?*I,
             -1.209762576525833? - 0.3930756888787117?*I]

        In the following situation, Sage is not (yet) able to compute a
        square root within the universal cyclotomic field::

            sage: (E(5) + E(5, 2)).sqrt()
            0.7476743906106103? + 1.029085513635746?*I
            sage: (E(5) + E(5, 2)).sqrt(extend=False)
            Traceback (most recent call last):
            ...
            NotImplementedError: sqrt() not fully implemented for elements of Universal Cyclotomic Field
        """
        if all:
            s = self.sqrt(all=False)
            return [s, -s]

        UCF = self.parent()

        # rational case
        if self._obj.IsRat():
            D = self._obj.sage()

            if self._obj.IsInt():
                return UCF_sqrt_int(D, UCF)
            else:
                return UCF_sqrt_int(D.numerator(), UCF) / \
                       UCF_sqrt_int(D.denominator(), UCF)

        # root of unity
        k = self._obj.Conductor()
        coeffs = self._obj.CoeffsCyc(k).sage()
        if sum(bool(x) for x in coeffs) == 1:
            for i, x in enumerate(coeffs):
                if x:
                    break
            return UCF(x).sqrt() * UCF.zeta(2 * k, i)

        # no method to construct square roots yet...
        if extend:
            return QQbar(self).sqrt()
        else:
            raise NotImplementedError(
                "sqrt() not fully implemented for elements of Universal Cyclotomic Field"
            )