示例#1
0
    def statistic(self, func, q=None):
        """
        Return

        .. MATH::

            prod_{(d, \lambda)\in \tau} n_\lambda(q^d)

        where `n_\lambda(q)` is the value returned by ``func`` on the input
        `\lambda`.

        INPUT:

        - ``func`` -- a function that takes a partition to a polynomial in ``q``

        - ``q`` -- an integer or an indeterminate

        EXAMPLES::

            sage: tau = SimilarityClassType([[1, [1]], [1, [2, 1]], [2, [1, 1]]])
            sage: from sage.combinat.similarity_class_type import fq
            sage: tau.statistic(lambda la: prod([fq(m) for m in la.to_exp()]))
            (q^9 - 3*q^8 + 2*q^7 + 2*q^6 - 4*q^5 + 4*q^4 - 2*q^3 - 2*q^2 + 3*q - 1)/q^9
            sage: q = ZZ['q'].gen()
            sage: tau.statistic(lambda la: q**la.size(), q = q)
            q^8
        """
        if q is None:
            q = FractionField(ZZ['q']).gen()
        return prod([PT.statistic(func, q=q) for PT in self])
示例#2
0
    def centralizer_group_card(self, q=None):
        """
        Return the cardinality of the centralizer group of a matrix of type
        ``self`` in a field of order ``q``.

        INPUT:

        ``q`` -- an integer or an indeterminate

        EXAMPLES::

            sage: PT = PrimarySimilarityClassType(1, [])
            sage: PT.centralizer_group_card()
            1
            sage: PT = PrimarySimilarityClassType(2, [1, 1])
            sage: PT.centralizer_group_card()
            q^8 - q^6 - q^4 + q^2
        """
        if q == None:
            R = FractionField(ZZ["q"])
            q = R.gen()
        return self.statistic(centralizer_group_cardinality, q=q)
示例#3
0
    def centralizer_group_card(self, q=None):
        """
        Return the cardinality of the centralizer group of a matrix of type
        ``self`` in a field of order ``q``.

        INPUT:

        ``q`` -- an integer or an indeterminate

        EXAMPLES::

            sage: PT = PrimarySimilarityClassType(1, [])
            sage: PT.centralizer_group_card()
            1
            sage: PT = PrimarySimilarityClassType(2, [1, 1])
            sage: PT.centralizer_group_card()
            q^8 - q^6 - q^4 + q^2
        """
        if q == None:
            R = FractionField(ZZ['q'])
            q = R.gen()
        return self.statistic(centralizer_group_cardinality, q=q)
