Elements of graded rings of modular forms for Hecke triangle groups - Modular Forms

Skip to content
Back to top
View this page
Edit this page

# Elements of graded rings of modular forms for Hecke triangle groups

AUTHORS:

- Jonas Jermann (2013): initial version

class sage.modular.modform_hecketriangle.graded_ring_element.FormsRingElement(parent, rat)

  Bases: `CommutativeAlgebraElement`, `UniqueRepresentation`

  Element of a FormsRing.

  AT = Analytic Type
  AnalyticType

    alias of `AnalyticType`

  analytic_type()

    Return the analytic type of `self`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms

        sage: # needs sage.symbolic
        sage: x, y, z, d = var("x,y,z,d")
        sage: QuasiMeromorphicModularFormsRing(n=5)(x/z+d).analytic_type()
        quasi meromorphic modular
        sage: QuasiMeromorphicModularFormsRing(n=5)((y^3-z^5)/(x^5-y^2)+y-d).analytic_type()
        quasi weakly holomorphic modular
        sage: QuasiMeromorphicModularFormsRing(n=5)(x^2+y-d).analytic_type()
        modular

        sage: QuasiMeromorphicModularForms(n=18).J_inv().analytic_type()
        weakly holomorphic modular
        sage: QuasiMeromorphicModularForms(n=18).f_inf().analytic_type()
        cuspidal
        sage: QuasiMeromorphicModularForms(n=infinity).f_inf().analytic_type()
        modular

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms

        >>> # needs sage.symbolic
        >>> x, y, z, d = var("x,y,z,d")
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))(x/z+d).analytic_type()
        quasi meromorphic modular
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))((y**Integer(3)-z**Integer(5))/(x**Integer(5)-y**Integer(2))+y-d).analytic_type()
        quasi weakly holomorphic modular
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))(x**Integer(2)+y-d).analytic_type()
        modular

        >>> QuasiMeromorphicModularForms(n=Integer(18)).J_inv().analytic_type()
        weakly holomorphic modular
        >>> QuasiMeromorphicModularForms(n=Integer(18)).f_inf().analytic_type()
        cuspidal
        >>> QuasiMeromorphicModularForms(n=infinity).f_inf().analytic_type()
        modular

  as_ring_element()

    Coerce `self` into the graded ring of its parent.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.space import CuspForms
        sage: Delta = CuspForms(k=12).Delta()
        sage: Delta.parent()
        CuspForms(n=3, k=12, ep=1) over Integer Ring
        sage: Delta.as_ring_element()
        f_rho^3*d - f_i^2*d
        sage: Delta.as_ring_element().parent()
        CuspFormsRing(n=3) over Integer Ring

        sage: CuspForms(n=infinity, k=12).Delta().as_ring_element()
        -E4^2*f_i^2*d + E4^3*d

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.space import CuspForms
        >>> Delta = CuspForms(k=Integer(12)).Delta()
        >>> Delta.parent()
        CuspForms(n=3, k=12, ep=1) over Integer Ring
        >>> Delta.as_ring_element()
        f_rho^3*d - f_i^2*d
        >>> Delta.as_ring_element().parent()
        CuspFormsRing(n=3) over Integer Ring

        >>> CuspForms(n=infinity, k=Integer(12)).Delta().as_ring_element()
        -E4^2*f_i^2*d + E4^3*d

  base_ring()

    Return base ring of `self.parent()`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.space import ModularForms
        sage: ModularForms(n=12, k=4, base_ring=CC).E4().base_ring()
        Complex Field with 53 bits of precision

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.space import ModularForms
        >>> ModularForms(n=Integer(12), k=Integer(4), base_ring=CC).E4().base_ring()
        Complex Field with 53 bits of precision

  coeff_ring()

    Return coefficient ring of `self`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
        sage: ModularFormsRing().E6().coeff_ring()
        Fraction Field of Univariate Polynomial Ring in d over Integer Ring

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
        >>> ModularFormsRing().E6().coeff_ring()
        Fraction Field of Univariate Polynomial Ring in d over Integer Ring

  degree()

    Return the degree of `self` in the graded ring. If `self` is not homogeneous, then `(None, None)` is returned.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import ModularForms
        sage: x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        sage: QuasiModularFormsRing()(x+y).degree() == (None, None)                 # needs sage.symbolic
        True
        sage: ModularForms(n=18).f_i().degree()
        (9/4, -1)
        sage: ModularForms(n=infinity).f_rho().degree()
        (0, 1)

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import ModularForms
        >>> x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        >>> QuasiModularFormsRing()(x+y).degree() == (None, None)                 # needs sage.symbolic
        True
        >>> ModularForms(n=Integer(18)).f_i().degree()
        (9/4, -1)
        >>> ModularForms(n=infinity).f_rho().degree()
        (0, 1)

  denominator()

    Return the denominator of `self`. I.e. the (properly reduced) new form corresponding to the numerator of `self.rat()`.

    Note that the parent of `self` might (probably will) change.

    EXAMPLES:

    Sage

        sage: # needs sage.symbolic
        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        sage: x, y, z, d = var("x,y,z,d")
        sage: QuasiMeromorphicModularFormsRing(n=5).Delta().full_reduce().denominator()
        1 + O(q^5)
        sage: QuasiMeromorphicModularFormsRing(n=5)((y^3-z^5)/(x^5-y^2)+y-d).denominator()
        f_rho^5 - f_i^2
        sage: QuasiMeromorphicModularFormsRing(n=5)((y^3-z^5)/(x^5-y^2)+y-d).denominator().parent()
        QuasiModularFormsRing(n=5) over Integer Ring
        sage: QuasiMeromorphicModularForms(n=5, k=-2, ep=-1)(x/y).denominator()
        1 - 13/(40*d)*q - 351/(64000*d^2)*q^2 - 13819/(76800000*d^3)*q^3 - 1163669/(491520000000*d^4)*q^4 + O(q^5)
        sage: QuasiMeromorphicModularForms(n=5, k=-2, ep=-1)(x/y).denominator().parent()
        QuasiModularForms(n=5, k=10/3, ep=-1) over Integer Ring
        sage: (QuasiMeromorphicModularForms(n=infinity, k=-6, ep=-1)(y/(x*(x-y^2)))).denominator()
        -64*q - 512*q^2 - 768*q^3 + 4096*q^4 + O(q^5)
        sage: (QuasiMeromorphicModularForms(n=infinity, k=-6, ep=-1)(y/(x*(x-y^2)))).denominator().parent()
        QuasiModularForms(n=+Infinity, k=8, ep=1) over Integer Ring

    Python

        >>> from sage.all import *
        >>> # needs sage.symbolic
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        >>> x, y, z, d = var("x,y,z,d")
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5)).Delta().full_reduce().denominator()
        1 + O(q^5)
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))((y**Integer(3)-z**Integer(5))/(x**Integer(5)-y**Integer(2))+y-d).denominator()
        f_rho^5 - f_i^2
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))((y**Integer(3)-z**Integer(5))/(x**Integer(5)-y**Integer(2))+y-d).denominator().parent()
        QuasiModularFormsRing(n=5) over Integer Ring
        >>> QuasiMeromorphicModularForms(n=Integer(5), k=-Integer(2), ep=-Integer(1))(x/y).denominator()
        1 - 13/(40*d)*q - 351/(64000*d^2)*q^2 - 13819/(76800000*d^3)*q^3 - 1163669/(491520000000*d^4)*q^4 + O(q^5)
        >>> QuasiMeromorphicModularForms(n=Integer(5), k=-Integer(2), ep=-Integer(1))(x/y).denominator().parent()
        QuasiModularForms(n=5, k=10/3, ep=-1) over Integer Ring
        >>> (QuasiMeromorphicModularForms(n=infinity, k=-Integer(6), ep=-Integer(1))(y/(x*(x-y**Integer(2))))).denominator()
        -64*q - 512*q^2 - 768*q^3 + 4096*q^4 + O(q^5)
        >>> (QuasiMeromorphicModularForms(n=infinity, k=-Integer(6), ep=-Integer(1))(y/(x*(x-y**Integer(2))))).denominator().parent()
        QuasiModularForms(n=+Infinity, k=8, ep=1) over Integer Ring

  derivative()

    Return the derivative `d/dq = lambda/(2*pi*i) d/dtau` of `self`.

    Note that the parent might (probably will) change. In particular its analytic type will be extended to contain “quasi”.

    If `parent.has_reduce_hom() == True` then the result is reduced to be an element of the corresponding forms space if possible.

    In particular this is the case if `self` is a (homogeneous) element of a forms space.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: MR = QuasiMeromorphicModularFormsRing(n=7, red_hom=True)
        sage: n = MR.hecke_n()
        sage: E2 = MR.E2().full_reduce()
        sage: E6 = MR.E6().full_reduce()
        sage: f_rho = MR.f_rho().full_reduce()
        sage: f_i = MR.f_i().full_reduce()
        sage: f_inf = MR.f_inf().full_reduce()

        sage: derivative(f_rho) == 1/n * (f_rho*E2 - f_i)
        True
        sage: derivative(f_i)   == 1/2 * (f_i*E2 - f_rho**(n-1))
        True
        sage: derivative(f_inf) == f_inf * E2
        True
        sage: derivative(f_inf).parent()
        QuasiCuspForms(n=7, k=38/5, ep=-1) over Integer Ring
        sage: derivative(E2)    == (n-2)/(4*n) * (E2**2 - f_rho**(n-2))
        True
        sage: derivative(E2).parent()
        QuasiModularForms(n=7, k=4, ep=1) over Integer Ring

        sage: MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        sage: E2 = MR.E2().full_reduce()
        sage: E4 = MR.E4().full_reduce()
        sage: E6 = MR.E6().full_reduce()
        sage: f_i = MR.f_i().full_reduce()
        sage: f_inf = MR.f_inf().full_reduce()

        sage: derivative(E4)    == E4 * (E2 - f_i)
        True
        sage: derivative(f_i)   == 1/2 * (f_i*E2 - E4)
        True
        sage: derivative(f_inf) == f_inf * E2
        True
        sage: derivative(f_inf).parent()
        QuasiModularForms(n=+Infinity, k=6, ep=-1) over Integer Ring
        sage: derivative(E2)    == 1/4 * (E2**2 - E4)
        True
        sage: derivative(E2).parent()
        QuasiModularForms(n=+Infinity, k=4, ep=1) over Integer Ring

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> MR = QuasiMeromorphicModularFormsRing(n=Integer(7), red_hom=True)
        >>> n = MR.hecke_n()
        >>> E2 = MR.E2().full_reduce()
        >>> E6 = MR.E6().full_reduce()
        >>> f_rho = MR.f_rho().full_reduce()
        >>> f_i = MR.f_i().full_reduce()
        >>> f_inf = MR.f_inf().full_reduce()

        >>> derivative(f_rho) == Integer(1)/n * (f_rho*E2 - f_i)
        True
        >>> derivative(f_i)   == Integer(1)/Integer(2) * (f_i*E2 - f_rho**(n-Integer(1)))
        True
        >>> derivative(f_inf) == f_inf * E2
        True
        >>> derivative(f_inf).parent()
        QuasiCuspForms(n=7, k=38/5, ep=-1) over Integer Ring
        >>> derivative(E2)    == (n-Integer(2))/(Integer(4)*n) * (E2**Integer(2) - f_rho**(n-Integer(2)))
        True
        >>> derivative(E2).parent()
        QuasiModularForms(n=7, k=4, ep=1) over Integer Ring

        >>> MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        >>> E2 = MR.E2().full_reduce()
        >>> E4 = MR.E4().full_reduce()
        >>> E6 = MR.E6().full_reduce()
        >>> f_i = MR.f_i().full_reduce()
        >>> f_inf = MR.f_inf().full_reduce()

        >>> derivative(E4)    == E4 * (E2 - f_i)
        True
        >>> derivative(f_i)   == Integer(1)/Integer(2) * (f_i*E2 - E4)
        True
        >>> derivative(f_inf) == f_inf * E2
        True
        >>> derivative(f_inf).parent()
        QuasiModularForms(n=+Infinity, k=6, ep=-1) over Integer Ring
        >>> derivative(E2)    == Integer(1)/Integer(4) * (E2**Integer(2) - E4)
        True
        >>> derivative(E2).parent()
        QuasiModularForms(n=+Infinity, k=4, ep=1) over Integer Ring

  diff_op(op, new_parent=None)

    Return the differential operator `op` applied to `self`. If `parent.has_reduce_hom() == True` then the result is reduced to be an element of the corresponding forms space if possible.

    INPUT:

    - `op` – an element of `self.parent().diff_alg()`. I.e. an element of the algebra over `QQ` of differential operators generated by `X, Y, Z, dX, dY, DZ`, where e.g. `X` corresponds to the multiplication by `x` (resp. `f_rho`) and `dX` corresponds to `d/dx`.

      To expect a homogeneous result after applying the operator to a homogeneous element it should should be homogeneous operator (with respect to the usual, special grading).

    - `new_parent` – try to convert the result to the specified `new_parent`. If `new_parent == None` (default) then the parent is extended to a “quasi meromorphic” ring.

    OUTPUT: the new element

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: MR = QuasiMeromorphicModularFormsRing(n=8, red_hom=True)
        sage: (X,Y,Z,dX,dY,dZ) = MR.diff_alg().gens()
        sage: n = MR.hecke_n()
        sage: mul_op = 4/(n-2)*X*dX + 2*n/(n-2)*Y*dY + 2*Z*dZ
        sage: der_op = MR._derivative_op()
        sage: ser_op = MR._serre_derivative_op()
        sage: der_op == ser_op + (n-2)/(4*n)*Z*mul_op
        True

        sage: Delta = MR.Delta().full_reduce()
        sage: E2 = MR.E2().full_reduce()
        sage: Delta.diff_op(mul_op) == 12*Delta
        True
        sage: Delta.diff_op(mul_op).parent()
        QuasiMeromorphicModularForms(n=8, k=12, ep=1) over Integer Ring
        sage: Delta.diff_op(mul_op, Delta.parent()).parent()
        CuspForms(n=8, k=12, ep=1) over Integer Ring
        sage: E2.diff_op(mul_op, E2.parent()) == 2*E2
        True
        sage: Delta.diff_op(Z*mul_op, Delta.parent().extend_type("quasi", ring=True)) == 12*E2*Delta
        True

        sage: ran_op = X + Y*X*dY*dX + dZ + dX^2
        sage: Delta.diff_op(ran_op)
        f_rho^19*d + 306*f_rho^16*d - f_rho^11*f_i^2*d - 20*f_rho^10*f_i^2*d - 90*f_rho^8*f_i^2*d
        sage: E2.diff_op(ran_op)
        f_rho*E2 + 1

        sage: MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        sage: (X,Y,Z,dX,dY,dZ) = MR.diff_alg().gens()
        sage: mul_op = 4*X*dX + 2*Y*dY + 2*Z*dZ
        sage: der_op = MR._derivative_op()
        sage: ser_op = MR._serre_derivative_op()
        sage: der_op == ser_op + Z/4*mul_op
        True

        sage: Delta = MR.Delta().full_reduce()
        sage: E2 = MR.E2().full_reduce()
        sage: Delta.diff_op(mul_op) == 12*Delta
        True
        sage: Delta.diff_op(mul_op).parent()
        QuasiMeromorphicModularForms(n=+Infinity, k=12, ep=1) over Integer Ring
        sage: Delta.diff_op(mul_op, Delta.parent()).parent()
        CuspForms(n=+Infinity, k=12, ep=1) over Integer Ring
        sage: E2.diff_op(mul_op, E2.parent()) == 2*E2
        True
        sage: Delta.diff_op(Z*mul_op, Delta.parent().extend_type("quasi", ring=True)) == 12*E2*Delta
        True

        sage: ran_op = X + Y*X*dY*dX + dZ + dX^2
        sage: Delta.diff_op(ran_op)
        -E4^3*f_i^2*d + E4^4*d - 4*E4^2*f_i^2*d - 2*f_i^2*d + 6*E4*d
        sage: E2.diff_op(ran_op)
        E4*E2 + 1

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> MR = QuasiMeromorphicModularFormsRing(n=Integer(8), red_hom=True)
        >>> (X,Y,Z,dX,dY,dZ) = MR.diff_alg().gens()
        >>> n = MR.hecke_n()
        >>> mul_op = Integer(4)/(n-Integer(2))*X*dX + Integer(2)*n/(n-Integer(2))*Y*dY + Integer(2)*Z*dZ
        >>> der_op = MR._derivative_op()
        >>> ser_op = MR._serre_derivative_op()
        >>> der_op == ser_op + (n-Integer(2))/(Integer(4)*n)*Z*mul_op
        True

        >>> Delta = MR.Delta().full_reduce()
        >>> E2 = MR.E2().full_reduce()
        >>> Delta.diff_op(mul_op) == Integer(12)*Delta
        True
        >>> Delta.diff_op(mul_op).parent()
        QuasiMeromorphicModularForms(n=8, k=12, ep=1) over Integer Ring
        >>> Delta.diff_op(mul_op, Delta.parent()).parent()
        CuspForms(n=8, k=12, ep=1) over Integer Ring
        >>> E2.diff_op(mul_op, E2.parent()) == Integer(2)*E2
        True
        >>> Delta.diff_op(Z*mul_op, Delta.parent().extend_type("quasi", ring=True)) == Integer(12)*E2*Delta
        True

        >>> ran_op = X + Y*X*dY*dX + dZ + dX**Integer(2)
        >>> Delta.diff_op(ran_op)
        f_rho^19*d + 306*f_rho^16*d - f_rho^11*f_i^2*d - 20*f_rho^10*f_i^2*d - 90*f_rho^8*f_i^2*d
        >>> E2.diff_op(ran_op)
        f_rho*E2 + 1

        >>> MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        >>> (X,Y,Z,dX,dY,dZ) = MR.diff_alg().gens()
        >>> mul_op = Integer(4)*X*dX + Integer(2)*Y*dY + Integer(2)*Z*dZ
        >>> der_op = MR._derivative_op()
        >>> ser_op = MR._serre_derivative_op()
        >>> der_op == ser_op + Z/Integer(4)*mul_op
        True

        >>> Delta = MR.Delta().full_reduce()
        >>> E2 = MR.E2().full_reduce()
        >>> Delta.diff_op(mul_op) == Integer(12)*Delta
        True
        >>> Delta.diff_op(mul_op).parent()
        QuasiMeromorphicModularForms(n=+Infinity, k=12, ep=1) over Integer Ring
        >>> Delta.diff_op(mul_op, Delta.parent()).parent()
        CuspForms(n=+Infinity, k=12, ep=1) over Integer Ring
        >>> E2.diff_op(mul_op, E2.parent()) == Integer(2)*E2
        True
        >>> Delta.diff_op(Z*mul_op, Delta.parent().extend_type("quasi", ring=True)) == Integer(12)*E2*Delta
        True

        >>> ran_op = X + Y*X*dY*dX + dZ + dX**Integer(2)
        >>> Delta.diff_op(ran_op)
        -E4^3*f_i^2*d + E4^4*d - 4*E4^2*f_i^2*d - 2*f_i^2*d + 6*E4*d
        >>> E2.diff_op(ran_op)
        E4*E2 + 1

  ep()

    Return the multiplier of `self`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import ModularForms
        sage: x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        sage: QuasiModularFormsRing()(x+y).ep() is None                             # needs sage.symbolic
        True
        sage: ModularForms(n=18).f_i().ep()
        -1
        sage: ModularForms(n=infinity).E2().ep()
        -1

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import ModularForms
        >>> x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        >>> QuasiModularFormsRing()(x+y).ep() is None                             # needs sage.symbolic
        True
        >>> ModularForms(n=Integer(18)).f_i().ep()
        -1
        >>> ModularForms(n=infinity).E2().ep()
        -1

  evaluate(tau, prec=None, num_prec=None, check=False)

    Try to return `self` evaluated at a point `tau` in the upper half plane, where `self` is interpreted as a function in `tau`, where `q=exp(2*pi*i*tau)`.

    Note that this interpretation might not make sense (and fail) for certain (many) choices of (`base_ring`, `tau.parent()`).

    It is possible to evaluate at points of `HyperbolicPlane`. In this case the coordinates of the upper half plane model are used.

    To obtain a precise and fast result the parameters `prec` and `num_prec` both have to be considered/balanced. A high `prec` value is usually quite costly.

    INPUT:

    - `tau` – `infinity` or an element of the upper half plane. E.g. with parent `AA` or `CC`.

    - `prec` – integer, namely the precision used for the Fourier expansion. If `prec == None` (default) then the default precision of `self.parent()` is used

    - `num_prec` – integer, namely the minimal numerical precision used for `tau` and `d`. If `num_prec == None` (default) then the default numerical precision of `self.parent()` is used.

    - `check` – if `True` then the order of `tau` is checked. Otherwise the order is only considered for `tau = infinity, i, rho, -1/rho`. Default: `False`.

    OUTPUT:

    The (numerical) evaluated function value.

    ALGORITHM:

    1. If the order of `self` at `tau` is known and nonzero: Return `0` resp. `infinity`.

    2. Else if `tau==infinity` and the order is zero: Return the constant Fourier coefficient of `self`.

    3. Else if `self` is homogeneous and modular:

       1. Because of the (modular) transformation property of `self` the evaluation at `tau` is given by the evaluation at `w` multiplied by `aut_factor(A,w)`.

       2. The evaluation at `w` is calculated by evaluating the truncated Fourier expansion of `self` at `q(w)`.

       Note that this is much faster and more precise than a direct evaluation at `tau`.

    4. Else if `self` is exactly `E2`:

       1. The same procedure as before is applied (with the aut_factor from the corresponding modular space).

       2. Except that at the end a correction term for the quasimodular form `E2` of the form `4*lambda/(2*pi*i)*n/(n-2) * c*(c*w + d)` (resp. `4/(pi*i) * c*(c*w + d)` for `n=infinity`) has to be added, where `lambda = 2*cos(pi/n)` (resp `lambda = 2` for `n=infinity`) and `c,d` are the lower entries of the matrix `A`.

    5. Else:

       1. Evaluate `f_rho, f_i, E2` at `tau` using the above procedures. If `n=infinity` use `E4` instead of `f_rho`.

       2. Substitute `x=f_rho(tau), y=f_i(tau), z=E2(tau)` and the numerical value of `d` for `d` in `self.rat()`. If `n=infinity` then substitute `x=E4(tau)` instead.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: MR = QuasiMeromorphicModularFormsRing(n=5, red_hom=True)
        sage: f_rho = MR.f_rho().full_reduce()
        sage: f_i   = MR.f_i().full_reduce()
        sage: f_inf = MR.f_inf().full_reduce()
        sage: E2    = MR.E2().full_reduce()
        sage: E4    = MR.E4().full_reduce()
        sage: rho   = MR.group().rho()

        sage: f_rho(rho)
        0
        sage: f_rho(rho + 1e-100)    # since rho == rho + 1e-100
        0
        sage: f_rho(rho + 1e-6)
        2.525...e-10 - 3.884...e-6*I
        sage: f_i(i)
        0
        sage: f_i(i + 1e-1000)  # rel tol 5e-2
        -6.08402217494586e-14 - 4.10147008296517e-1000*I
        sage: f_inf(infinity)
        0

        sage: i = I = QuadraticField(-1, 'I').gen()
        sage: z = -1/(-1/(2*i+30)-1)
        sage: z
        2/965*I + 934/965
        sage: E4(z)
        32288.05588811... - 118329.8566016...*I
        sage: E4(z, prec=30, num_prec=100)    # long time
        32288.0558872351130041311053... - 118329.856600349999751420381...*I
        sage: E2(z)
        409.3144737105... + 100.6926857489...*I
        sage: E2(z, prec=30, num_prec=100)    # long time
        409.314473710489761254584951... + 100.692685748952440684513866...*I
        sage: (E2^2-E4)(z)
        125111.2655383... + 200759.8039479...*I
        sage: (E2^2-E4)(z, prec=30, num_prec=100)    # long time
        125111.265538336196262200469... + 200759.803948009905410385699...*I

        sage: (E2^2-E4)(infinity)
        0
        sage: (1/(E2^2-E4))(infinity)
        +Infinity
        sage: ((E2^2-E4)/f_inf)(infinity)
        -3/(10*d)

        sage: G = HeckeTriangleGroup(n=8)
        sage: MR = QuasiMeromorphicModularFormsRing(group=G, red_hom=True)
        sage: f_rho = MR.f_rho().full_reduce()
        sage: f_i   = MR.f_i().full_reduce()
        sage: E2    = MR.E2().full_reduce()

        sage: z = AlgebraicField()(1/10+13/10*I)
        sage: A = G.V(4)
        sage: S = G.S()
        sage: T = G.T()
        sage: A == (T*S)**3*T
        True
        sage: az = A.acton(z)
        sage: az == (A[0,0]*z + A[0,1]) / (A[1,0]*z + A[1,1])
        True

        sage: f_rho(z)
        1.03740476727... + 0.0131941034523...*I
        sage: f_rho(az)
        -2.29216470688... - 1.46235057536...*I
        sage: k = f_rho.weight()
        sage: aut_fact = f_rho.ep()^3 * (((T*S)**2*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        sage: abs(aut_fact - f_rho.parent().aut_factor(A, z)) < 1e-12
        True
        sage: aut_fact * f_rho(z)
        -2.29216470688... - 1.46235057536...*I

        sage: f_rho.parent().default_num_prec(1000)
        sage: f_rho.parent().default_prec(300)
        sage: (f_rho.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*z/G.lam()))    # long time
        1.0374047672719462149821251... + 0.013194103452368974597290332...*I
        sage: (f_rho.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*az/G.lam()))    # long time
        -2.2921647068881834598616367... - 1.4623505753697635207183406...*I

        sage: f_i(z)
        0.667489320423... - 0.118902824870...*I
        sage: f_i(az)
        14.5845388476... - 28.4604652892...*I
        sage: k = f_i.weight()
        sage: aut_fact = f_i.ep()^3 * (((T*S)**2*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        sage: abs(aut_fact - f_i.parent().aut_factor(A, z)) < 1e-12
        True
        sage: aut_fact * f_i(z)
        14.5845388476... - 28.4604652892...*I

        sage: f_i.parent().default_num_prec(1000)
        sage: f_i.parent().default_prec(300)
        sage: (f_i.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*z/G.lam()))    # long time
        0.66748932042300250077433252... - 0.11890282487028677063054267...*I
        sage: (f_i.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*az/G.lam()))    # long time
        14.584538847698600875918891... - 28.460465289220303834894855...*I

        sage: f = f_rho*E2
        sage: f(z)
        0.966024386418... - 0.0138894699429...*I
        sage: f(az)
        -15.9978074989... - 29.2775758341...*I
        sage: k = f.weight()
        sage: aut_fact = f.ep()^3 * (((T*S)**2*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        sage: abs(aut_fact - f.parent().aut_factor(A, z)) < 1e-12
        True
        sage: k2 = f_rho.weight()
        sage: aut_fact2 = f_rho.ep() * (((T*S)**2*T).acton(z)/AlgebraicField()(i))**k2 * (((T*S)*T).acton(z)/AlgebraicField()(i))**k2 * (T.acton(z)/AlgebraicField()(i))**k2
        sage: abs(aut_fact2 - f_rho.parent().aut_factor(A, z)) < 1e-12
        True
        sage: cor_term = (4 * G.n() / (G.n()-2) * A.c() * (A.c()*z+A.d())) / (2*pi*i).n(1000) * G.lam()
        sage: aut_fact*f(z) + cor_term*aut_fact2*f_rho(z)
        -15.9978074989... - 29.2775758341...*I

        sage: f.parent().default_num_prec(1000)
        sage: f.parent().default_prec(300)
        sage: (f.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*z/G.lam()))    # long time
        0.96602438641867296777809436... - 0.013889469942995530807311503...*I
        sage: (f.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*az/G.lam()))    # long time
        -15.997807498958825352887040... - 29.277575834123246063432206...*I

        sage: MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        sage: f_i   = MR.f_i().full_reduce()
        sage: f_inf = MR.f_inf().full_reduce()
        sage: E2    = MR.E2().full_reduce()
        sage: E4    = MR.E4().full_reduce()

        sage: f_i(i)
        0
        sage: f_i(i + 1e-1000)
        2.991...e-12 - 3.048...e-1000*I
        sage: f_inf(infinity)
        0

        sage: z = -1/(-1/(2*i+30)-1)
        sage: E4(z, prec=15)
        804.0722034... + 211.9278206...*I
        sage: E4(z, prec=30, num_prec=100)    # long time
        803.928382417... + 211.889914044...*I
        sage: E2(z)
        2.438455612... - 39.48442265...*I
        sage: E2(z, prec=30, num_prec=100)    # long time
        2.43968197227756036957475... - 39.4842637577742677851431...*I
        sage: (E2^2-E4)(z)
        -2265.442515... - 380.3197877...*I
        sage: (E2^2-E4)(z, prec=30, num_prec=100)    # long time
        -2265.44251550679807447320... - 380.319787790548788238792...*I

        sage: (E2^2-E4)(infinity)
        0
        sage: (1/(E2^2-E4))(infinity)
        +Infinity
        sage: ((E2^2-E4)/f_inf)(infinity)
        -1/(2*d)

        sage: G = HeckeTriangleGroup(n=Infinity)
        sage: z = AlgebraicField()(1/10+13/10*I)
        sage: A = G.V(4)
        sage: S = G.S()
        sage: T = G.T()
        sage: A == (T*S)**3*T
        True
        sage: az = A.acton(z)
        sage: az == (A[0,0]*z + A[0,1]) / (A[1,0]*z + A[1,1])
        True

        sage: f_i(z)
        0.6208853409... - 0.1212525492...*I
        sage: f_i(az)
        6.103314419... + 20.42678597...*I
        sage: k = f_i.weight()
        sage: aut_fact = f_i.ep()^3 * (((T*S)**2*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        sage: abs(aut_fact - f_i.parent().aut_factor(A, z)) < 1e-12
        True
        sage: aut_fact * f_i(z)
        6.103314419... + 20.42678597...*I

        sage: f_i.parent().default_num_prec(1000)
        sage: f_i.parent().default_prec(300)
        sage: (f_i.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*z/G.lam()))    # long time
        0.620885340917559158572271... - 0.121252549240996430425967...*I
        sage: (f_i.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*az/G.lam()))    # long time
        6.10331441975198186745017... + 20.4267859728657976382684...*I

        sage: f = f_i*E2
        sage: f(z)
        0.5349190275... - 0.1322370856...*I
        sage: f(az)
        -140.4711702... + 469.0793692...*I
        sage: k = f.weight()
        sage: aut_fact = f.ep()^3 * (((T*S)**2*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        sage: abs(aut_fact - f.parent().aut_factor(A, z)) < 1e-12
        True
        sage: k2 = f_i.weight()
        sage: aut_fact2 = f_i.ep() * (((T*S)**2*T).acton(z)/AlgebraicField()(i))**k2 * (((T*S)*T).acton(z)/AlgebraicField()(i))**k2 * (T.acton(z)/AlgebraicField()(i))**k2
        sage: abs(aut_fact2 - f_i.parent().aut_factor(A, z)) < 1e-12
        True
        sage: cor_term = (4 * A.c() * (A.c()*z+A.d())) / (2*pi*i).n(1000) * G.lam()
        sage: aut_fact*f(z) + cor_term*aut_fact2*f_i(z)
        -140.4711702... + 469.0793692...*I

        sage: f.parent().default_num_prec(1000)
        sage: f.parent().default_prec(300)
        sage: (f.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*z/G.lam()))    # long time
        0.534919027587592616802582... - 0.132237085641931661668338...*I

        sage: (f.q_expansion_fixed_d().polynomial())(exp((2*pi*i).n(1000)*az/G.lam()))    # long time
        -140.471170232432551196978... + 469.079369280804086032719...*I

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> MR = QuasiMeromorphicModularFormsRing(n=Integer(5), red_hom=True)
        >>> f_rho = MR.f_rho().full_reduce()
        >>> f_i   = MR.f_i().full_reduce()
        >>> f_inf = MR.f_inf().full_reduce()
        >>> E2    = MR.E2().full_reduce()
        >>> E4    = MR.E4().full_reduce()
        >>> rho   = MR.group().rho()

        >>> f_rho(rho)
        0
        >>> f_rho(rho + RealNumber('1e-100'))    # since rho == rho + 1e-100
        0
        >>> f_rho(rho + RealNumber('1e-6'))
        2.525...e-10 - 3.884...e-6*I
        >>> f_i(i)
        0
        >>> f_i(i + RealNumber('1e-1000'))  # rel tol 5e-2
        -6.08402217494586e-14 - 4.10147008296517e-1000*I
        >>> f_inf(infinity)
        0

        >>> i = I = QuadraticField(-Integer(1), 'I').gen()
        >>> z = -Integer(1)/(-Integer(1)/(Integer(2)*i+Integer(30))-Integer(1))
        >>> z
        2/965*I + 934/965
        >>> E4(z)
        32288.05588811... - 118329.8566016...*I
        >>> E4(z, prec=Integer(30), num_prec=Integer(100))    # long time
        32288.0558872351130041311053... - 118329.856600349999751420381...*I
        >>> E2(z)
        409.3144737105... + 100.6926857489...*I
        >>> E2(z, prec=Integer(30), num_prec=Integer(100))    # long time
        409.314473710489761254584951... + 100.692685748952440684513866...*I
        >>> (E2**Integer(2)-E4)(z)
        125111.2655383... + 200759.8039479...*I
        >>> (E2**Integer(2)-E4)(z, prec=Integer(30), num_prec=Integer(100))    # long time
        125111.265538336196262200469... + 200759.803948009905410385699...*I

        >>> (E2**Integer(2)-E4)(infinity)
        0
        >>> (Integer(1)/(E2**Integer(2)-E4))(infinity)
        +Infinity
        >>> ((E2**Integer(2)-E4)/f_inf)(infinity)
        -3/(10*d)

        >>> G = HeckeTriangleGroup(n=Integer(8))
        >>> MR = QuasiMeromorphicModularFormsRing(group=G, red_hom=True)
        >>> f_rho = MR.f_rho().full_reduce()
        >>> f_i   = MR.f_i().full_reduce()
        >>> E2    = MR.E2().full_reduce()

        >>> z = AlgebraicField()(Integer(1)/Integer(10)+Integer(13)/Integer(10)*I)
        >>> A = G.V(Integer(4))
        >>> S = G.S()
        >>> T = G.T()
        >>> A == (T*S)**Integer(3)*T
        True
        >>> az = A.acton(z)
        >>> az == (A[Integer(0),Integer(0)]*z + A[Integer(0),Integer(1)]) / (A[Integer(1),Integer(0)]*z + A[Integer(1),Integer(1)])
        True

        >>> f_rho(z)
        1.03740476727... + 0.0131941034523...*I
        >>> f_rho(az)
        -2.29216470688... - 1.46235057536...*I
        >>> k = f_rho.weight()
        >>> aut_fact = f_rho.ep()**Integer(3) * (((T*S)**Integer(2)*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        >>> abs(aut_fact - f_rho.parent().aut_factor(A, z)) < RealNumber('1e-12')
        True
        >>> aut_fact * f_rho(z)
        -2.29216470688... - 1.46235057536...*I

        >>> f_rho.parent().default_num_prec(Integer(1000))
        >>> f_rho.parent().default_prec(Integer(300))
        >>> (f_rho.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*z/G.lam()))    # long time
        1.0374047672719462149821251... + 0.013194103452368974597290332...*I
        >>> (f_rho.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*az/G.lam()))    # long time
        -2.2921647068881834598616367... - 1.4623505753697635207183406...*I

        >>> f_i(z)
        0.667489320423... - 0.118902824870...*I
        >>> f_i(az)
        14.5845388476... - 28.4604652892...*I
        >>> k = f_i.weight()
        >>> aut_fact = f_i.ep()**Integer(3) * (((T*S)**Integer(2)*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        >>> abs(aut_fact - f_i.parent().aut_factor(A, z)) < RealNumber('1e-12')
        True
        >>> aut_fact * f_i(z)
        14.5845388476... - 28.4604652892...*I

        >>> f_i.parent().default_num_prec(Integer(1000))
        >>> f_i.parent().default_prec(Integer(300))
        >>> (f_i.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*z/G.lam()))    # long time
        0.66748932042300250077433252... - 0.11890282487028677063054267...*I
        >>> (f_i.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*az/G.lam()))    # long time
        14.584538847698600875918891... - 28.460465289220303834894855...*I

        >>> f = f_rho*E2
        >>> f(z)
        0.966024386418... - 0.0138894699429...*I
        >>> f(az)
        -15.9978074989... - 29.2775758341...*I
        >>> k = f.weight()
        >>> aut_fact = f.ep()**Integer(3) * (((T*S)**Integer(2)*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        >>> abs(aut_fact - f.parent().aut_factor(A, z)) < RealNumber('1e-12')
        True
        >>> k2 = f_rho.weight()
        >>> aut_fact2 = f_rho.ep() * (((T*S)**Integer(2)*T).acton(z)/AlgebraicField()(i))**k2 * (((T*S)*T).acton(z)/AlgebraicField()(i))**k2 * (T.acton(z)/AlgebraicField()(i))**k2
        >>> abs(aut_fact2 - f_rho.parent().aut_factor(A, z)) < RealNumber('1e-12')
        True
        >>> cor_term = (Integer(4) * G.n() / (G.n()-Integer(2)) * A.c() * (A.c()*z+A.d())) / (Integer(2)*pi*i).n(Integer(1000)) * G.lam()
        >>> aut_fact*f(z) + cor_term*aut_fact2*f_rho(z)
        -15.9978074989... - 29.2775758341...*I

        >>> f.parent().default_num_prec(Integer(1000))
        >>> f.parent().default_prec(Integer(300))
        >>> (f.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*z/G.lam()))    # long time
        0.96602438641867296777809436... - 0.013889469942995530807311503...*I
        >>> (f.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*az/G.lam()))    # long time
        -15.997807498958825352887040... - 29.277575834123246063432206...*I

        >>> MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        >>> f_i   = MR.f_i().full_reduce()
        >>> f_inf = MR.f_inf().full_reduce()
        >>> E2    = MR.E2().full_reduce()
        >>> E4    = MR.E4().full_reduce()

        >>> f_i(i)
        0
        >>> f_i(i + RealNumber('1e-1000'))
        2.991...e-12 - 3.048...e-1000*I
        >>> f_inf(infinity)
        0

        >>> z = -Integer(1)/(-Integer(1)/(Integer(2)*i+Integer(30))-Integer(1))
        >>> E4(z, prec=Integer(15))
        804.0722034... + 211.9278206...*I
        >>> E4(z, prec=Integer(30), num_prec=Integer(100))    # long time
        803.928382417... + 211.889914044...*I
        >>> E2(z)
        2.438455612... - 39.48442265...*I
        >>> E2(z, prec=Integer(30), num_prec=Integer(100))    # long time
        2.43968197227756036957475... - 39.4842637577742677851431...*I
        >>> (E2**Integer(2)-E4)(z)
        -2265.442515... - 380.3197877...*I
        >>> (E2**Integer(2)-E4)(z, prec=Integer(30), num_prec=Integer(100))    # long time
        -2265.44251550679807447320... - 380.319787790548788238792...*I

        >>> (E2**Integer(2)-E4)(infinity)
        0
        >>> (Integer(1)/(E2**Integer(2)-E4))(infinity)
        +Infinity
        >>> ((E2**Integer(2)-E4)/f_inf)(infinity)
        -1/(2*d)

        >>> G = HeckeTriangleGroup(n=Infinity)
        >>> z = AlgebraicField()(Integer(1)/Integer(10)+Integer(13)/Integer(10)*I)
        >>> A = G.V(Integer(4))
        >>> S = G.S()
        >>> T = G.T()
        >>> A == (T*S)**Integer(3)*T
        True
        >>> az = A.acton(z)
        >>> az == (A[Integer(0),Integer(0)]*z + A[Integer(0),Integer(1)]) / (A[Integer(1),Integer(0)]*z + A[Integer(1),Integer(1)])
        True

        >>> f_i(z)
        0.6208853409... - 0.1212525492...*I
        >>> f_i(az)
        6.103314419... + 20.42678597...*I
        >>> k = f_i.weight()
        >>> aut_fact = f_i.ep()**Integer(3) * (((T*S)**Integer(2)*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        >>> abs(aut_fact - f_i.parent().aut_factor(A, z)) < RealNumber('1e-12')
        True
        >>> aut_fact * f_i(z)
        6.103314419... + 20.42678597...*I

        >>> f_i.parent().default_num_prec(Integer(1000))
        >>> f_i.parent().default_prec(Integer(300))
        >>> (f_i.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*z/G.lam()))    # long time
        0.620885340917559158572271... - 0.121252549240996430425967...*I
        >>> (f_i.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*az/G.lam()))    # long time
        6.10331441975198186745017... + 20.4267859728657976382684...*I

        >>> f = f_i*E2
        >>> f(z)
        0.5349190275... - 0.1322370856...*I
        >>> f(az)
        -140.4711702... + 469.0793692...*I
        >>> k = f.weight()
        >>> aut_fact = f.ep()**Integer(3) * (((T*S)**Integer(2)*T).acton(z)/AlgebraicField()(i))**k * (((T*S)*T).acton(z)/AlgebraicField()(i))**k * (T.acton(z)/AlgebraicField()(i))**k
        >>> abs(aut_fact - f.parent().aut_factor(A, z)) < RealNumber('1e-12')
        True
        >>> k2 = f_i.weight()
        >>> aut_fact2 = f_i.ep() * (((T*S)**Integer(2)*T).acton(z)/AlgebraicField()(i))**k2 * (((T*S)*T).acton(z)/AlgebraicField()(i))**k2 * (T.acton(z)/AlgebraicField()(i))**k2
        >>> abs(aut_fact2 - f_i.parent().aut_factor(A, z)) < RealNumber('1e-12')
        True
        >>> cor_term = (Integer(4) * A.c() * (A.c()*z+A.d())) / (Integer(2)*pi*i).n(Integer(1000)) * G.lam()
        >>> aut_fact*f(z) + cor_term*aut_fact2*f_i(z)
        -140.4711702... + 469.0793692...*I

        >>> f.parent().default_num_prec(Integer(1000))
        >>> f.parent().default_prec(Integer(300))
        >>> (f.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*z/G.lam()))    # long time
        0.534919027587592616802582... - 0.132237085641931661668338...*I

        >>> (f.q_expansion_fixed_d().polynomial())(exp((Integer(2)*pi*i).n(Integer(1000))*az/G.lam()))    # long time
        -140.471170232432551196978... + 469.079369280804086032719...*I

    It is possible to evaluate at points of `HyperbolicPlane`:

    Sage

        sage: # needs sage.symbolic
        sage: p = HyperbolicPlane().PD().get_point(-I/2)
        sage: bool(p.to_model('UHP').coordinates() == I/3)
        True
        sage: E4(p) == E4(I/3)
        True
        sage: p = HyperbolicPlane().PD().get_point(I)
        sage: f_inf(p, check=True) == 0
        True
        sage: (1/(E2^2-E4))(p) == infinity
        True

    [Python]

        >>> from sage.all import *
        >>> # needs sage.symbolic
        >>> p = HyperbolicPlane().PD().get_point(-I/Integer(2))
        >>> bool(p.to_model('UHP').coordinates() == I/Integer(3))
        True
        >>> E4(p) == E4(I/Integer(3))
        True
        >>> p = HyperbolicPlane().PD().get_point(I)
        >>> f_inf(p, check=True) == Integer(0)
        True
        >>> (Integer(1)/(E2**Integer(2)-E4))(p) == infinity
        True

  full_reduce()

    Convert `self` into its reduced parent.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: Delta = QuasiMeromorphicModularFormsRing().Delta()
        sage: Delta
        f_rho^3*d - f_i^2*d
        sage: Delta.full_reduce()
        q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5)
        sage: Delta.full_reduce().parent() == Delta.reduced_parent()
        True

        sage: QuasiMeromorphicModularFormsRing().Delta().full_reduce().parent()
        CuspForms(n=3, k=12, ep=1) over Integer Ring

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> Delta = QuasiMeromorphicModularFormsRing().Delta()
        >>> Delta
        f_rho^3*d - f_i^2*d
        >>> Delta.full_reduce()
        q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5)
        >>> Delta.full_reduce().parent() == Delta.reduced_parent()
        True

        >>> QuasiMeromorphicModularFormsRing().Delta().full_reduce().parent()
        CuspForms(n=3, k=12, ep=1) over Integer Ring

  group()

    Return the (Hecke triangle) group of `self.parent()`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.space import ModularForms
        sage: ModularForms(n=12, k=4).E4().group()
        Hecke triangle group for n = 12

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.space import ModularForms
        >>> ModularForms(n=Integer(12), k=Integer(4)).E4().group()
        Hecke triangle group for n = 12

  hecke_n()

    Return the parameter `n` of the (Hecke triangle) group of `self.parent()`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.space import ModularForms
        sage: ModularForms(n=12, k=6).E6().hecke_n()
        12

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.space import ModularForms
        >>> ModularForms(n=Integer(12), k=Integer(6)).E6().hecke_n()
        12

  is_cuspidal()

    Return whether `self` is cuspidal.

    This means that `self` is holomorphic and `f_inf` divides the numerator.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms
        sage: x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        sage: QuasiModularFormsRing(n=5)(y^3-z^5).is_cuspidal()                     # needs sage.symbolic
        False
        sage: QuasiModularFormsRing(n=5)(z*x^5-z*y^2).is_cuspidal()                 # needs sage.symbolic
        True
        sage: QuasiModularForms(n=18).Delta().is_cuspidal()
        True
        sage: QuasiModularForms(n=18).f_rho().is_cuspidal()
        False
        sage: QuasiModularForms(n=infinity).f_inf().is_cuspidal()
        False
        sage: QuasiModularForms(n=infinity).Delta().is_cuspidal()
        True

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiModularForms
        >>> x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        >>> QuasiModularFormsRing(n=Integer(5))(y**Integer(3)-z**Integer(5)).is_cuspidal()                     # needs sage.symbolic
        False
        >>> QuasiModularFormsRing(n=Integer(5))(z*x**Integer(5)-z*y**Integer(2)).is_cuspidal()                 # needs sage.symbolic
        True
        >>> QuasiModularForms(n=Integer(18)).Delta().is_cuspidal()
        True
        >>> QuasiModularForms(n=Integer(18)).f_rho().is_cuspidal()
        False
        >>> QuasiModularForms(n=infinity).f_inf().is_cuspidal()
        False
        >>> QuasiModularForms(n=infinity).Delta().is_cuspidal()
        True

  is_holomorphic()

    Return whether `self` is holomorphic in the sense that the denominator of `self` is constant.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        sage: x, y, z, d = var("x,y,z,d")                                                       # needs sage.symbolic
        sage: QuasiMeromorphicModularFormsRing(n=5)((y^3-z^5)/(x^5-y^2)+y-d).is_holomorphic()   # needs sage.symbolic
        False
        sage: QuasiMeromorphicModularFormsRing(n=5)(x^2+y-d+z).is_holomorphic()                 # needs sage.symbolic
        True
        sage: QuasiMeromorphicModularForms(n=18).J_inv().is_holomorphic()
        False
        sage: QuasiMeromorphicModularForms(n=18).f_i().is_holomorphic()
        True
        sage: QuasiMeromorphicModularForms(n=infinity).f_inf().is_holomorphic()
        True

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        >>> x, y, z, d = var("x,y,z,d")                                                       # needs sage.symbolic
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))((y**Integer(3)-z**Integer(5))/(x**Integer(5)-y**Integer(2))+y-d).is_holomorphic()   # needs sage.symbolic
        False
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))(x**Integer(2)+y-d+z).is_holomorphic()                 # needs sage.symbolic
        True
        >>> QuasiMeromorphicModularForms(n=Integer(18)).J_inv().is_holomorphic()
        False
        >>> QuasiMeromorphicModularForms(n=Integer(18)).f_i().is_holomorphic()
        True
        >>> QuasiMeromorphicModularForms(n=infinity).f_inf().is_holomorphic()
        True

  is_homogeneous()

    Return whether `self` is homogeneous.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        sage: QuasiModularFormsRing(n=12).Delta().is_homogeneous()
        True
        sage: QuasiModularFormsRing(n=12).Delta().parent().is_homogeneous()
        False
        sage: x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        sage: QuasiModularFormsRing(n=12)(x^3+y^2+z+d).is_homogeneous()             # needs sage.symbolic
        False

        sage: QuasiModularFormsRing(n=infinity)(x*(x-y^2)+y^4).is_homogeneous()     # needs sage.symbolic
        True

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        >>> QuasiModularFormsRing(n=Integer(12)).Delta().is_homogeneous()
        True
        >>> QuasiModularFormsRing(n=Integer(12)).Delta().parent().is_homogeneous()
        False
        >>> x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        >>> QuasiModularFormsRing(n=Integer(12))(x**Integer(3)+y**Integer(2)+z+d).is_homogeneous()             # needs sage.symbolic
        False

        >>> QuasiModularFormsRing(n=infinity)(x*(x-y**Integer(2))+y**Integer(4)).is_homogeneous()     # needs sage.symbolic
        True

  is_modular()

    Return whether `self` (resp. its homogeneous components) transform like modular forms.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms
        sage: x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        sage: QuasiModularFormsRing(n=5)(x^2+y-d).is_modular()                      # needs sage.symbolic
        True
        sage: QuasiModularFormsRing(n=5)(x^2+y-d+z).is_modular()                    # needs sage.symbolic
        False
        sage: QuasiModularForms(n=18).f_i().is_modular()
        True
        sage: QuasiModularForms(n=18).E2().is_modular()
        False
        sage: QuasiModularForms(n=infinity).f_inf().is_modular()
        True

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiModularForms
        >>> x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        >>> QuasiModularFormsRing(n=Integer(5))(x**Integer(2)+y-d).is_modular()                      # needs sage.symbolic
        True
        >>> QuasiModularFormsRing(n=Integer(5))(x**Integer(2)+y-d+z).is_modular()                    # needs sage.symbolic
        False
        >>> QuasiModularForms(n=Integer(18)).f_i().is_modular()
        True
        >>> QuasiModularForms(n=Integer(18)).E2().is_modular()
        False
        >>> QuasiModularForms(n=infinity).f_inf().is_modular()
        True

  is_weakly_holomorphic()

    Return whether `self` is weakly holomorphic.

    This means that `self` has at most a power of `f_inf` in its denominator.

    EXAMPLES:

    Sage

        sage: # needs sage.symbolic
        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        sage: x, y, z, d = var("x,y,z,d")
        sage: QuasiMeromorphicModularFormsRing(n=5)(x/(x^5-y^2)+z).is_weakly_holomorphic()
        True
        sage: QuasiMeromorphicModularFormsRing(n=5)(x^2+y/x-d).is_weakly_holomorphic()
        False
        sage: QuasiMeromorphicModularForms(n=18).J_inv().is_weakly_holomorphic()
        True
        sage: QuasiMeromorphicModularForms(n=infinity, k=-4)(1/x).is_weakly_holomorphic()
        True
        sage: QuasiMeromorphicModularForms(n=infinity, k=-2)(1/y).is_weakly_holomorphic()
        False

    Python

        >>> from sage.all import *
        >>> # needs sage.symbolic
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        >>> x, y, z, d = var("x,y,z,d")
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))(x/(x**Integer(5)-y**Integer(2))+z).is_weakly_holomorphic()
        True
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))(x**Integer(2)+y/x-d).is_weakly_holomorphic()
        False
        >>> QuasiMeromorphicModularForms(n=Integer(18)).J_inv().is_weakly_holomorphic()
        True
        >>> QuasiMeromorphicModularForms(n=infinity, k=-Integer(4))(Integer(1)/x).is_weakly_holomorphic()
        True
        >>> QuasiMeromorphicModularForms(n=infinity, k=-Integer(2))(Integer(1)/y).is_weakly_holomorphic()
        False

  is_zero()

    Return whether `self` is the zero function.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms
        sage: QuasiModularFormsRing(n=5)(1).is_zero()
        False
        sage: QuasiModularFormsRing(n=5)(0).is_zero()
        True
        sage: QuasiModularForms(n=18).zero().is_zero()
        True
        sage: QuasiModularForms(n=18).Delta().is_zero()
        False
        sage: QuasiModularForms(n=infinity).f_rho().is_zero()
        False

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiModularForms
        >>> QuasiModularFormsRing(n=Integer(5))(Integer(1)).is_zero()
        False
        >>> QuasiModularFormsRing(n=Integer(5))(Integer(0)).is_zero()
        True
        >>> QuasiModularForms(n=Integer(18)).zero().is_zero()
        True
        >>> QuasiModularForms(n=Integer(18)).Delta().is_zero()
        False
        >>> QuasiModularForms(n=infinity).f_rho().is_zero()
        False

  numerator()

    Return the numerator of `self`.

    I.e. the (properly reduced) new form corresponding to the numerator of `self.rat()`.

    Note that the parent of `self` might (probably will) change.

    EXAMPLES:

    Sage

        sage: # needs sage.symbolic
        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        sage: x, y, z, d = var("x,y,z,d")
        sage: QuasiMeromorphicModularFormsRing(n=5)((y^3-z^5)/(x^5-y^2)+y-d).numerator()
        f_rho^5*f_i - f_rho^5*d - E2^5 + f_i^2*d
        sage: QuasiMeromorphicModularFormsRing(n=5)((y^3-z^5)/(x^5-y^2)+y-d).numerator().parent()
        QuasiModularFormsRing(n=5) over Integer Ring
        sage: QuasiMeromorphicModularForms(n=5, k=-2, ep=-1)(x/y).numerator()
        1 + 7/(100*d)*q + 21/(160000*d^2)*q^2 + 1043/(192000000*d^3)*q^3 + 45479/(1228800000000*d^4)*q^4 + O(q^5)
        sage: QuasiMeromorphicModularForms(n=5, k=-2, ep=-1)(x/y).numerator().parent()
        QuasiModularForms(n=5, k=4/3, ep=1) over Integer Ring
        sage: (QuasiMeromorphicModularForms(n=infinity, k=-2, ep=-1)(y/x)).numerator()
        1 - 24*q + 24*q^2 - 96*q^3 + 24*q^4 + O(q^5)
        sage: (QuasiMeromorphicModularForms(n=infinity, k=-2, ep=-1)(y/x)).numerator().parent()
        QuasiModularForms(n=+Infinity, k=2, ep=-1) over Integer Ring

    Python

        >>> from sage.all import *
        >>> # needs sage.symbolic
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import QuasiMeromorphicModularForms
        >>> x, y, z, d = var("x,y,z,d")
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))((y**Integer(3)-z**Integer(5))/(x**Integer(5)-y**Integer(2))+y-d).numerator()
        f_rho^5*f_i - f_rho^5*d - E2^5 + f_i^2*d
        >>> QuasiMeromorphicModularFormsRing(n=Integer(5))((y**Integer(3)-z**Integer(5))/(x**Integer(5)-y**Integer(2))+y-d).numerator().parent()
        QuasiModularFormsRing(n=5) over Integer Ring
        >>> QuasiMeromorphicModularForms(n=Integer(5), k=-Integer(2), ep=-Integer(1))(x/y).numerator()
        1 + 7/(100*d)*q + 21/(160000*d^2)*q^2 + 1043/(192000000*d^3)*q^3 + 45479/(1228800000000*d^4)*q^4 + O(q^5)
        >>> QuasiMeromorphicModularForms(n=Integer(5), k=-Integer(2), ep=-Integer(1))(x/y).numerator().parent()
        QuasiModularForms(n=5, k=4/3, ep=1) over Integer Ring
        >>> (QuasiMeromorphicModularForms(n=infinity, k=-Integer(2), ep=-Integer(1))(y/x)).numerator()
        1 - 24*q + 24*q^2 - 96*q^3 + 24*q^4 + O(q^5)
        >>> (QuasiMeromorphicModularForms(n=infinity, k=-Integer(2), ep=-Integer(1))(y/x)).numerator().parent()
        QuasiModularForms(n=+Infinity, k=2, ep=-1) over Integer Ring

  order_at(tau=+Infinity)

    Return the (overall) order of `self` at `tau` if easily possible: Namely if `tau` is `infinity` or congruent to `i` resp. `rho`.

    It is possible to determine the order of points from `HyperbolicPlane`. In this case the coordinates of the upper half plane model are used.

    If `self` is homogeneous and modular then the rational function `self.rat()` is used. Otherwise only `tau=infinity` is supported by using the Fourier expansion with increasing precision (until the order can be determined).

    The function is mainly used to be able to work with the correct precision for Laurent series.

    Note

    For quasi forms one cannot deduce the analytic type from this order at `infinity` since the analytic order is defined by the behavior on each quasi part and not by their linear combination.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: MR = QuasiMeromorphicModularFormsRing(red_hom=True)
        sage: (MR.Delta()^3).order_at(infinity)
        3
        sage: MR.E2().order_at(infinity)
        0
        sage: (MR.J_inv()^2).order_at(infinity)
        -2
        sage: x,y,z,d = MR.pol_ring().gens()
        sage: el = MR((z^3-y)^2/(x^3-y^2)).full_reduce()
        sage: el
        108*q + 11664*q^2 + 502848*q^3 + 12010464*q^4 + O(q^5)
        sage: el.order_at(infinity)
        1
        sage: el.parent()
        QuasiWeakModularForms(n=3, k=0, ep=1) over Integer Ring
        sage: el.is_holomorphic()
        False
        sage: MR((z-y)^2+(x-y)^3).order_at(infinity)
        2
        sage: MR((x-y)^10).order_at(infinity)
        10
        sage: MR.zero().order_at(infinity)
        +Infinity
        sage: (MR(x*y^2)/MR.J_inv()).order_at(i)
        2
        sage: (MR(x*y^2)/MR.J_inv()).order_at(MR.group().rho())
        -2

        sage: MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        sage: (MR.Delta()^3*MR.E4()).order_at(infinity)
        3
        sage: MR.E2().order_at(infinity)
        0
        sage: (MR.J_inv()^2/MR.E4()).order_at(infinity)
        -2
        sage: el = MR((z^3-x*y)^2/(x^2*(x-y^2))).full_reduce()
        sage: el
        4*q - 304*q^2 + 8128*q^3 - 106144*q^4 + O(q^5)
        sage: el.order_at(infinity)
        1
        sage: el.parent()
        QuasiWeakModularForms(n=+Infinity, k=0, ep=1) over Integer Ring
        sage: el.is_holomorphic()
        False
        sage: MR((z-x)^2+(x-y)^3).order_at(infinity)
        2
        sage: MR((x-y)^10).order_at(infinity)
        10
        sage: MR.zero().order_at(infinity)
        +Infinity

        sage: (MR.j_inv()*MR.f_i()^3).order_at(-1)
        1
        sage: (MR.j_inv()*MR.f_i()^3).order_at(i)
        3
        sage: (1/MR.f_inf()^2).order_at(-1)
        0

        sage: p = HyperbolicPlane().PD().get_point(I)                               # needs sage.symbolic
        sage: MR((x-y)^10).order_at(p)                                              # needs sage.symbolic
        10
        sage: MR.zero().order_at(p)                                                 # needs sage.symbolic
        +Infinity

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> MR = QuasiMeromorphicModularFormsRing(red_hom=True)
        >>> (MR.Delta()**Integer(3)).order_at(infinity)
        3
        >>> MR.E2().order_at(infinity)
        0
        >>> (MR.J_inv()**Integer(2)).order_at(infinity)
        -2
        >>> x,y,z,d = MR.pol_ring().gens()
        >>> el = MR((z**Integer(3)-y)**Integer(2)/(x**Integer(3)-y**Integer(2))).full_reduce()
        >>> el
        108*q + 11664*q^2 + 502848*q^3 + 12010464*q^4 + O(q^5)
        >>> el.order_at(infinity)
        1
        >>> el.parent()
        QuasiWeakModularForms(n=3, k=0, ep=1) over Integer Ring
        >>> el.is_holomorphic()
        False
        >>> MR((z-y)**Integer(2)+(x-y)**Integer(3)).order_at(infinity)
        2
        >>> MR((x-y)**Integer(10)).order_at(infinity)
        10
        >>> MR.zero().order_at(infinity)
        +Infinity
        >>> (MR(x*y**Integer(2))/MR.J_inv()).order_at(i)
        2
        >>> (MR(x*y**Integer(2))/MR.J_inv()).order_at(MR.group().rho())
        -2

        >>> MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        >>> (MR.Delta()**Integer(3)*MR.E4()).order_at(infinity)
        3
        >>> MR.E2().order_at(infinity)
        0
        >>> (MR.J_inv()**Integer(2)/MR.E4()).order_at(infinity)
        -2
        >>> el = MR((z**Integer(3)-x*y)**Integer(2)/(x**Integer(2)*(x-y**Integer(2)))).full_reduce()
        >>> el
        4*q - 304*q^2 + 8128*q^3 - 106144*q^4 + O(q^5)
        >>> el.order_at(infinity)
        1
        >>> el.parent()
        QuasiWeakModularForms(n=+Infinity, k=0, ep=1) over Integer Ring
        >>> el.is_holomorphic()
        False
        >>> MR((z-x)**Integer(2)+(x-y)**Integer(3)).order_at(infinity)
        2
        >>> MR((x-y)**Integer(10)).order_at(infinity)
        10
        >>> MR.zero().order_at(infinity)
        +Infinity

        >>> (MR.j_inv()*MR.f_i()**Integer(3)).order_at(-Integer(1))
        1
        >>> (MR.j_inv()*MR.f_i()**Integer(3)).order_at(i)
        3
        >>> (Integer(1)/MR.f_inf()**Integer(2)).order_at(-Integer(1))
        0

        >>> p = HyperbolicPlane().PD().get_point(I)                               # needs sage.symbolic
        >>> MR((x-y)**Integer(10)).order_at(p)                                              # needs sage.symbolic
        10
        >>> MR.zero().order_at(p)                                                 # needs sage.symbolic
        +Infinity

  q_expansion(prec=None, fix_d=False, d_num_prec=None, fix_prec=False)

    Return the Fourier expansion of `self`.

    INPUT:

    - `prec` – integer, the desired output precision O(q^prec). Default: `None` in which case the default precision of `self.parent()` is used.

    - `fix_d` – if `False` (default) a formal parameter is used for `d`. If `True` then the numerical value of `d` is used (resp. an exact value if the group is arithmetic). Otherwise the given value is used for `d`.

    - `d_num_prec` – the precision to be used if a numerical value for `d` is substituted (default: `None`), otherwise the default numerical precision of `self.parent()` is used

    - `fix_prec` – if `fix_prec` is not `False` (default) then the precision of the `MFSeriesConstructor` is increased such that the output has exactly the specified precision O(q^prec).

    OUTPUT: the Fourier expansion of `self` as a `FormalPowerSeries` or `FormalLaurentSeries`

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import WeakModularFormsRing, QuasiModularFormsRing
        sage: j_inv = WeakModularFormsRing(red_hom=True).j_inv()
        sage: j_inv.q_expansion(prec=3)
        q^-1 + 31/(72*d) + 1823/(27648*d^2)*q + 10495/(2519424*d^3)*q^2 + O(q^3)

        sage: E2 = QuasiModularFormsRing(n=5, red_hom=True).E2()
        sage: E2.q_expansion(prec=3)
        1 - 9/(200*d)*q - 369/(320000*d^2)*q^2 + O(q^3)
        sage: E2.q_expansion(prec=3, fix_d=1)
        1 - 9/200*q - 369/320000*q^2 + O(q^3)

        sage: E6 = WeakModularFormsRing(n=5, red_hom=True).E6().full_reduce()
        sage: Delta = WeakModularFormsRing(n=5, red_hom=True).Delta().full_reduce()
        sage: E6.q_expansion(prec=3).prec() == 3
        True
        sage: (Delta/(E2^3-E6)).q_expansion(prec=3).prec() == 3
        True
        sage: (Delta/(E2^3-E6)^3).q_expansion(prec=3).prec() == 3
        True
        sage: ((E2^3-E6)/Delta^2).q_expansion(prec=3).prec() == 3
        True
        sage: ((E2^3-E6)^3/Delta).q_expansion(prec=3).prec() == 3
        True

        sage: x,y = var("x,y")
        sage: el = WeakModularFormsRing()((x+1)/(x^3-y^2))
        sage: el.q_expansion(prec=2, fix_prec = True)
        2*d*q^-1 + O(1)
        sage: el.q_expansion(prec=2)
        2*d*q^-1 + 1/6 + 119/(41472*d)*q + O(q^2)

        sage: j_inv = WeakModularFormsRing(n=infinity, red_hom=True).j_inv()
        sage: j_inv.q_expansion(prec=3)
        q^-1 + 3/(8*d) + 69/(1024*d^2)*q + 1/(128*d^3)*q^2 + O(q^3)

        sage: E2 = QuasiModularFormsRing(n=infinity, red_hom=True).E2()
        sage: E2.q_expansion(prec=3)
        1 - 1/(8*d)*q - 1/(512*d^2)*q^2 + O(q^3)
        sage: E2.q_expansion(prec=3, fix_d=1)
        1 - 1/8*q - 1/512*q^2 + O(q^3)

        sage: E4 = WeakModularFormsRing(n=infinity, red_hom=True).E4().full_reduce()
        sage: Delta = WeakModularFormsRing(n=infinity, red_hom=True).Delta().full_reduce()
        sage: E4.q_expansion(prec=3).prec() == 3
        True
        sage: (Delta/(E2^2-E4)).q_expansion(prec=3).prec() == 3
        True
        sage: (Delta/(E2^2-E4)^3).q_expansion(prec=3).prec() == 3
        True
        sage: ((E2^2-E4)/Delta^2).q_expansion(prec=3).prec() == 3
        True
        sage: ((E2^2-E4)^3/Delta).q_expansion(prec=3).prec() == 3
        True

        sage: x,y = var("x,y")
        sage: el = WeakModularFormsRing(n=infinity)((x+1)/(x-y^2))
        sage: el.q_expansion(prec=2, fix_prec = True)
        2*d*q^-1 + O(1)
        sage: el.q_expansion(prec=2)
        2*d*q^-1 + 1/2 + 39/(512*d)*q + O(q^2)

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import WeakModularFormsRing, QuasiModularFormsRing
        >>> j_inv = WeakModularFormsRing(red_hom=True).j_inv()
        >>> j_inv.q_expansion(prec=Integer(3))
        q^-1 + 31/(72*d) + 1823/(27648*d^2)*q + 10495/(2519424*d^3)*q^2 + O(q^3)

        >>> E2 = QuasiModularFormsRing(n=Integer(5), red_hom=True).E2()
        >>> E2.q_expansion(prec=Integer(3))
        1 - 9/(200*d)*q - 369/(320000*d^2)*q^2 + O(q^3)
        >>> E2.q_expansion(prec=Integer(3), fix_d=Integer(1))
        1 - 9/200*q - 369/320000*q^2 + O(q^3)

        >>> E6 = WeakModularFormsRing(n=Integer(5), red_hom=True).E6().full_reduce()
        >>> Delta = WeakModularFormsRing(n=Integer(5), red_hom=True).Delta().full_reduce()
        >>> E6.q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> (Delta/(E2**Integer(3)-E6)).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> (Delta/(E2**Integer(3)-E6)**Integer(3)).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> ((E2**Integer(3)-E6)/Delta**Integer(2)).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> ((E2**Integer(3)-E6)**Integer(3)/Delta).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True

        >>> x,y = var("x,y")
        >>> el = WeakModularFormsRing()((x+Integer(1))/(x**Integer(3)-y**Integer(2)))
        >>> el.q_expansion(prec=Integer(2), fix_prec = True)
        2*d*q^-1 + O(1)
        >>> el.q_expansion(prec=Integer(2))
        2*d*q^-1 + 1/6 + 119/(41472*d)*q + O(q^2)

        >>> j_inv = WeakModularFormsRing(n=infinity, red_hom=True).j_inv()
        >>> j_inv.q_expansion(prec=Integer(3))
        q^-1 + 3/(8*d) + 69/(1024*d^2)*q + 1/(128*d^3)*q^2 + O(q^3)

        >>> E2 = QuasiModularFormsRing(n=infinity, red_hom=True).E2()
        >>> E2.q_expansion(prec=Integer(3))
        1 - 1/(8*d)*q - 1/(512*d^2)*q^2 + O(q^3)
        >>> E2.q_expansion(prec=Integer(3), fix_d=Integer(1))
        1 - 1/8*q - 1/512*q^2 + O(q^3)

        >>> E4 = WeakModularFormsRing(n=infinity, red_hom=True).E4().full_reduce()
        >>> Delta = WeakModularFormsRing(n=infinity, red_hom=True).Delta().full_reduce()
        >>> E4.q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> (Delta/(E2**Integer(2)-E4)).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> (Delta/(E2**Integer(2)-E4)**Integer(3)).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> ((E2**Integer(2)-E4)/Delta**Integer(2)).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True
        >>> ((E2**Integer(2)-E4)**Integer(3)/Delta).q_expansion(prec=Integer(3)).prec() == Integer(3)
        True

        >>> x,y = var("x,y")
        >>> el = WeakModularFormsRing(n=infinity)((x+Integer(1))/(x-y**Integer(2)))
        >>> el.q_expansion(prec=Integer(2), fix_prec = True)
        2*d*q^-1 + O(1)
        >>> el.q_expansion(prec=Integer(2))
        2*d*q^-1 + 1/2 + 39/(512*d)*q + O(q^2)

  q_expansion_fixed_d(prec=None, d_num_prec=None, fix_prec=False)

    Return the Fourier expansion of `self`.

    The numerical (or exact) value for `d` is substituted.

    INPUT:

    - `prec` – integer; the desired output precision O(q^prec). Default: `None`, in which case the default precision of `self.parent()` is used.

    - `d_num_prec` – the precision to be used if a numerical value for `d` is substituted (default: `None`), otherwise the default numerical precision of `self.parent()` is used

    - `fix_prec` – if `fix_prec` is not `False` (default) then the precision of the `MFSeriesConstructor` is increased such that the output has exactly the specified precision O(q^prec).

    OUTPUT: the Fourier expansion of `self` as a `FormalPowerSeries` or `FormalLaurentSeries`

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import WeakModularFormsRing, QuasiModularFormsRing
        sage: j_inv = WeakModularFormsRing(red_hom=True).j_inv()
        sage: j_inv.q_expansion_fixed_d(prec=3)
        q^-1 + 744 + 196884*q + 21493760*q^2 + O(q^3)

        sage: E2 = QuasiModularFormsRing(n=5, red_hom=True).E2()
        sage: E2.q_expansion_fixed_d(prec=3)
        1.000000000000... - 6.380956565426...*q - 23.18584547617...*q^2 + O(q^3)

        sage: x,y = var("x,y")
        sage: WeakModularFormsRing()((x+1)/(x^3-y^2)).q_expansion_fixed_d(prec=2, fix_prec = True)
        1/864*q^-1 + O(1)
        sage: WeakModularFormsRing()((x+1)/(x^3-y^2)).q_expansion_fixed_d(prec=2)
        1/864*q^-1 + 1/6 + 119/24*q + O(q^2)

        sage: j_inv = WeakModularFormsRing(n=infinity, red_hom=True).j_inv()
        sage: j_inv.q_expansion_fixed_d(prec=3)
        q^-1 + 24 + 276*q + 2048*q^2 + O(q^3)

        sage: E2 = QuasiModularFormsRing(n=infinity, red_hom=True).E2()
        sage: E2.q_expansion_fixed_d(prec=3)
        1 - 8*q - 8*q^2 + O(q^3)

        sage: x,y = var("x,y")
        sage: WeakModularFormsRing(n=infinity)((x+1)/(x-y^2)).q_expansion_fixed_d(prec=2, fix_prec = True)
        1/32*q^-1 + O(1)
        sage: WeakModularFormsRing(n=infinity)((x+1)/(x-y^2)).q_expansion_fixed_d(prec=2)
        1/32*q^-1 + 1/2 + 39/8*q + O(q^2)

        sage: (WeakModularFormsRing(n=14).J_inv()^3).q_expansion_fixed_d(prec=2)
        2.933373093...e-6*q^-3 + 0.0002320999814...*q^-2 + 0.009013529265...*q^-1 + 0.2292916854... + 4.303583833...*q + O(q^2)

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import WeakModularFormsRing, QuasiModularFormsRing
        >>> j_inv = WeakModularFormsRing(red_hom=True).j_inv()
        >>> j_inv.q_expansion_fixed_d(prec=Integer(3))
        q^-1 + 744 + 196884*q + 21493760*q^2 + O(q^3)

        >>> E2 = QuasiModularFormsRing(n=Integer(5), red_hom=True).E2()
        >>> E2.q_expansion_fixed_d(prec=Integer(3))
        1.000000000000... - 6.380956565426...*q - 23.18584547617...*q^2 + O(q^3)

        >>> x,y = var("x,y")
        >>> WeakModularFormsRing()((x+Integer(1))/(x**Integer(3)-y**Integer(2))).q_expansion_fixed_d(prec=Integer(2), fix_prec = True)
        1/864*q^-1 + O(1)
        >>> WeakModularFormsRing()((x+Integer(1))/(x**Integer(3)-y**Integer(2))).q_expansion_fixed_d(prec=Integer(2))
        1/864*q^-1 + 1/6 + 119/24*q + O(q^2)

        >>> j_inv = WeakModularFormsRing(n=infinity, red_hom=True).j_inv()
        >>> j_inv.q_expansion_fixed_d(prec=Integer(3))
        q^-1 + 24 + 276*q + 2048*q^2 + O(q^3)

        >>> E2 = QuasiModularFormsRing(n=infinity, red_hom=True).E2()
        >>> E2.q_expansion_fixed_d(prec=Integer(3))
        1 - 8*q - 8*q^2 + O(q^3)

        >>> x,y = var("x,y")
        >>> WeakModularFormsRing(n=infinity)((x+Integer(1))/(x-y**Integer(2))).q_expansion_fixed_d(prec=Integer(2), fix_prec = True)
        1/32*q^-1 + O(1)
        >>> WeakModularFormsRing(n=infinity)((x+Integer(1))/(x-y**Integer(2))).q_expansion_fixed_d(prec=Integer(2))
        1/32*q^-1 + 1/2 + 39/8*q + O(q^2)

        >>> (WeakModularFormsRing(n=Integer(14)).J_inv()**Integer(3)).q_expansion_fixed_d(prec=Integer(2))
        2.933373093...e-6*q^-3 + 0.0002320999814...*q^-2 + 0.009013529265...*q^-1 + 0.2292916854... + 4.303583833...*q + O(q^2)

  q_expansion_vector(min_exp=None, max_exp=None, prec=None, **kwargs)

    Return (part of) the Laurent series expansion of `self` as a vector.

    INPUT:

    - `min_exp` – integer specifying the first coefficient to be used for the vector. Default: `None`, meaning that the first non-trivial coefficient is used.

    - `max_exp` – integer specifying the last coefficient to be used for the vector. Default: `None`, meaning that the default precision + 1 is used.

    - `prec` – integer specifying the precision of the underlying Laurent series. Default: `None`, meaning that `max_exp + 1` is used.

    OUTPUT:

    A vector of size `max_exp - min_exp` over the coefficient ring of `self`, determined by the corresponding Laurent series coefficients.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import WeakModularFormsRing
        sage: f = WeakModularFormsRing(red_hom=True).j_inv()^3
        sage: f.q_expansion(prec=3)
        q^-3 + 31/(24*d)*q^-2 + 20845/(27648*d^2)*q^-1 + 7058345/(26873856*d^3) + 30098784355/(495338913792*d^4)*q + 175372747465/(17832200896512*d^5)*q^2 + O(q^3)
        sage: v = f.q_expansion_vector(max_exp=1, prec=3)
        sage: v
        (1, 31/(24*d), 20845/(27648*d^2), 7058345/(26873856*d^3), 30098784355/(495338913792*d^4))
        sage: v.parent()
        Vector space of dimension 5 over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
        sage: f.q_expansion_vector(min_exp=1, max_exp=2)
        (30098784355/(495338913792*d^4), 175372747465/(17832200896512*d^5))
        sage: f.q_expansion_vector(min_exp=1, max_exp=2, fix_d=True)
        (541778118390, 151522053809760)

        sage: f = WeakModularFormsRing(n=infinity, red_hom=True).j_inv()^3
        sage: f.q_expansion_fixed_d(prec=3)
        q^-3 + 72*q^-2 + 2556*q^-1 + 59712 + 1033974*q + 14175648*q^2 + O(q^3)
        sage: v = f.q_expansion_vector(max_exp=1, prec=3, fix_d=True)
        sage: v
        (1, 72, 2556, 59712, 1033974)
        sage: v.parent()
        Vector space of dimension 5 over Rational Field
        sage: f.q_expansion_vector(min_exp=1, max_exp=2)
        (516987/(8388608*d^4), 442989/(33554432*d^5))

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import WeakModularFormsRing
        >>> f = WeakModularFormsRing(red_hom=True).j_inv()**Integer(3)
        >>> f.q_expansion(prec=Integer(3))
        q^-3 + 31/(24*d)*q^-2 + 20845/(27648*d^2)*q^-1 + 7058345/(26873856*d^3) + 30098784355/(495338913792*d^4)*q + 175372747465/(17832200896512*d^5)*q^2 + O(q^3)
        >>> v = f.q_expansion_vector(max_exp=Integer(1), prec=Integer(3))
        >>> v
        (1, 31/(24*d), 20845/(27648*d^2), 7058345/(26873856*d^3), 30098784355/(495338913792*d^4))
        >>> v.parent()
        Vector space of dimension 5 over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
        >>> f.q_expansion_vector(min_exp=Integer(1), max_exp=Integer(2))
        (30098784355/(495338913792*d^4), 175372747465/(17832200896512*d^5))
        >>> f.q_expansion_vector(min_exp=Integer(1), max_exp=Integer(2), fix_d=True)
        (541778118390, 151522053809760)

        >>> f = WeakModularFormsRing(n=infinity, red_hom=True).j_inv()**Integer(3)
        >>> f.q_expansion_fixed_d(prec=Integer(3))
        q^-3 + 72*q^-2 + 2556*q^-1 + 59712 + 1033974*q + 14175648*q^2 + O(q^3)
        >>> v = f.q_expansion_vector(max_exp=Integer(1), prec=Integer(3), fix_d=True)
        >>> v
        (1, 72, 2556, 59712, 1033974)
        >>> v.parent()
        Vector space of dimension 5 over Rational Field
        >>> f.q_expansion_vector(min_exp=Integer(1), max_exp=Integer(2))
        (516987/(8388608*d^4), 442989/(33554432*d^5))

  rat()

    Return the rational function representing `self`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
        sage: ModularFormsRing(n=12).Delta().rat()
        x^30*d - x^18*y^2*d

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
        >>> ModularFormsRing(n=Integer(12)).Delta().rat()
        x^30*d - x^18*y^2*d

  reduce(force=False)

    In case `self.parent().has_reduce_hom() == True` (or `force==True`) and `self` is homogeneous the converted element lying in the corresponding homogeneous_part is returned.

    Otherwise `self` is returned.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
        sage: E2 = ModularFormsRing(n=7).E2().reduce()
        sage: E2.parent()
        QuasiModularFormsRing(n=7) over Integer Ring
        sage: E2 = ModularFormsRing(n=7, red_hom=True).E2().reduce()
        sage: E2.parent()
        QuasiModularForms(n=7, k=2, ep=-1) over Integer Ring
        sage: ModularFormsRing(n=7)(x+1).reduce().parent()
        ModularFormsRing(n=7) over Integer Ring
        sage: E2 = ModularFormsRing(n=7).E2().reduce(force=True)
        sage: E2.parent()
        QuasiModularForms(n=7, k=2, ep=-1) over Integer Ring
        sage: ModularFormsRing(n=7)(x+1).reduce(force=True).parent()
        ModularFormsRing(n=7) over Integer Ring

        sage: y = var("y")
        sage: ModularFormsRing(n=infinity)(x-y^2).reduce(force=True)
        64*q - 512*q^2 + 1792*q^3 - 4096*q^4 + O(q^5)

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import ModularFormsRing
        >>> E2 = ModularFormsRing(n=Integer(7)).E2().reduce()
        >>> E2.parent()
        QuasiModularFormsRing(n=7) over Integer Ring
        >>> E2 = ModularFormsRing(n=Integer(7), red_hom=True).E2().reduce()
        >>> E2.parent()
        QuasiModularForms(n=7, k=2, ep=-1) over Integer Ring
        >>> ModularFormsRing(n=Integer(7))(x+Integer(1)).reduce().parent()
        ModularFormsRing(n=7) over Integer Ring
        >>> E2 = ModularFormsRing(n=Integer(7)).E2().reduce(force=True)
        >>> E2.parent()
        QuasiModularForms(n=7, k=2, ep=-1) over Integer Ring
        >>> ModularFormsRing(n=Integer(7))(x+Integer(1)).reduce(force=True).parent()
        ModularFormsRing(n=7) over Integer Ring

        >>> y = var("y")
        >>> ModularFormsRing(n=infinity)(x-y**Integer(2)).reduce(force=True)
        64*q - 512*q^2 + 1792*q^3 - 4096*q^4 + O(q^5)

  reduced_parent()

    Return the space with the analytic type of `self`. If `self` is homogeneous the corresponding `FormsSpace` is returned.

    I.e. return the smallest known ambient space of `self`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: Delta = QuasiMeromorphicModularFormsRing(n=7).Delta()
        sage: Delta.parent()
        QuasiMeromorphicModularFormsRing(n=7) over Integer Ring
        sage: Delta.reduced_parent()
        CuspForms(n=7, k=12, ep=1) over Integer Ring
        sage: el = QuasiMeromorphicModularFormsRing()(x+1)
        sage: el.parent()
        QuasiMeromorphicModularFormsRing(n=3) over Integer Ring
        sage: el.reduced_parent()
        ModularFormsRing(n=3) over Integer Ring

        sage: y = var("y")
        sage: QuasiMeromorphicModularFormsRing(n=infinity)(x-y^2).reduced_parent()
        ModularForms(n=+Infinity, k=4, ep=1) over Integer Ring
        sage: QuasiMeromorphicModularFormsRing(n=infinity)(x*(x-y^2)).reduced_parent()
        CuspForms(n=+Infinity, k=8, ep=1) over Integer Ring

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> Delta = QuasiMeromorphicModularFormsRing(n=Integer(7)).Delta()
        >>> Delta.parent()
        QuasiMeromorphicModularFormsRing(n=7) over Integer Ring
        >>> Delta.reduced_parent()
        CuspForms(n=7, k=12, ep=1) over Integer Ring
        >>> el = QuasiMeromorphicModularFormsRing()(x+Integer(1))
        >>> el.parent()
        QuasiMeromorphicModularFormsRing(n=3) over Integer Ring
        >>> el.reduced_parent()
        ModularFormsRing(n=3) over Integer Ring

        >>> y = var("y")
        >>> QuasiMeromorphicModularFormsRing(n=infinity)(x-y**Integer(2)).reduced_parent()
        ModularForms(n=+Infinity, k=4, ep=1) over Integer Ring
        >>> QuasiMeromorphicModularFormsRing(n=infinity)(x*(x-y**Integer(2))).reduced_parent()
        CuspForms(n=+Infinity, k=8, ep=1) over Integer Ring

  serre_derivative()

    Return the Serre derivative of `self`.

    Note that the parent might (probably will) change. However a modular element is returned if `self` was already modular.

    If `parent.has_reduce_hom() == True` then the result is reduced to be an element of the corresponding forms space if possible.

    In particular this is the case if `self` is a (homogeneous) element of a forms space.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        sage: MR = QuasiMeromorphicModularFormsRing(n=7, red_hom=True)
        sage: n = MR.hecke_n()
        sage: Delta = MR.Delta().full_reduce()
        sage: E2 = MR.E2().full_reduce()
        sage: E4 = MR.E4().full_reduce()
        sage: E6 = MR.E6().full_reduce()
        sage: f_rho = MR.f_rho().full_reduce()
        sage: f_i = MR.f_i().full_reduce()
        sage: f_inf = MR.f_inf().full_reduce()

        sage: f_rho.serre_derivative() == -1/n * f_i
        True
        sage: f_i.serre_derivative()   == -1/2 * E4 * f_rho
        True
        sage: f_inf.serre_derivative() == 0
        True
        sage: E2.serre_derivative()    == -(n-2)/(4*n) * (E2^2 + E4)
        True
        sage: E4.serre_derivative()    == -(n-2)/n * E6
        True
        sage: E6.serre_derivative()    == -1/2 * E4^2 - (n-3)/n * E6^2 / E4
        True
        sage: E6.serre_derivative().parent()
        ModularForms(n=7, k=8, ep=1) over Integer Ring

        sage: MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        sage: Delta = MR.Delta().full_reduce()
        sage: E2 = MR.E2().full_reduce()
        sage: E4 = MR.E4().full_reduce()
        sage: E6 = MR.E6().full_reduce()
        sage: f_i = MR.f_i().full_reduce()
        sage: f_inf = MR.f_inf().full_reduce()

        sage: E4.serre_derivative()    == -E4 * f_i
        True
        sage: f_i.serre_derivative()   == -1/2 * E4
        True
        sage: f_inf.serre_derivative() == 0
        True
        sage: E2.serre_derivative()    == -1/4 * (E2^2 + E4)
        True
        sage: E4.serre_derivative()    == -E6
        True
        sage: E6.serre_derivative()    == -1/2 * E4^2 - E6^2 / E4
        True
        sage: E6.serre_derivative().parent()
        ModularForms(n=+Infinity, k=8, ep=1) over Integer Ring

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiMeromorphicModularFormsRing
        >>> MR = QuasiMeromorphicModularFormsRing(n=Integer(7), red_hom=True)
        >>> n = MR.hecke_n()
        >>> Delta = MR.Delta().full_reduce()
        >>> E2 = MR.E2().full_reduce()
        >>> E4 = MR.E4().full_reduce()
        >>> E6 = MR.E6().full_reduce()
        >>> f_rho = MR.f_rho().full_reduce()
        >>> f_i = MR.f_i().full_reduce()
        >>> f_inf = MR.f_inf().full_reduce()

        >>> f_rho.serre_derivative() == -Integer(1)/n * f_i
        True
        >>> f_i.serre_derivative()   == -Integer(1)/Integer(2) * E4 * f_rho
        True
        >>> f_inf.serre_derivative() == Integer(0)
        True
        >>> E2.serre_derivative()    == -(n-Integer(2))/(Integer(4)*n) * (E2**Integer(2) + E4)
        True
        >>> E4.serre_derivative()    == -(n-Integer(2))/n * E6
        True
        >>> E6.serre_derivative()    == -Integer(1)/Integer(2) * E4**Integer(2) - (n-Integer(3))/n * E6**Integer(2) / E4
        True
        >>> E6.serre_derivative().parent()
        ModularForms(n=7, k=8, ep=1) over Integer Ring

        >>> MR = QuasiMeromorphicModularFormsRing(n=infinity, red_hom=True)
        >>> Delta = MR.Delta().full_reduce()
        >>> E2 = MR.E2().full_reduce()
        >>> E4 = MR.E4().full_reduce()
        >>> E6 = MR.E6().full_reduce()
        >>> f_i = MR.f_i().full_reduce()
        >>> f_inf = MR.f_inf().full_reduce()

        >>> E4.serre_derivative()    == -E4 * f_i
        True
        >>> f_i.serre_derivative()   == -Integer(1)/Integer(2) * E4
        True
        >>> f_inf.serre_derivative() == Integer(0)
        True
        >>> E2.serre_derivative()    == -Integer(1)/Integer(4) * (E2**Integer(2) + E4)
        True
        >>> E4.serre_derivative()    == -E6
        True
        >>> E6.serre_derivative()    == -Integer(1)/Integer(2) * E4**Integer(2) - E6**Integer(2) / E4
        True
        >>> E6.serre_derivative().parent()
        ModularForms(n=+Infinity, k=8, ep=1) over Integer Ring

  sqrt()

    Return the square root of `self` if it exists.

    I.e. the element corresponding to `sqrt(self.rat())`.

    Whether this works or not depends on whether `sqrt(self.rat())` works and coerces into `self.parent().rat_field()`.

    Note that the parent might (probably will) change.

    If `parent.has_reduce_hom() == True` then the result is reduced to be an element of the corresponding forms space if possible.

    In particular this is the case if `self` is a (homogeneous) element of a forms space.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms
        sage: E2 = QuasiModularForms(k=2, ep=-1).E2()
        sage: (E2^2).sqrt()
        1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 + O(q^5)
        sage: (E2^2).sqrt() == E2
        True

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.space import QuasiModularForms
        >>> E2 = QuasiModularForms(k=Integer(2), ep=-Integer(1)).E2()
        >>> (E2**Integer(2)).sqrt()
        1 - 24*q - 72*q^2 - 96*q^3 - 168*q^4 + O(q^5)
        >>> (E2**Integer(2)).sqrt() == E2
        True

  weight()

    Return the weight of `self`.

    EXAMPLES:

    Sage

        sage: from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        sage: from sage.modular.modform_hecketriangle.space import ModularForms
        sage: x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        sage: QuasiModularFormsRing()(x+y).weight() is None                         # needs sage.symbolic
        True
        sage: ModularForms(n=18).f_i().weight()
        9/4
        sage: ModularForms(n=infinity).f_inf().weight()
        4

    Python

        >>> from sage.all import *
        >>> from sage.modular.modform_hecketriangle.graded_ring import QuasiModularFormsRing
        >>> from sage.modular.modform_hecketriangle.space import ModularForms
        >>> x, y, z, d = var("x,y,z,d")                                           # needs sage.symbolic
        >>> QuasiModularFormsRing()(x+y).weight() is None                         # needs sage.symbolic
        True
        >>> ModularForms(n=Integer(18)).f_i().weight()
        9/4
        >>> ModularForms(n=infinity).f_inf().weight()
        4