Exemplo n.º 1
0
class AnalyticType(FiniteLatticePoset):
    r"""
    Container for all possible analytic types of forms and/or spaces

    The ``analytic type`` of forms spaces or rings describes all possible
    occuring basic ``analytic properties`` of elements in the space/ring
    (or more).

    For ambient spaces/rings this means that all elements with those properties
    (and the restrictions of the space/ring) are contained in the space/ring.

    The analytic type of an element is the analytic type of its minimal
    ambient space/ring.

    The basic ``analytic properties`` are:

        - ``quasi``  - Whether the element is quasi modular (and not modular)
                       or modular.
        - ``mero``   - ``meromorphic``: If the element is meromorphic
                       and meromorphic at infinity.
        - ``weak``   - ``weakly holomorphic``: If the element is holomorphic
                       and meromorphic at infinity.
        - ``holo``   - ``holomorphic``: If the element is holomorphic and
                       holomorphic at infinity.
        - ``cusp``   - ``cuspidal``: If the element additionally has a positive
                       order at infinity.

    The ``zero`` elements/property have no analytic properties (or only ``quasi``).

    For ring elements the property describes whether one of its homogeneous
    components satisfies that property and the "union" of those properties
    is returned as the ``analytic type``.

    Similarly for quasi forms the property describes whether one of its
    quasi components satisfies that property.

    There is a (natural) partial order between the basic properties
    (and analytic types) given by "inclusion". We name the analytic type
    according to its maximal analytic properties.

    EXAMPLES::

    For n=3 the quasi form ``el = E6 - E2^3`` has the quasi components ``E6``
    which is ``holomorphic`` and ``E2^3`` which is ``quasi holomorphic``.
    So the analytic type of ``el`` is ``quasi holomorphic`` despite the fact
    that the sum (``el``) describes a function which is zero at infinity.
 
        sage: from space import QModularForms
        sage: x,y,z,d = var("x,y,z,d")
        sage: el = QModularForms(group=3, k=6, ep=-1)(y-z^3)
        sage: el.analytic_type()
        quasi modular

    Similarly the type of the ring element ``el2 = E4/Delta - E6/Delta`` is
    ``weakly holomorphic`` despite the fact that the sum (``el2``) describes
    a function which is holomorphic at infinity.

        sage: from graded_ring import WeakModularFormsRing
        sage: x,y,z,d = var("x,y,z,d")
        sage: el2 = WeakModularFormsRing(group=3)(x/(x^3-y^2)-y/(x^3-y^2))
        sage: el2.analytic_type()
        weakly holomorphic modular
    """

    Element = AnalyticTypeElement

    @staticmethod
    def __classcall__(cls):
        r"""
        Directly return the classcall of UniqueRepresentation
        (skipping the classcalls of the other superclasses).

        That's because ``self`` is supposed to be used as a Singleton.
        It initializes the FinitelatticePoset with the proper arguments
        by itself in ``self.__init__()``.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT2 = AnalyticType()
            sage: AT == AT2
            True
        """

        return super(FinitePoset, cls).__classcall__(cls)
                
    def __init__(self):
        r"""
        Container for all possible analytic types of forms and/or spaces.

        This class is supposed to be used as a Singleton.

        It first creates a ``Poset`` that contains all basic analytic
        properties to be modeled by the AnalyticType. Then the order
        ideals lattice of that Poset is taken as the underlying
        FiniteLatticePoset of ``self``.

        In particular elements of ``self`` describe what basic analytic
        properties are contained/included in that element.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT
            Analytic Type
            sage: isinstance(AT, FiniteLatticePoset)
            True

            sage: AT.is_lattice()
            True
            sage: AT.is_finite()
            True
            sage: AT.cardinality()
            10
            sage: AT.is_modular()
            True
            sage: AT.is_bounded()
            True
            sage: AT.is_distributive()
            True
            sage: AT.list()
            [zero,
             zero,
             cuspidal,
             modular,
             weakly holomorphic modular,
             quasi cuspidal,
             quasi modular,
             quasi weakly holomorphic modular,
             meromorphic modular,
             quasi meromorphic modular]
            sage: len(AT.relations())
            45
            sage: AT.cover_relations()
            [[zero, zero],
             [zero, cuspidal],
             [zero, quasi cuspidal],
             [cuspidal, modular],
             [cuspidal, quasi cuspidal],
             [modular, weakly holomorphic modular],
             [modular, quasi modular],
             [weakly holomorphic modular, quasi weakly holomorphic modular],
             [weakly holomorphic modular, meromorphic modular],
             [quasi cuspidal, quasi modular],
             [quasi modular, quasi weakly holomorphic modular],
             [quasi weakly holomorphic modular, quasi meromorphic modular],
             [meromorphic modular, quasi meromorphic modular]]
            sage: AT.has_top()
            True
            sage: AT.has_bottom()
            True
            sage: AT.top()
            quasi meromorphic modular
            sage: AT.bottom()
            zero
        """

        # We (arbitrarily) choose to model by inclusion instead of restriction
        P_elements = [ "cusp", "holo", "weak", "mero", "quasi"]
        P_relations = [["cusp", "holo"], ["holo", "weak"], ["weak", "mero"]]
        
        self._base_poset = Poset([P_elements, P_relations], cover_relations=True, facade=False)
        L = self._base_poset.order_ideals_lattice()
        L = FiniteLatticePoset(L, facade=False)

        FiniteLatticePoset.__init__(self, hasse_diagram=L._hasse_diagram, elements=L._elements, category=L.category(), facade=L._is_facade, key=None)

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

        EXAMPLES::

            sage: AnalyticType()
            Analytic Type
        """

        return "Analytic Type"

    def __call__(self, *args, **kwargs):
        r"""
        Return the result of the corresponding call function
        of ``FiniteLatticePoset``.

        If more than one argument is given it is called with
        the list of those arguments instead.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT("holo", "quasi") == AT(["holo", "quasi"])
            True
        """

        if len(args)>1:
            return super(AnalyticType,self).__call__([arg for arg in args], **kwargs)
        else:
            return super(AnalyticType,self).__call__(*args, **kwargs)

    def _element_constructor_(self, element):
        r"""
        Return ``element`` coerced into an element of ``self``.

        INPUT:

        - ``element``   - Either something which coerces in the
                          ``FiniteLatticePoset`` of ``self`` or
                          a string or a list of strings of basic
                          properties that should be contained in
                          the new element.
                          

        OUTPUT:

        An element of ``self`` corresponding to ``element``
        (resp. containing all specified basic analytic properties).

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT("holo") == AT(["holo"])
            True
            sage: el = AT(["quasi", "holo"])
            sage: el
            quasi modular
            sage: el == AT(("holo", "quasi"))
            True
            sage: el.parent() == AT
            True
            sage: isinstance(el, AnalyticTypeElement)
            True
            sage: el.element
            {holo, cusp, quasi}
        """
        
        if type(element)==str:
            element=[element]
        if isinstance(element,list) or isinstance(element,tuple):
            element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element]))

        return super(AnalyticType, self)._element_constructor_(element)

        #res = self.first()
        #for element in args:
        #    if type(element)==str:
        #        element=[element]
        #    if isinstance(element,list) or isinstance(element,tuple):
        #        element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element]))
        #    element = super(AnalyticType,self)._element_constructor_(element)
        #    res += element
        #return res

    def base_poset(self):
        r"""
        Return the base poset from which everything of ``self``
        was constructed. Elements of the base poset correspond
        to the basic ``analytic properties``.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: P = AT.base_poset()
            sage: P
            Finite poset containing 5 elements
            sage: isinstance(P, FinitePoset)
            True

            sage: P.is_lattice()
            False
            sage: P.is_finite()
            True
            sage: P.cardinality()
            5
            sage: P.is_bounded()
            False
            sage: P.list()
            [quasi, cusp, holo, weak, mero]
            
            sage: len(P.relations())
            11
            sage: P.cover_relations()
            [[cusp, holo], [holo, weak], [weak, mero]]
            sage: P.has_top()
            False
            sage: P.has_bottom()
            False
        """

        return self._base_poset

    def lattice_poset(self):
        r"""
        Return the underlying lattice poset of ``self``.

        EXAMPLES::

            sage: AnalyticType().lattice_poset()
            Finite lattice containing 10 elements
        """

        return FiniteLatticePoset(self._base_poset.order_ideals_lattice(), facade=False)
                        
Exemplo n.º 2
0
class AnalyticType(FiniteLatticePoset):
    r"""
    Container for all possible analytic types of forms and/or spaces.

    The ``analytic type`` of forms spaces or rings describes all possible
    occuring basic ``analytic properties`` of elements in the space/ring
    (or more).

    For ambient spaces/rings this means that all elements with those properties
    (and the restrictions of the space/ring) are contained in the space/ring.

    The analytic type of an element is the analytic type of its minimal
    ambient space/ring.

    The basic ``analytic properties`` are:

    - ``quasi``  - Whether the element is quasi modular (and not modular)
                   or modular.
    - ``mero``   - ``meromorphic``: If the element is meromorphic
                   and meromorphic at infinity.
    - ``weak``   - ``weakly holomorphic``: If the element is holomorphic
                   and meromorphic at infinity.
    - ``holo``   - ``holomorphic``: If the element is holomorphic and
                   holomorphic at infinity.
    - ``cusp``   - ``cuspidal``: If the element additionally has a positive
                   order at infinity.

    The ``zero`` elements/property have no analytic properties (or only ``quasi``).

    For ring elements the property describes whether one of its homogeneous
    components satisfies that property and the "union" of those properties
    is returned as the ``analytic type``.

    Similarly for quasi forms the property describes whether one of its
    quasi components satisfies that property.

    There is a (natural) partial order between the basic properties
    (and analytic types) given by "inclusion". We name the analytic type
    according to its maximal analytic properties.

    EXAMPLES:

    For `n=3` the quasi form ``el = E6 - E2^3`` has the quasi components ``E6``
    which is ``holomorphic`` and ``E2^3`` which is ``quasi holomorphic``.
    So the analytic type of ``el`` is ``quasi holomorphic`` despite the fact
    that the sum (``el``) describes a function which is zero at infinity.

    ::

        sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms
        sage: x,y,z,d = var("x,y,z,d")
        sage: el = QuasiModularForms(n=3, k=6, ep=-1)(y-z^3)
        sage: el.analytic_type()
        quasi modular

    Similarly the type of the ring element ``el2 = E4/Delta - E6/Delta`` is
    ``weakly holomorphic`` despite the fact that the sum (``el2``) describes
    a function which is holomorphic at infinity.

        sage: from sage.modular.modform_hecketriangle.graded_ring import WeakModularFormsRing
        sage: x,y,z,d = var("x,y,z,d")
        sage: el2 = WeakModularFormsRing(n=3)(x/(x^3-y^2)-y/(x^3-y^2))
        sage: el2.analytic_type()
        weakly holomorphic modular
    """

    Element = AnalyticTypeElement

    @staticmethod
    def __classcall__(cls):
        r"""
        Directly return the classcall of UniqueRepresentation
        (skipping the classcalls of the other superclasses).

        That's because ``self`` is supposed to be used as a Singleton.
        It initializes the FinitelatticePoset with the proper arguments
        by itself in ``self.__init__()``.

        EXAMPLES::

            sage: from sage.modular.modform_hecketriangle.analytic_type import AnalyticType
            sage: AT = AnalyticType()
            sage: AT2 = AnalyticType()
            sage: AT is AT2
            True
        """
        return super(FinitePoset, cls).__classcall__(cls)

    def __init__(self):
        r"""
        Container for all possible analytic types of forms and/or spaces.

        This class is supposed to be used as a Singleton.

        It first creates a ``Poset`` that contains all basic analytic
        properties to be modeled by the AnalyticType. Then the order
        ideals lattice of that Poset is taken as the underlying
        FiniteLatticePoset of ``self``.

        In particular elements of ``self`` describe what basic analytic
        properties are contained/included in that element.

        EXAMPLES::

            sage: from sage.modular.modform_hecketriangle.analytic_type import AnalyticType
            sage: from sage.combinat.posets.lattices import FiniteLatticePoset
            sage: AT = AnalyticType()
            sage: AT
            Analytic Type
            sage: isinstance(AT, FiniteLatticePoset)
            True

            sage: AT.is_lattice()
            True
            sage: AT.is_finite()
            True
            sage: AT.cardinality()
            10
            sage: AT.is_modular()
            True
            sage: AT.is_bounded()
            True
            sage: AT.is_distributive()
            True
            sage: AT.list()
            [zero,
             cuspidal,
             zero,
             modular,
             weakly holomorphic modular,
             meromorphic modular,
             quasi cuspidal,
             quasi modular,
             quasi weakly holomorphic modular,
             quasi meromorphic modular]
            sage: len(AT.relations())
            45
            sage: AT.cover_relations()
            [[zero, cuspidal],
             [zero, zero],
             [cuspidal, modular],
             [cuspidal, quasi cuspidal],
             [zero, quasi cuspidal],
             [modular, weakly holomorphic modular],
             [modular, quasi modular],
             [weakly holomorphic modular, meromorphic modular],
             [weakly holomorphic modular, quasi weakly holomorphic modular],
             [meromorphic modular, quasi meromorphic modular],
             [quasi cuspidal, quasi modular],
             [quasi modular, quasi weakly holomorphic modular],
             [quasi weakly holomorphic modular, quasi meromorphic modular]]
            sage: AT.has_top()
            True
            sage: AT.has_bottom()
            True
            sage: AT.top()
            quasi meromorphic modular
            sage: AT.bottom()
            zero
        """
        # We (arbitrarily) choose to model by inclusion instead of restriction
        P_elements = ["cusp", "holo", "weak", "mero", "quasi"]
        P_relations = [["cusp", "holo"], ["holo", "weak"], ["weak", "mero"]]

        self._base_poset = Poset([P_elements, P_relations],
                                 cover_relations=True,
                                 linear_extension=True,
                                 facade=False)

        L = self._base_poset.order_ideals_lattice()
        H = L._hasse_diagram.relabel({i: x
                                      for i, x in enumerate(L._elements)},
                                     inplace=False)
        FiniteLatticePoset.__init__(self,
                                    hasse_diagram=H,
                                    elements=L._elements,
                                    category=L.category(),
                                    facade=False,
                                    key=None)

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

        EXAMPLES::

            sage: from sage.modular.modform_hecketriangle.analytic_type import AnalyticType
            sage: AnalyticType()
            Analytic Type
        """

        return "Analytic Type"

    def __call__(self, *args, **kwargs):
        r"""
        Return the result of the corresponding call function
        of ``FiniteLatticePoset``.

        If more than one argument is given it is called with
        the list of those arguments instead.

        .. NOTE::

            The function just extends the ``__call__`` function to allow multiple arguments
            (see the example below).

        EXAMPLES::

            sage: from sage.modular.modform_hecketriangle.analytic_type import AnalyticType
            sage: AT = AnalyticType()
            sage: AT("holo", "quasi") == AT(["holo", "quasi"])
            True
        """

        if len(args) > 1:
            return super(AnalyticType, self).__call__([arg for arg in args],
                                                      **kwargs)
        else:
            return super(AnalyticType, self).__call__(*args, **kwargs)

    def _element_constructor_(self, element):
        r"""
        Return ``element`` coerced into an element of ``self``.

        INPUT:

        - ``element``  -- Either something which coerces in the
                          ``FiniteLatticePoset`` of ``self`` or
                          a string or a list of strings of basic
                          properties that should be contained in
                          the new element.


        OUTPUT:

        An element of ``self`` corresponding to ``element``
        (resp. containing all specified basic analytic properties).

        EXAMPLES::

            sage: from sage.modular.modform_hecketriangle.analytic_type import (AnalyticType, AnalyticTypeElement)
            sage: AT = AnalyticType()
            sage: AT("holo") == AT(["holo"])
            True
            sage: el = AT(["quasi", "holo"])
            sage: el
            quasi modular
            sage: el == AT(("holo", "quasi"))
            True
            sage: el.parent() == AT
            True
            sage: isinstance(el, AnalyticTypeElement)
            True
            sage: el.element
            {holo, cusp, quasi}
        """

        if isinstance(element, str):
            element = [element]
        if isinstance(element, list) or isinstance(element, tuple):
            element = Set(
                self._base_poset.order_ideal(
                    [self._base_poset(s) for s in element]))

        return super(AnalyticType, self)._element_constructor_(element)

        #res = self.first()
        #for element in args:
        #    if type(element)==str:
        #        element=[element]
        #    if isinstance(element,list) or isinstance(element,tuple):
        #        element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element]))
        #    element = super(AnalyticType,self)._element_constructor_(element)
        #    res += element
        #return res

    def base_poset(self):
        r"""
        Return the base poset from which everything of ``self``
        was constructed. Elements of the base poset correspond
        to the basic ``analytic properties``.

        EXAMPLES::

            sage: from sage.modular.modform_hecketriangle.analytic_type import AnalyticType
            sage: from sage.combinat.posets.posets import FinitePoset
            sage: AT = AnalyticType()
            sage: P = AT.base_poset()
            sage: P
            Finite poset containing 5 elements with distinguished linear extension
            sage: isinstance(P, FinitePoset)
            True

            sage: P.is_lattice()
            False
            sage: P.is_finite()
            True
            sage: P.cardinality()
            5
            sage: P.is_bounded()
            False
            sage: P.list()
            [cusp, holo, weak, mero, quasi]

            sage: len(P.relations())
            11
            sage: P.cover_relations()
            [[cusp, holo], [holo, weak], [weak, mero]]
            sage: P.has_top()
            False
            sage: P.has_bottom()
            False
        """

        return self._base_poset

    def lattice_poset(self):
        r"""
        Return the underlying lattice poset of ``self``.

        EXAMPLES::

            sage: from sage.modular.modform_hecketriangle.analytic_type import AnalyticType
            sage: AnalyticType().lattice_poset()
            Finite lattice containing 10 elements
        """

        return FiniteLatticePoset(self._base_poset.order_ideals_lattice(),
                                  facade=False)