示例#4
0
def mod5family(a, b):
    """
    Formulas for computing the family of elliptic curves with
    congruent mod-5 representation.

    EXAMPLES::

        sage: from sage.schemes.elliptic_curves.mod5family import mod5family
        sage: mod5family(0,1)
        Elliptic Curve defined by y^2 = x^3 + (t^30+30*t^29+435*t^28+4060*t^27+27405*t^26+142506*t^25+593775*t^24+2035800*t^23+5852925*t^22+14307150*t^21+30045015*t^20+54627300*t^19+86493225*t^18+119759850*t^17+145422675*t^16+155117520*t^15+145422675*t^14+119759850*t^13+86493225*t^12+54627300*t^11+30045015*t^10+14307150*t^9+5852925*t^8+2035800*t^7+593775*t^6+142506*t^5+27405*t^4+4060*t^3+435*t^2+30*t+1) over Fraction Field of Univariate Polynomial Ring in t over Rational Field
    """
    J = 4 * a**3 / (4 * a**3 + 27 * b**2)

    alpha = [0 for _ in range(21)]
    alpha[0] = 1
    alpha[1] = 0
    alpha[2] = 190 * (J - 1)
    alpha[3] = -2280 * (J - 1)**2
    alpha[4] = 855 * (J - 1)**2 * (-17 + 16 * J)
    alpha[5] = 3648 * (J - 1)**3 * (17 - 9 * J)
    alpha[6] = 11400 * (J - 1)**3 * (17 - 8 * J)
    alpha[7] = -27360 * (J - 1)**4 * (17 + 26 * J)
    alpha[8] = 7410 * (J - 1)**4 * (-119 - 448 * J + 432 * J**2)
    alpha[9] = 79040 * (J - 1)**5 * (17 + 145 * J - 108 * J**2)
    alpha[10] = 8892 * (J - 1)**5 * (187 + 2640 * J - 5104 * J**2 +
                                     1152 * J**3)
    alpha[11] = 98800 * (J - 1)**6 * (-17 - 388 * J + 864 * J**2)
    alpha[12] = 7410 * (J - 1)**6 * (-187 - 6160 * J + 24464 * J**2 -
                                     24192 * J**3)
    alpha[13] = 54720 * (J - 1)**7 * (17 + 795 * J - 3944 * J**2 + 9072 * J**3)
    alpha[14] = 2280 * (J - 1)**7 * (221 + 13832 * J - 103792 * J**2 +
                                     554112 * J**3 - 373248 * J**4)
    alpha[15] = 1824 * (J - 1)**8 * (-119 - 9842 * J + 92608 * J**2 -
                                     911520 * J**3 + 373248 * J**4)
    alpha[16] = 4275 * (J - 1)**8 * (-17 - 1792 * J + 23264 * J**2 -
                                     378368 * J**3 + 338688 * J**4)
    alpha[17] = 18240 * (J - 1)**9 * (1 + 133 * J - 2132 * J**2 +
                                      54000 * J**3 - 15552 * J**4)
    alpha[18] = 190 * (J - 1)**9 * (17 + 2784 * J - 58080 * J**2 + 2116864 *
                                    J**3 - 946944 * J**4 + 2985984 * J**5)
    alpha[19] = 360 * (J - 1)**10 * (-1 + 28 * J - 1152 * J**2) * (
        1 + 228 * J + 176 * J**2 + 1728 * J**3)
    alpha[20] = (J - 1)**10 * (-19 - 4560 * J + 144096 * J**2 -
                               9859328 * J**3 - 8798976 * J**4 -
                               226934784 * J**5 + 429981696 * J**6)

    beta = [0 for _ in range(31)]
    beta[0] = 1
    beta[1] = 30
    beta[2] = -435 * (J - 1)
    beta[3] = 580 * (J - 1) * (-7 + 9 * J)
    beta[4] = 3915 * (J - 1)**2 * (7 - 8 * J)
    beta[5] = 1566 * (J - 1)**2 * (91 - 78 * J + 48 * J**2)
    beta[6] = -84825 * (J - 1)**3 * (7 + 16 * J)
    beta[7] = 156600 * (J - 1)**3 * (-13 - 91 * J + 92 * J**2)
    beta[8] = 450225 * (J - 1)**4 * (13 + 208 * J - 144 * J**2)
    beta[9] = 100050 * (J - 1)**4 * (143 + 4004 * J - 5632 * J**2 +
                                     1728 * J**3)
    beta[10] = 30015 * (J - 1)**5 * (-1001 - 45760 * J + 44880 * J**2 -
                                     6912 * J**3)
    beta[11] = 600300 * (J - 1)**5 * (-91 - 6175 * J + 9272 * J**2 -
                                      2736 * J**3)
    beta[12] = 950475 * (J - 1)**6 * (91 + 8840 * J - 7824 * J**2)
    beta[13] = 17108550 * (J - 1)**6 * (7 + 926 * J - 1072 * J**2 + 544 * J**3)
    beta[14] = 145422675 * (J - 1)**7 * (-1 - 176 * J + 48 * J**2 - 384 * J**3)
    beta[15] = 155117520 * (J - 1)**8 * (1 + 228 * J + 176 * J**2 +
                                         1728 * J**3)
    beta[16] = 145422675 * (J - 1)**8 * (1 + 288 * J + 288 * J**2 +
                                         5120 * J**3 - 6912 * J**4)
    beta[17] = 17108550 * (J - 1)**8 * (7 + 2504 * J + 3584 * J**2 + 93184 *
                                        J**3 - 283392 * J**4 + 165888 * J**5)
    beta[18] = 950475 * (J - 1)**9 * (-91 - 39936 * J - 122976 * J**2 -
                                      2960384 * J**3 + 11577600 * J**4 -
                                      5971968 * J**5)
    beta[19] = 600300 * (J - 1)**9 * (-91 - 48243 * J - 191568 * J**2 -
                                      6310304 * J**3 + 40515072 * J**4 -
                                      46455552 * J**5 + 11943936 * J**6)
    beta[20] = 30015 * (J - 1)**10 * (1001 + 634920 * J + 3880800 * J**2 +
                                      142879744 * J**3 - 1168475904 * J**4 +
                                      1188919296 * J**5 - 143327232 * J**6)
    beta[21] = 100050 * (J - 1)**10 * (143 + 107250 * J + 808368 * J**2 +
                                       38518336 * J**3 - 451953408 * J**4 +
                                       757651968 * J**5 - 367276032 * J**6)
    beta[22] = 450225 * (J - 1)**11 * (-13 - 11440 * J - 117216 * J**2 -
                                       6444800 * J**3 + 94192384 * J**4 -
                                       142000128 * J**5 + 95551488 * J**6)
    beta[23] = 156600 * (J - 1)**11 * (
        -13 - 13299 * J - 163284 * J**2 - 11171552 * J**3 + 217203840 * J**4 -
        474406656 * J**5 + 747740160 * J**6 - 429981696 * J**7)
    beta[24] = 6525*(J - 1)**12*(91 + 107536*J + 1680624*J**2 + 132912128*J**3 -\
          3147511552*J**4 + 6260502528*J**5 - 21054173184*J**6 + 10319560704*J**7)
    beta[25] = 1566*(J - 1)**12*(91 + 123292*J + 2261248*J**2 + 216211904*J**3 - \
          6487793920*J**4 + 17369596928*J**5 - 97854234624*J**6 + 96136740864*J**7 - 20639121408*J**8)
    beta[26] = 3915*(J - 1)**13*(-7 - 10816*J - 242352*J**2 - 26620160*J**3 + 953885440*J**4 - \
          2350596096*J**5 + 26796552192*J**6 - 13329432576*J**7)
    beta[27] = 580*(J - 1)**13*(-7 - 12259*J - 317176*J**2 - 41205008*J**3 + \
          1808220160*J**4 - 5714806016*J**5 + 93590857728*J**6 - 70131806208*J**7 - 36118462464*J**8)
    beta[28] = 435*(J - 1)**14*(1 + 1976*J + 60720*J**2 + 8987648*J**3 - 463120640*J**4 + 1359157248*J**5 - \
          40644882432*J**6 - 5016453120*J**7 + 61917364224*J**8)
    beta[29] = 30*(J - 1)**14*(1 + 2218*J + 77680*J**2 + 13365152*J**3 - \
          822366976*J**4 + 2990693888*J**5 - 118286217216*J**6 - 24514928640*J**7 + 509958291456*J**8 - 743008370688*J**9)
    beta[30] = (J - 1)**15*(-1 - 2480*J - 101040*J**2 - 19642496*J**3 + 1399023872*J**4 - \
          4759216128*J**5 + 315623485440*J**6 + 471904911360*J**7 - 2600529297408*J**8 + 8916100448256*J**9)

    R = PolynomialRing(QQ, 't')
    b4 = a * R(alpha)
    b6 = b * R(beta)

    c2 = b4
    c3 = b6
    d = lcm(c2.denominator(), c3.denominator())
    F = FractionField(R)

    E = EllipticCurve(F, [c2 * d**4, c3 * d**6])
    return E
示例#5
0
    def __init__(self, group, base_ring, prec, fix_d, set_d, d_num_prec):
        r"""
        Constructor for the Fourier expansion of some
        (specific, basic) modular forms.

        INPUT:

        - ``group``       - A Hecke triangle group (default: HeckeTriangleGroup(3)).

        - ``base_ring``   - The base ring (default: ZZ)

        - ``prec``        - An integer (default: 10), the default precision used
                            in calculations in the LaurentSeriesRing or PowerSeriesRing.

        - ``fix_d``       - ``True`` or ``False`` (default: ``False``).

                            If ``fix_d == False`` the base ring of the power series
                            is (the fraction field) of the polynomial ring over the base
                            ring in one formal parameter ``d``.

                            If ``fix_d == True`` the formal parameter ``d`` is replaced
                            by its numerical value with numerical precision at least ``d_num_prec``
                            (or exact in case n=3, 4, 6). The base ring of the PowerSeriesRing
                            or LaurentSeriesRing is changed to a common parent of
                            ``base_ring`` and the parent of the mentioned value ``d``.

        - ``set_d``       - A number which replaces the formal parameter ``d``.
                            The base ring of the PowerSeriesRing or LaurentSeriesRing is
                            changed to a common parent of ``base_ring``
                            and the parent of the specified value for ``d``.
                            Note that in particular ``set_d=1`` will produce
                            rational Fourier expansions.

        - ``d_num_prec``  - An integer, a lower bound for the precision of the
                            numerical value of ``d``.

        OUTPUT:

        The constructor for Fourier expansion with the specified settings.

        EXAMPLES::

            sage: MFC = MFSeriesConstructor()
            sage: MFC
            Power series constructor for Hecke modular forms for n=3, base ring=Integer Ring
            with (basic series) precision 10 with formal parameter d
            sage: MFC.group()
            Hecke triangle group for n = 3
            sage: MFC.prec()
            10
            sage: MFC.d().parent()
            Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFC._ZZseries_ring
            Power Series Ring in q over Rational Field

            sage: MFSeriesConstructor(set_d=CC(1))
            Power series constructor for Hecke modular forms for n=3, base ring=Complex Field with 53 bits of precision
            with (basic series) precision 10 with parameter d=1.00000000000000
            
            sage: MFSeriesConstructor(group=4, fix_d=True)
            Power series constructor for Hecke modular forms for n=4, base ring=Rational Field
            with (basic series) precision 10 with parameter d=1/256

            sage: MFSeriesConstructor(group=5, fix_d=True)
            Power series constructor for Hecke modular forms for n=5, base ring=Real Field with 53 bits of precision
            with (basic series) precision 10 with parameter d=0.00705223418128563
        """

        self._group          = group
        self._base_ring      = base_ring
        self._prec           = prec
        self._fix_d          = fix_d
        self._set_d          = set_d
        self._d_num_prec     = d_num_prec

        if (set_d):
            self._coeff_ring = FractionField(base_ring)
            self._d          = set_d
        else:
            self._coeff_ring = FractionField(PolynomialRing(base_ring,"d"))
            self._d          = self._coeff_ring.gen()

        self._ZZseries_ring  = PowerSeriesRing(QQ,'q',default_prec=self._prec)
        self._qseries_ring   = PowerSeriesRing(self._coeff_ring,'q',default_prec=self._prec)
示例#6
0
class MFSeriesConstructor(SageObject,UniqueRepresentation):
    r"""
    Constructor for the Fourier expansion of some
    (specific, basic) modular forms.

    The constructor is used by forms elements in case
    their Fourier expansion is needed or requested.
    """

    @staticmethod
    def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, prec=ZZ(10), fix_d=False, set_d=None, d_num_prec=ZZ(53)):
        r"""
        Return a (cached) instance with canonical parameters.

        In particular in case ``fix_d = True`` or if ``set_d`` is
        set then the ``base_ring`` is replaced by the common parent
        of ``base_ring`` and the parent of ``set_d`` (resp. the
        numerical value of ``d`` in case ``fix_d=True``).

        EXAMPLES::

            sage: MFSeriesConstructor() == MFSeriesConstructor(3, ZZ, 10, False, None, 53)
            True
            sage: MFSeriesConstructor(base_ring = CC, set_d=CC(1)) == MFSeriesConstructor(set_d=CC(1))
            True
            sage: MFSeriesConstructor(group=4, fix_d=True).base_ring() == QQ
            True
            sage: MFSeriesConstructor(group=5, fix_d=True).base_ring() == RR
            True
        """

        if (group==infinity):
            group = HeckeTriangleGroup(infinity)
        else:
            try:
                group = HeckeTriangleGroup(ZZ(group))
            except TypeError:
                group = HeckeTriangleGroup(group.n())
        prec=ZZ(prec)
        #if (prec<1):
        #    raise Exception("prec must be an Integer >=1")

        fix_d = bool(fix_d)
        if (fix_d):
            n = group.n()
            d = group.dvalue()
            if (group.is_arithmetic()):
                d_num_prec = None
                set_d = 1/base_ring(1/d)
            else:
                d_num_prec = ZZ(d_num_prec)
                set_d = group.dvalue().n(d_num_prec)
        else:
            d_num_prec = None

        if (set_d is not None):
            base_ring=(base_ring(1)*set_d).parent()
        #elif (not base_ring.is_exact()):
        #    raise NotImplementedError

        return super(MFSeriesConstructor,cls).__classcall__(cls, group, base_ring, prec, fix_d, set_d, d_num_prec)

    def __init__(self, group, base_ring, prec, fix_d, set_d, d_num_prec):
        r"""
        Constructor for the Fourier expansion of some
        (specific, basic) modular forms.

        INPUT:

        - ``group``       - A Hecke triangle group (default: HeckeTriangleGroup(3)).

        - ``base_ring``   - The base ring (default: ZZ)

        - ``prec``        - An integer (default: 10), the default precision used
                            in calculations in the LaurentSeriesRing or PowerSeriesRing.

        - ``fix_d``       - ``True`` or ``False`` (default: ``False``).

                            If ``fix_d == False`` the base ring of the power series
                            is (the fraction field) of the polynomial ring over the base
                            ring in one formal parameter ``d``.

                            If ``fix_d == True`` the formal parameter ``d`` is replaced
                            by its numerical value with numerical precision at least ``d_num_prec``
                            (or exact in case n=3, 4, 6). The base ring of the PowerSeriesRing
                            or LaurentSeriesRing is changed to a common parent of
                            ``base_ring`` and the parent of the mentioned value ``d``.

        - ``set_d``       - A number which replaces the formal parameter ``d``.
                            The base ring of the PowerSeriesRing or LaurentSeriesRing is
                            changed to a common parent of ``base_ring``
                            and the parent of the specified value for ``d``.
                            Note that in particular ``set_d=1`` will produce
                            rational Fourier expansions.

        - ``d_num_prec``  - An integer, a lower bound for the precision of the
                            numerical value of ``d``.

        OUTPUT:

        The constructor for Fourier expansion with the specified settings.

        EXAMPLES::

            sage: MFC = MFSeriesConstructor()
            sage: MFC
            Power series constructor for Hecke modular forms for n=3, base ring=Integer Ring
            with (basic series) precision 10 with formal parameter d
            sage: MFC.group()
            Hecke triangle group for n = 3
            sage: MFC.prec()
            10
            sage: MFC.d().parent()
            Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFC._ZZseries_ring
            Power Series Ring in q over Rational Field

            sage: MFSeriesConstructor(set_d=CC(1))
            Power series constructor for Hecke modular forms for n=3, base ring=Complex Field with 53 bits of precision
            with (basic series) precision 10 with parameter d=1.00000000000000
            
            sage: MFSeriesConstructor(group=4, fix_d=True)
            Power series constructor for Hecke modular forms for n=4, base ring=Rational Field
            with (basic series) precision 10 with parameter d=1/256

            sage: MFSeriesConstructor(group=5, fix_d=True)
            Power series constructor for Hecke modular forms for n=5, base ring=Real Field with 53 bits of precision
            with (basic series) precision 10 with parameter d=0.00705223418128563
        """

        self._group          = group
        self._base_ring      = base_ring
        self._prec           = prec
        self._fix_d          = fix_d
        self._set_d          = set_d
        self._d_num_prec     = d_num_prec

        if (set_d):
            self._coeff_ring = FractionField(base_ring)
            self._d          = set_d
        else:
            self._coeff_ring = FractionField(PolynomialRing(base_ring,"d"))
            self._d          = self._coeff_ring.gen()

        self._ZZseries_ring  = PowerSeriesRing(QQ,'q',default_prec=self._prec)
        self._qseries_ring   = PowerSeriesRing(self._coeff_ring,'q',default_prec=self._prec)

    def _repr_(self):
        r"""
        Return the string representation of ``self``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True)
            Power series constructor for Hecke modular forms for n=4, base ring=Rational Field
            with (basic series) precision 10 with parameter d=1/256

            sage: MFSeriesConstructor(group=5)
            Power series constructor for Hecke modular forms for n=5, base ring=Integer Ring
            with (basic series) precision 10 with formal parameter d
        """

        if (self._set_d):
            return "Power series constructor for Hecke modular forms for n={}, base ring={} with (basic series) precision {} with parameter d={}".\
                format(self._group.n(), self._base_ring, self._prec, self._d)
        else:
            return "Power series constructor for Hecke modular forms for n={}, base ring={} with (basic series) precision {} with formal parameter d".\
                format(self._group.n(), self._base_ring, self._prec)

    def group(self):
        r"""
        Return the (Hecke triangle) group of ``self``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True).group()
            Hecke triangle group for n = 4
        """

        return self._group

    def hecke_n(self):
        r"""
        Return the parameter ``n`` of the (Hecke triangle) group of ``self``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True).hecke_n()
            4
        """

        return self._group.n()

    def base_ring(self):
        r"""
        Return base ring of ``self``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=5, fix_d=True).base_ring()
            Real Field with 53 bits of precision
            sage: MFSeriesConstructor(group=5, fix_d=True, d_num_prec=100).base_ring()
            Real Field with 100 bits of precision
        """

        return self._base_ring

    def prec(self):
        r"""
        Return the used default precision for the PowerSeriesRing or LaurentSeriesRing.

        EXAMPLES::

            sage: MFSeriesConstructor(group=5, fix_d=True).prec()
            10
            sage: MFSeriesConstructor(group=5, prec=20).prec()
            20
        """

        return self._prec

    def fix_d(self):
        r"""
        Return whether the numerical value for the parameter
        ``d`` will be substituted or not.
        
        Note: Depending on whether ``set_d`` is ``None`` or
        not ``d`` might still be substituted despite ``fix_d``
        being ``False``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=5, fix_d=True, set_d=1).fix_d()
            True
            sage: MFSeriesConstructor(group=5, fix_d=True, set_d=1).set_d()
            0.00705223418128563
            sage: MFSeriesConstructor(group=5, set_d=1).fix_d()
            False
        """

        return self._fix_d

    def set_d(self):
        r"""
        Return the numerical value which is substituted for
        the parameter ``d``. Default: ``None``, meaning
        the formal parameter ``d`` is used.

        EXAMPLES::

            sage: MFSeriesConstructor(group=5, fix_d=True, set_d=1).set_d()
            0.00705223418128563
            sage: MFSeriesConstructor(group=5, set_d=1).set_d()
            1
            sage: MFSeriesConstructor(group=5, set_d=1).set_d().parent()
            Integer Ring
        """

        return self._set_d

    def is_exact(self):
        r"""
        Return whether used ``base_ring`` is exact.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True).is_exact()
            True
            sage: MFSeriesConstructor(group=5, fix_d=True).is_exact()
            False
            sage: MFSeriesConstructor(group=5, set_d=1).is_exact()
            True
        """

        return self._base_ring.is_exact()

    def d(self):
        r"""
        Return the formal parameter ``d`` respectively
        its (possibly numerical) value in case ``set_d``
        is not ``None``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True).d()
            1/256
            sage: MFSeriesConstructor(group=4).d()
            d
            sage: MFSeriesConstructor(group=4).d().parent()
            Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, fix_d=True).d()
            0.00705223418128563
            sage: MFSeriesConstructor(group=5, set_d=1).d()
            1
        """

        return self._d

    def q(self):
        r"""
        Return the generator of the used PowerSeriesRing.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True).q()
            q
            sage: MFSeriesConstructor(group=4, fix_d=True).q().parent()
            Power Series Ring in q over Rational Field
            sage: MFSeriesConstructor(group=5, fix_d=True).q().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return self._qseries_ring.gen()

    def coeff_ring(self):
        r"""
        Return coefficient ring of ``self``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True).coeff_ring()
            Rational Field
            sage: MFSeriesConstructor(group=4).coeff_ring()
            Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, fix_d=True).coeff_ring()
            Real Field with 53 bits of precision
            sage: MFSeriesConstructor(group=5).coeff_ring()
            Fraction Field of Univariate Polynomial Ring in d over Integer Ring
        """

        return self._coeff_ring

    def qseries_ring(self):
        r"""
        Return the used PowerSeriesRing.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, fix_d=True).qseries_ring()
            Power Series Ring in q over Rational Field
            sage: MFSeriesConstructor(group=4).qseries_ring()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, fix_d=True).qseries_ring()
            Power Series Ring in q over Real Field with 53 bits of precision
            sage: MFSeriesConstructor(group=5).qseries_ring()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
        """

        return self._qseries_ring

    @cached_method
    def J_inv_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``J_inv``,
        where ``d`` is replaced by ``1``.

        This is the main function used to determine all Fourier expansions!

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).J_inv_ZZ()
            q^-1 + 31/72 + 1823/27648*q + O(q^2)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).J_inv_ZZ()
            q^-1 + 79/200 + 42877/640000*q + O(q^2)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).J_inv_ZZ().parent()
            Laurent Series Ring in q over Rational Field
        """

        F1       = lambda a,b:   self._ZZseries_ring(\
                       [ ZZ(0) ] + [\
                           rising_factorial(a,k) * rising_factorial(b,k) / (ZZ(k).factorial())**2 * sum([\
                               ZZ(1)/(a+j)+ZZ(1)/(b+j)-ZZ(2)/ZZ(1+j) for j in range(ZZ(0),ZZ(k))\
                           ]) for k in range(ZZ(1),ZZ(self._prec+1))
                       ], ZZ(self._prec+1)\
                   )
        F        = lambda a,b,c: self._ZZseries_ring([\
                       rising_factorial(a,k) * rising_factorial(b,k) / rising_factorial(c,k) / (ZZ(k).factorial())\
                       for k in range(ZZ(0),ZZ(self._prec+1))\
                   ], ZZ(self._prec+1))
        a        = self._group.alpha()
        b        = self._group.beta()
        Phi      = F1(a,b) / F(a,b,ZZ(1))
        q        = self._ZZseries_ring.gen()
        J_inv_ZZ = ZZ(1) / ((q*Phi.exp()).reversion())
        return J_inv_ZZ

    @cached_method
    def J_inv(self):
        r"""
        Return the Fourier expansion of ``J_inv``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).J_inv()
            1/1728*q^-1 + 31/72 + 1823/16*q + O(q^2)
            sage: MFSeriesConstructor(prec=3).J_inv_ZZ() == MFSeriesConstructor(prec=3, set_d=1).J_inv()
            True

            sage: MFSeriesConstructor(group=5, prec=3).J_inv()
            d*q^-1 + 79/200 + 42877/(640000*d)*q + O(q^2)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).J_inv()
            0.00705223418128563*q^-1 + 0.395000000000000 + 9.49987064777062*q + O(q^2)

            sage: MFSeriesConstructor(group=5, prec=3).J_inv().parent()
            Laurent Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).J_inv().parent()
            Laurent Series Ring in q over Real Field with 53 bits of precision
        """

        return self.J_inv_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def F_rho_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``F_rho``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).F_rho_ZZ()
            1 + 5/36*q + 5/6912*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_rho_ZZ()
            1 + 7/100*q + 21/160000*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_rho_ZZ().parent()
            Power Series Ring in q over Rational Field
        """

        q = self._ZZseries_ring.gen()
        n = self.hecke_n()
        temp_expr = ((-q*self.J_inv_ZZ().derivative())**2/(self.J_inv_ZZ()*(self.J_inv_ZZ()-1))).power_series()
        F_rho_ZZ = (temp_expr.log()/(n-2)).exp()
        return F_rho_ZZ

    @cached_method
    def F_rho(self):
        r"""
        Return the Fourier expansion of ``F_rho``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).F_rho()
            1 + 240*q + 2160*q^2 + O(q^3)

            sage: MFSeriesConstructor(prec=3).F_rho_ZZ() == MFSeriesConstructor(prec=3, set_d=1).F_rho()
            True

            sage: MFSeriesConstructor(group=5, prec=3).F_rho()
            1 + 7/(100*d)*q + 21/(160000*d^2)*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_rho()
            1.00000000000000 + 9.92593243510795*q + 2.63903932249093*q^2 + O(q^3)

            sage: MFSeriesConstructor(group=5, prec=3).F_rho().parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_rho().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return self.F_rho_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def F_i_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``F_i``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).F_i_ZZ()
            1 - 7/24*q - 77/13824*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_i_ZZ()
            1 - 13/40*q - 351/64000*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_i_ZZ().parent()
            Power Series Ring in q over Rational Field
        """

        q = self._ZZseries_ring.gen()
        n = self.hecke_n()
        temp_expr = ((-q*self.J_inv_ZZ().derivative())**n/(self.J_inv_ZZ()**(n-1)*(self.J_inv_ZZ()-1))).power_series()
        F_i_ZZ = (temp_expr.log()/(n-2)).exp()
        return F_i_ZZ

    @cached_method
    def F_i(self):
        r"""
        Return the Fourier expansion of ``F_i``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).F_i()
            1 - 504*q - 16632*q^2 + O(q^3)
            sage: MFSeriesConstructor(prec=3).F_i_ZZ() == MFSeriesConstructor(prec=3, set_d=1).F_i()
            True

            sage: MFSeriesConstructor(group=5, prec=3).F_i()
            1 - 13/(40*d)*q - 351/(64000*d^2)*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_i()
            1.00000000000000 - 46.0846863058583*q - 110.274143118371*q^2 + O(q^3)

            sage: MFSeriesConstructor(group=5, prec=3).F_i().parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_i().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return self.F_i_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def F_inf_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``F_inf``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).F_inf_ZZ()
            q - 1/72*q^2 + 7/82944*q^3 + O(q^4)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_inf_ZZ()
            q - 9/200*q^2 + 279/640000*q^3 + O(q^4)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_inf_ZZ().parent()
            Power Series Ring in q over Rational Field
        """

        q = self._ZZseries_ring.gen()
        n = self.hecke_n()
        temp_expr  = ((-q*self.J_inv_ZZ().derivative())**(2*n)/(self.J_inv_ZZ()**(2*n-2)*(self.J_inv_ZZ()-1)**n)/q**(n-2)).power_series()
        F_inf_ZZ = (temp_expr.log()/(n-2)).exp()*q
        return F_inf_ZZ

    @cached_method
    def F_inf(self):
        r"""
        Return the Fourier expansion of ``F_inf``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).F_inf()
            q - 24*q^2 + 252*q^3 + O(q^4)
            sage: MFSeriesConstructor(prec=3).F_inf_ZZ() == MFSeriesConstructor(prec=3, set_d=1).F_inf()
            True

            sage: MFSeriesConstructor(group=5, prec=3).F_inf()
            q - 9/(200*d)*q^2 + 279/(640000*d^2)*q^3 + O(q^4)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_inf()
            0.000000000000000 + 1.00000000000000*q - 6.38095656542654*q^2 + 8.76538060684488*q^3 + O(q^4)

            sage: MFSeriesConstructor(group=5, prec=3).F_inf().parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).F_inf().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return self._d*self.F_inf_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def G_inv_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``G_inv``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, prec=3).G_inv_ZZ()
            q^-1 - 3/32 - 955/16384*q + O(q^2)
            sage: MFSeriesConstructor(group=8, prec=3, fix_d=True).G_inv_ZZ()
            q^-1 - 15/128 - 15139/262144*q + O(q^2)
            sage: MFSeriesConstructor(group=8, prec=3, fix_d=True).G_inv_ZZ().parent()
            Laurent Series Ring in q over Rational Field
        """

        n = self.hecke_n()
        if (ZZ(2).divides(n)):
            return self.F_i_ZZ()*(self.F_rho_ZZ()**(ZZ(n/ZZ(2))))/self.F_inf_ZZ()
        else:
            #return self._qseries_ring([])
            raise Exception("G_inv doesn't exist for n={}.".format(self.hecke_n()))
    @cached_method
    def G_inv(self):
        r"""
        Return the Fourier expansion of ``G_inv``.

        EXAMPLES::

            sage: MFSeriesConstructor(group=4, prec=3, fix_d=True).G_inv()
            1/16777216*q^-1 - 3/2097152 - 955/4194304*q + O(q^2)
            sage: MFSeriesConstructor(group=4, prec=3).G_inv_ZZ() == MFSeriesConstructor(group=4, prec=3, set_d=1).G_inv()
            True

            sage: MFSeriesConstructor(group=8, prec=3).G_inv()
            d^3*q^-1 - 15*d^2/128 - 15139*d/262144*q + O(q^2)
            sage: MFSeriesConstructor(group=8, prec=3, fix_d=True).G_inv()
            1.64838830030189e-6*q^-1 - 0.0000163526310530017 - 0.000682197999433738*q + O(q^2)

            sage: MFSeriesConstructor(group=8, prec=3).G_inv().parent()
            Laurent Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=8, prec=3, fix_d=True).G_inv().parent()
            Laurent Series Ring in q over Real Field with 53 bits of precision
        """

        return (self._d)**2*self.G_inv_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def E4_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``E_4``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).E4_ZZ()
            1 + 5/36*q + 5/6912*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E4_ZZ()
            1 + 21/100*q + 483/32000*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E4_ZZ().parent()
            Power Series Ring in q over Rational Field
        """

        q = self._ZZseries_ring.gen()
        E4_ZZ = ((-q*self.J_inv_ZZ().derivative())**2/(self.J_inv_ZZ()*(self.J_inv_ZZ()-1))).power_series()
        return E4_ZZ

    @cached_method
    def E4(self):
        r"""
        Return the Fourier expansion of ``E_4``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).E4()
            1 + 240*q + 2160*q^2 + O(q^3)
            sage: MFSeriesConstructor(prec=3).E4_ZZ() == MFSeriesConstructor(prec=3, set_d=1).E4()
            True

            sage: MFSeriesConstructor(group=5, prec=3).E4()
            1 + 21/(100*d)*q + 483/(32000*d^2)*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E4()
            1.00000000000000 + 29.7777973053239*q + 303.489522086457*q^2 + O(q^3)

            sage: MFSeriesConstructor(group=5, prec=3).E4().parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E4().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return self.E4_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def E6_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``E_6``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).E6_ZZ()
            1 - 7/24*q - 77/13824*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E6_ZZ()
            1 - 37/200*q - 14663/320000*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E6_ZZ().parent()
            Power Series Ring in q over Rational Field
        """

        q = self._ZZseries_ring.gen()
        n = self.hecke_n()
        E6_ZZ = ((-q*self.J_inv_ZZ().derivative())**3/(self.J_inv_ZZ()**2*(self.J_inv_ZZ()-1))).power_series()
        return E6_ZZ

    @cached_method
    def E6(self):
        r"""
        Return the Fourier expansion of ``E_6``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).E6()
            1 - 504*q - 16632*q^2 + O(q^3)
            sage: MFSeriesConstructor(prec=3).E6_ZZ() == MFSeriesConstructor(prec=3, set_d=1).E6()
            True

            sage: MFSeriesConstructor(group=5, prec=3).E6()
            1 - 37/(200*d)*q - 14663/(320000*d^2)*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E6()
            1.00000000000000 - 26.2328214356424*q - 921.338894897250*q^2 + O(q^3)

            sage: MFSeriesConstructor(group=5, prec=3).E6().parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E6().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return self.E6_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def Delta_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``Delta``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).Delta_ZZ()
            q - 1/72*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).Delta_ZZ()
            71/50*q + 28267/16000*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).Delta_ZZ().parent()
            Power Series Ring in q over Rational Field
        """

        n = self.hecke_n()
        return self.E4_ZZ()**(2*n-6)*(self.E4_ZZ()**n-self.E6_ZZ()**2)

    @cached_method
    def Delta(self):
        r"""
        Return the Fourier expansion of ``Delta``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).Delta()
            q - 24*q^2 + O(q^3)
            sage: MFSeriesConstructor(prec=3).Delta_ZZ() == MFSeriesConstructor(prec=3, set_d=1).Delta()
            True

            sage: MFSeriesConstructor(group=5, prec=3).Delta()
            71/50*q + 28267/(16000*d)*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).Delta()
            0.000000000000000 + 1.42000000000000*q + 250.514582270711*q^2 + O(q^3)

            sage: MFSeriesConstructor(group=5, prec=3).Delta().parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).Delta().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return (self._d)*self.Delta_ZZ()(self._qseries_ring.gen()/self._d)

    @cached_method
    def E2_ZZ(self):
        r"""
        Return the rational Fourier expansion of ``E2``,
        where ``d`` is replaced by ``1``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3).E2_ZZ()
            1 - 1/72*q - 1/41472*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E2_ZZ()
            1 - 9/200*q - 369/320000*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E2_ZZ().parent()
            Power Series Ring in q over Rational Field
        """

        q = self._ZZseries_ring.gen()
        E2_ZZ = (q*self.F_inf_ZZ().derivative())/self.F_inf_ZZ()
        return E2_ZZ

    @cached_method
    def E2(self):
        r"""
        Return the Fourier expansion of ``E2``.

        EXAMPLES::

            sage: MFSeriesConstructor(prec=3, fix_d=True).E2()
            1 - 24*q - 72*q^2 + O(q^3)
            sage: MFSeriesConstructor(prec=3).E2_ZZ() == MFSeriesConstructor(prec=3, set_d=1).E2()
            True

            sage: MFSeriesConstructor(group=5, prec=3).E2()
            1 - 9/(200*d)*q - 369/(320000*d^2)*q^2 + O(q^3)
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E2()
            1.00000000000000 - 6.38095656542654*q - 23.1858454761703*q^2 + O(q^3)

            sage: MFSeriesConstructor(group=5, prec=3).E2().parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MFSeriesConstructor(group=5, prec=3, fix_d=True).E2().parent()
            Power Series Ring in q over Real Field with 53 bits of precision
        """

        return self.E2_ZZ()(self._qseries_ring.gen()/self._d)
示例#7
0
def rational_type(f, n=ZZ(3), base_ring=ZZ):
    r"""
    Return the basic analytic properties that can be determined
    directly from the specified rational function ``f``
    which is interpreted as a representation of an
    element of a FormsRing for the Hecke Triangle group
    with parameter ``n`` and the specified ``base_ring``.

    In particular the following degree of the generators is assumed:

    `deg(1) := (0, 1)`
    `deg(x) := (4/(n-2), 1)`
    `deg(y) := (2n/(n-2), -1)`
    `deg(z) := (2, -1)`

    The meaning of homogeneous elements changes accordingly.

    INPUT:

    - ``f``              -- A rational function in ``x,y,z,d`` over ``base_ring``.

    - ``n``              -- An integer greater or equal to `3` corresponding
                            to the ``HeckeTriangleGroup`` with that parameter
                            (default: `3`).

    - ``base_ring``      -- The base ring of the corresponding forms ring, resp.
                            polynomial ring (default: ``ZZ``).

    OUTPUT:

    A tuple ``(elem, h**o, k, ep, analytic_type)`` describing the basic
    analytic properties of `f` (with the interpretation indicated above).

    - ``elem``           -- ``True`` if `f` has a homogeneous denominator.

    - ``h**o``           -- ``True`` if `f` also has a homogeneous numerator.

    - ``k``              -- ``None`` if `f` is not homogeneous, otherwise
                            the weight of `f` (which is the first component
                            of its degree).

    - ``ep``             -- ``None`` if `f` is not homogeneous, otherwise
                            the multiplier of `f` (which is the second component
                            of its degree)

    - ``analytic_type``  -- The ``AnalyticType`` of `f`.

    For the zero function the degree `(0, 1)` is choosen.

    This function is (heavily) used to determine the type of elements
    and to check if the element really is contained in its parent.


    EXAMPLES::

        sage: from sage.modular.modform_hecketriangle.constructor import rational_type
        sage: (x,y,z,d) = var("x,y,z,d")

        sage: rational_type(0, n=4)
        (True, True, 0, 1, zero)

        sage: rational_type(1, n=12)
        (True, True, 0, 1, modular)

        sage: rational_type(x^3 - y^2)
        (True, True, 12, 1, cuspidal)

        sage: rational_type(x * z, n=7)
        (True, True, 14/5, -1, quasi modular)

        sage: rational_type(1/(x^3 - y^2) + z/d)
        (True, False, None, None, quasi weakly holomorphic modular)

        sage: rational_type(x^3/(x^3 - y^2))
        (True, True, 0, 1, weakly holomorphic modular)

        sage: rational_type(1/(x + z))
        (False, False, None, None, None)

        sage: rational_type(1/x + 1/z)
        (True, False, None, None, quasi meromorphic modular)

        sage: rational_type(d/x, n=10)
        (True, True, -1/2, 1, meromorphic modular)

        sage: rational_type(1.1 * z * (x^8-y^2), n=8, base_ring=CC)
        (True, True, 22/3, -1, quasi cuspidal)

        sage: rational_type(x-y^2, n=infinity)
        (True, True, 4, 1, modular)

        sage: rational_type(x*(x-y^2), n=infinity)
        (True, True, 8, 1, cuspidal)

        sage: rational_type(1/x, n=infinity)
        (True, True, -4, 1, weakly holomorphic modular)
    """

    from .analytic_type import AnalyticType
    AT = AnalyticType()

    # Determine whether f is zero
    if (f == 0):
        #       elem, h**o, k,     ep,    analytic_type
        return (True, True, QQ(0), ZZ(1), AT([]))

    analytic_type = AT(["quasi", "mero"])

    R = PolynomialRing(base_ring, 'x,y,z,d')
    F = FractionField(R)
    (x, y, z, d) = R.gens()
    R2 = PolynomialRing(PolynomialRing(base_ring, 'd'), 'x,y,z')
    dhom = R.hom(R2.gens() + (R2.base().gen(), ), R2)

    f = F(f)

    num = R(f.numerator())
    denom = R(f.denominator())
    ep_num = set([
        ZZ(1) - 2 * ((sum([g.exponents()[0][m] for m in [1, 2]])) % 2)
        for g in dhom(num).monomials()
    ])
    ep_denom = set([
        ZZ(1) - 2 * ((sum([g.exponents()[0][m] for m in [1, 2]])) % 2)
        for g in dhom(denom).monomials()
    ])

    if (n == infinity):
        hom_num = R(num.subs(x=x**4, y=y**2, z=z**2))
        hom_denom = R(denom.subs(x=x**4, y=y**2, z=z**2))
    else:
        n = ZZ(n)
        hom_num = R(num.subs(x=x**4, y=y**(2 * n), z=z**(2 * (n - 2))))
        hom_denom = R(denom.subs(x=x**4, y=y**(2 * n), z=z**(2 * (n - 2))))

    # Determine whether the denominator of f is homogeneous
    if (len(ep_denom) == 1 and dhom(hom_denom).is_homogeneous()):
        elem = True
    else:
        #       elem,  h**o,  k,    ep,   analytic_type
        return (False, False, None, None, None)

    # Determine whether f is homogeneous
    if (len(ep_num) == 1 and dhom(hom_num).is_homogeneous()):
        h**o = True
        if (n == infinity):
            weight = (dhom(hom_num).degree() - dhom(hom_denom).degree())
        else:
            weight = (dhom(hom_num).degree() - dhom(hom_denom).degree()) / (n -
                                                                            2)
        ep = ep_num.pop() / ep_denom.pop()
    # TODO: decompose f (resp. its degrees) into homogeneous parts
    else:
        h**o = False
        weight = None
        ep = None

    # Note that we intentionally leave out the d-factor!
    if (n == infinity):
        finf_pol = (x - y**2)
    else:
        finf_pol = x**n - y**2

    # Determine whether f is modular
    if not ((num.degree(z) > 0) or (denom.degree(z) > 0)):
        analytic_type = analytic_type.reduce_to("mero")

    # Determine whether f is holomorphic
    if (dhom(denom).is_constant()):
        analytic_type = analytic_type.reduce_to(["quasi", "holo"])
        # Determine whether f is cuspidal in the sense that finf divides it...
        # Bug in singular: finf_pol.divides(1.0) fails over RR
        if (not dhom(num).is_constant() and finf_pol.divides(num)):
            if (n != infinity or x.divides(num)):
                analytic_type = analytic_type.reduce_to(["quasi", "cusp"])
    else:
        # -> Because of a bug with singular in some cases
        try:
            while (finf_pol.divides(denom)):
                # a simple "denom /= finf_pol" is strangely not enough for non-exact rings
                # and dividing would/may result with an element of the quotient ring of the polynomial ring
                denom = denom.quo_rem(finf_pol)[0]
                denom = R(denom)
            if (n == infinity):
                while (x.divides(denom)):
                    # a simple "denom /= x" is strangely not enough for non-exact rings
                    # and dividing would/may result with an element of the quotient ring of the polynomial ring
                    denom = denom.quo_rem(x)[0]
                    denom = R(denom)
        except TypeError:
            pass

        # Determine whether f is weakly holomorphic in the sense that at most powers of finf occur in denom
        if (dhom(denom).is_constant()):
            analytic_type = analytic_type.reduce_to(["quasi", "weak"])

    return (elem, h**o, weight, ep, analytic_type)