Beispiel #1
0
    def __init__(self, X, Y):
        """
        EXAMPLES::

            sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ); W = V.span([2*V.0+4*V.1, 9*V.0+12*V.1, 4*V.2]); Q = V/W
            sage: type(Q.Hom(Q))
            <class 'sage.modules.fg_pid.fgp_morphism.FGP_Homset_class_with_category'>
        """
        Homset.__init__(self, X, Y)
        self._populate_coercion_lists_(element_constructor = FGP_Morphism,
                                       coerce_list = [])
Beispiel #2
0
    def __call__(self, *args, **kwds):
        r"""
        Construct an element of ``self`` from the input.

        EXAMPLES::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: X.<x,y> = M.chart()
            sage: N = Manifold(3, 'N', structure='topological')
            sage: Y.<u,v,w> = N.chart()
            sage: H = Hom(M,N)
            sage: f = H.__call__({(X, Y): [x+y, x-y, x*y]}, name='f') ; f
            Continuous map f from the 2-dimensional topological manifold M to
             the 3-dimensional topological manifold N
            sage: f.display()
            f: M --> N
               (x, y) |--> (u, v, w) = (x + y, x - y, x*y)

        There is also the following shortcut for :meth:`one`::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: H = Hom(M, M)
            sage: H(1)
            Identity map Id_M of the 2-dimensional topological manifold M
        """
        if len(args) == 1:
            if self.domain() == self.codomain() and args[0] == 1:
                return self.one()
            if isinstance(args[0], ContinuousMap):
                return Homset.__call__(self, args[0])
        return Parent.__call__(self, *args, **kwds)
Beispiel #3
0
    def __call__(self, *args, **kwds):
        r"""
        Construct an element of ``self`` from the input.

        EXAMPLES::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: X.<x,y> = M.chart()
            sage: N = Manifold(3, 'N', structure='topological')
            sage: Y.<u,v,w> = N.chart()
            sage: H = Hom(M,N)
            sage: f = H.__call__({(X, Y): [x+y, x-y, x*y]}, name='f') ; f
            Continuous map f from the 2-dimensional topological manifold M to
             the 3-dimensional topological manifold N
            sage: f.display()
            f: M --> N
               (x, y) |--> (u, v, w) = (x + y, x - y, x*y)

        There is also the following shortcut for :meth:`one`::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: H = Hom(M, M)
            sage: H(1)
            Identity map Id_M of the 2-dimensional topological manifold M
        """
        if len(args) == 1:
            if self.domain() == self.codomain() and args[0] == 1:
                return self.one()
            if isinstance(args[0], ContinuousMap):
                return Homset.__call__(self, args[0])
        return Parent.__call__(self, *args, **kwds)
Beispiel #4
0
    def __init__(self, domain, codomain):
        """
        The Python constructor

        EXAMPLES::

            sage: R = QQ['x']['y']['s','t']['X']
            sage: p = R.random_element()
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: f = FlatteningMorphism(R)
            sage: g = f.section()
            sage: g(f(p)) == p
            True

        ::

            sage: R = QQ['a','b','x','y']
            sage: S = ZZ['a','b']['x','z']
            sage: from sage.rings.polynomial.flatten import UnflatteningMorphism
            sage: UnflatteningMorphism(R, S)
            Traceback (most recent call last):
            ...
            ValueError: rings must have same base ring

        ::

            sage: R = QQ['a','b','x','y']
            sage: S = QQ['a','b']['x','z','w']
            sage: from sage.rings.polynomial.flatten import UnflatteningMorphism
            sage: UnflatteningMorphism(R, S)
            Traceback (most recent call last):
            ...
            ValueError: rings must have the same number of variables
        """
        if not is_MPolynomialRing(domain):
            raise ValueError("domain should be a multivariate polynomial ring")
        if not is_PolynomialRing(codomain) and not is_MPolynomialRing(
                codomain):
            raise ValueError("codomain should be a polynomial ring")

        ring = codomain
        intermediate_rings = []

        while True:
            is_polynomial_ring = is_PolynomialRing(ring)
            if not (is_polynomial_ring or is_MPolynomialRing(ring)):
                break
            intermediate_rings.append((ring, is_polynomial_ring))
            ring = ring.base_ring()

        if domain.base_ring() != intermediate_rings[-1][0].base_ring():
            raise ValueError("rings must have same base ring")
        if domain.ngens() != sum([R.ngens() for R, _ in intermediate_rings]):
            raise ValueError("rings must have the same number of variables")

        self._intermediate_rings = intermediate_rings

        hom = Homset(domain, codomain, base=ring, check=False)
        Morphism.__init__(self, hom)
        self._repr_type_str = 'Unflattening'
Beispiel #5
0
    def __init__(self, X, Y, category=None):
        """
        EXAMPLES::

            sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ); W = V.span([2*V.0+4*V.1, 9*V.0+12*V.1, 4*V.2]); Q = V/W
            sage: type(Q.Hom(Q))
            <class 'sage.modules.fg_pid.fgp_morphism.FGP_Homset_class_with_category'>
        """
        if category is None:
            from sage.modules.free_module import is_FreeModule
            if is_FreeModule(X) and is_FreeModule(Y):
                from sage.all import FreeModules
                category = FreeModules(X.base_ring())
            else:
                from sage.all import Modules
                category = Modules(X.base_ring())
        Homset.__init__(self, X, Y, category)
Beispiel #6
0
    def __init__(self, X, Y, category=None):
        """
        EXAMPLES::

            sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ); W = V.span([2*V.0+4*V.1, 9*V.0+12*V.1, 4*V.2]); Q = V/W
            sage: type(Q.Hom(Q))
            <class 'sage.modules.fg_pid.fgp_morphism.FGP_Homset_class_with_category'>
        """
        if category is None:
            from sage.modules.free_module import is_FreeModule
            if is_FreeModule(X) and is_FreeModule(Y):
                from sage.all import FreeModules
                category = FreeModules(X.base_ring())
            else:
                from sage.all import Modules
                category = Modules(X.base_ring())
        Homset.__init__(self, X, Y, category)
Beispiel #7
0
    def __init__(self, X, Y, category=None, base=None, check=True):
        """
        Initalize ``self``.

        EXAMPLES::

            sage: L = LieAlgebra(QQ, 'x,y,z')
            sage: Lyn = L.Lyndon()
            sage: H = L.Hall()
            sage: HS = Hom(Lyn, H)

        We skip the elements test since homsets are not proper parents::

            sage: TestSuite(HS).run(skip=["_test_elements"])
        """
        if base is None:
            base = X.base_ring()
        Homset.__init__(self, X, Y, category, base, check)
Beispiel #8
0
    def __init__(self, X, Y, category=None, base=None, check=True):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: L = LieAlgebra(QQ, 'x,y,z')
            sage: Lyn = L.Lyndon()
            sage: H = L.Hall()
            sage: HS = Hom(Lyn, H)

        We skip the elements test since homsets are not proper parents::

            sage: TestSuite(HS).run(skip=["_test_elements"])
        """
        if base is None:
            base = X.base_ring()
        Homset.__init__(self, X, Y, category, base, check)
Beispiel #9
0
    def __init__(self, domain, codomain, name=None, latex_name=None):
        r"""
        Initialize ``self``.

        TESTS::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: X.<x,y> = M.chart()
            sage: N = Manifold(3, 'N', structure='topological')
            sage: Y.<u,v,w> = N.chart()
            sage: H = Hom(M, N) ; H
            Set of Morphisms from 2-dimensional topological manifold M to
             3-dimensional topological manifold N in Category of manifolds
             over Real Field with 53 bits of precision
            sage: TestSuite(H).run()

        Test for an endomorphism set::

            sage: E = Hom(M, M) ; E
            Set of Morphisms from 2-dimensional topological manifold M to
             2-dimensional topological manifold M in Category of manifolds over
             Real Field with 53 bits of precision
            sage: TestSuite(E).run()

        """
        from sage.manifolds.manifold import TopologicalManifold
        if not isinstance(domain, TopologicalManifold):
            raise TypeError("domain = {} is not an ".format(domain) +
                            "instance of TopologicalManifold")
        if not isinstance(codomain, TopologicalManifold):
            raise TypeError("codomain = {} is not an ".format(codomain) +
                            "instance of TopologicalManifold")
        Homset.__init__(self, domain, codomain)
        if name is None:
            self._name = "Hom({},{})".format(domain._name, codomain._name)
        else:
            self._name = name
        if latex_name is None:
            self._latex_name = r"\mathrm{{Hom}}\left({},{}\right)".format(
                                    domain._latex_name, codomain._latex_name)
        else:
            self._latex_name = latex_name
Beispiel #10
0
    def __init__(self, domain, codomain, name=None, latex_name=None):
        r"""
        Initialize ``self``.

        TESTS::

            sage: M = Manifold(2, 'M', structure='topological')
            sage: X.<x,y> = M.chart()
            sage: N = Manifold(3, 'N', structure='topological')
            sage: Y.<u,v,w> = N.chart()
            sage: H = Hom(M, N) ; H
            Set of Morphisms from 2-dimensional topological manifold M to
             3-dimensional topological manifold N in Category of manifolds
             over Real Field with 53 bits of precision
            sage: TestSuite(H).run()

        Test for an endomorphism set::

            sage: E = Hom(M, M) ; E
            Set of Morphisms from 2-dimensional topological manifold M to
             2-dimensional topological manifold M in Category of manifolds over
             Real Field with 53 bits of precision
            sage: TestSuite(E).run()

        """
        from sage.manifolds.manifold import TopologicalManifold
        if not isinstance(domain, TopologicalManifold):
            raise TypeError("domain = {} is not an ".format(domain) +
                            "instance of TopologicalManifold")
        if not isinstance(codomain, TopologicalManifold):
            raise TypeError("codomain = {} is not an ".format(codomain) +
                            "instance of TopologicalManifold")
        Homset.__init__(self, domain, codomain)
        if name is None:
            self._name = "Hom({},{})".format(domain._name, codomain._name)
        else:
            self._name = name
        if latex_name is None:
            self._latex_name = r"\mathrm{{Hom}}\left({},{}\right)".format(
                                    domain._latex_name, codomain._latex_name)
        else:
            self._latex_name = latex_name
Beispiel #11
0
    def __init__(self, domain, codomain, name=None, latex_name=None):
        r"""
        TESTS::

            sage: M = Manifold(2, 'M')
            sage: X.<x,y> = M.chart()
            sage: N = Manifold(3, 'N')
            sage: Y.<u,v,w> = N.chart()
            sage: H = Hom(M, N) ; H
            Set of Morphisms from 2-dimensional manifold 'M' to 3-dimensional
             manifold 'N' in Category of sets
            sage: TestSuite(H).run()

        Test for an endomorphism set::

            sage: E = Hom(M, M) ; E
            Set of Morphisms from 2-dimensional manifold 'M' to 2-dimensional
             manifold 'M' in Category of sets
            sage: TestSuite(E).run()

        """
        from sage.geometry.manifolds.domain import ManifoldOpenSubset
        if not isinstance(domain, ManifoldOpenSubset):
            raise TypeError("domain = {} is not an ".format(domain) +
                            "instance of ManifoldOpenSubset")
        if not isinstance(codomain, ManifoldOpenSubset):
            raise TypeError("codomain = {} is not an ".format(codomain) +
                            "instance of ManifoldOpenSubset")
        Homset.__init__(self, domain, codomain)
        if name is None:
            self._name = "Hom(" + domain._name + "," + codomain._name + ")"
        else:
            self._name = name
        if latex_name is None:
            self._latex_name = \
                    r"\mathrm{Hom}\left(" + domain._latex_name + "," + \
                    codomain._latex_name + r"\right)"
        else:
            self._latex_name = latex_name
        self._one = None  # to be set by self.one() if self is an endomorphism
Beispiel #12
0
    def __init__(self, fmodule1, fmodule2, name=None, latex_name=None):
        r"""
        TESTS::

            sage: from sage.tensor.modules.free_module_homset import FreeModuleHomset
            sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
            sage: N = FiniteRankFreeModule(ZZ, 2, name='N')
            sage: FreeModuleHomset(M, N)
            Set of Morphisms from Rank-3 free module M over the Integer Ring
             to Rank-2 free module N over the Integer Ring
             in Category of finite dimensional modules over Integer Ring

            sage: H = FreeModuleHomset(M, N, name='L(M,N)',
            ....:                      latex_name=r'\mathcal{L}(M,N)')
            sage: latex(H)
            \mathcal{L}(M,N)

        """
        from .finite_rank_free_module import FiniteRankFreeModule
        if not isinstance(fmodule1, FiniteRankFreeModule):
            raise TypeError("fmodule1 = {} is not an ".format(fmodule1) +
                            "instance of FiniteRankFreeModule")
        if not isinstance(fmodule2, FiniteRankFreeModule):
            raise TypeError("fmodule2 = {} is not an ".format(fmodule2) +
                            "instance of FiniteRankFreeModule")
        if fmodule1.base_ring() != fmodule2.base_ring():
            raise TypeError("the domain and codomain are not defined over " +
                            "the same ring")
        Homset.__init__(self, fmodule1, fmodule2)
        if name is None:
            self._name = "Hom(" + fmodule1._name + "," + fmodule2._name + ")"
        else:
            self._name = name
        if latex_name is None:
            self._latex_name = \
                    r"\mathrm{Hom}\left(" + fmodule1._latex_name + "," + \
                    fmodule2._latex_name + r"\right)"
        else:
            self._latex_name = latex_name
        self._one = None  # to be set by self.one() if self is an endomorphism
Beispiel #13
0
    def __init__(self, domain, codomain, name=None, latex_name=None):
        r"""
        TESTS::

            sage: M = Manifold(2, 'M')
            sage: X.<x,y> = M.chart()
            sage: N = Manifold(3, 'N')
            sage: Y.<u,v,w> = N.chart()
            sage: H = Hom(M, N) ; H
            Set of Morphisms from 2-dimensional manifold 'M' to 3-dimensional
             manifold 'N' in Category of sets
            sage: TestSuite(H).run()

        Test for an endomorphism set::

            sage: E = Hom(M, M) ; E
            Set of Morphisms from 2-dimensional manifold 'M' to 2-dimensional
             manifold 'M' in Category of sets
            sage: TestSuite(E).run()

        """
        from sage.geometry.manifolds.domain import ManifoldOpenSubset
        if not isinstance(domain, ManifoldOpenSubset):
            raise TypeError("domain = {} is not an ".format(domain) +
                            "instance of ManifoldOpenSubset")
        if not isinstance(codomain, ManifoldOpenSubset):
            raise TypeError("codomain = {} is not an ".format(codomain) +
                            "instance of ManifoldOpenSubset")
        Homset.__init__(self, domain, codomain)
        if name is None:
            self._name = "Hom(" + domain._name + "," + codomain._name + ")"
        else:
            self._name = name
        if latex_name is None:
            self._latex_name = \
                    r"\mathrm{Hom}\left(" + domain._latex_name + "," + \
                    codomain._latex_name + r"\right)"
        else:
            self._latex_name = latex_name
        self._one = None # to be set by self.one() if self is an endomorphism
Beispiel #14
0
    def __init__(self, fmodule1, fmodule2, name=None, latex_name=None):
        r"""
        TESTS::

            sage: from sage.tensor.modules.free_module_homset import FreeModuleHomset
            sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
            sage: N = FiniteRankFreeModule(ZZ, 2, name='N')
            sage: FreeModuleHomset(M, N)
            Set of Morphisms from Rank-3 free module M over the Integer Ring
             to Rank-2 free module N over the Integer Ring
             in Category of finite dimensional modules over Integer Ring

            sage: H = FreeModuleHomset(M, N, name='L(M,N)',
            ....:                      latex_name=r'\mathcal{L}(M,N)')
            sage: latex(H)
            \mathcal{L}(M,N)

        """
        from .finite_rank_free_module import FiniteRankFreeModule
        if not isinstance(fmodule1, FiniteRankFreeModule):
            raise TypeError("fmodule1 = {} is not an ".format(fmodule1) +
                            "instance of FiniteRankFreeModule")
        if not isinstance(fmodule2, FiniteRankFreeModule):
            raise TypeError("fmodule2 = {} is not an ".format(fmodule2) +
                            "instance of FiniteRankFreeModule")
        if fmodule1.base_ring() != fmodule2.base_ring():
            raise TypeError("the domain and codomain are not defined over " +
                            "the same ring")
        Homset.__init__(self, fmodule1, fmodule2)
        if name is None:
            self._name = "Hom(" + fmodule1._name + "," + fmodule2._name + ")"
        else:
            self._name = name
        if latex_name is None:
            self._latex_name = \
                    r"\mathrm{Hom}\left(" + fmodule1._latex_name + "," + \
                    fmodule2._latex_name + r"\right)"
        else:
            self._latex_name = latex_name
        self._one = None # to be set by self.one() if self is an endomorphism
Beispiel #15
0
    def __init__(self, domain, codomain, category=None):
        """
        Initialize ``self``. Type ``QuiverHomSpace?`` for more information.

        TESTS::

            sage: Q = DiGraph({1:{2:['a', 'b']}}).path_semigroup()
            sage: H = Q.S(QQ, 2).Hom(Q.P(QQ, 1))
            sage: TestSuite(H).run()
        """
        # The data in the class is stored in the following private variables:
        #
        # * _base
        #      The base ring of the representations M and N.
        # * _codomain
        #      The QuiverRep object of the codomain N.
        # * _domain
        #      The QuiverRep object of the domain M.
        # * _quiver
        #      The quiver of the representations M and N.
        # * _space
        #      A free module with ambient space.
        #
        # The free module _space is the homomorphism space.  The ambient space
        # is k^n where k is the base ring and n is the sum of the dimensions of
        # the spaces of homomorphisms between the free modules attached in M
        # and N to the vertices of the quiver.  Each coordinate represents a
        # single entry in one of those matrices.

        # Get the quiver and base ring and check they they are the same for
        # both modules
        if domain._semigroup != codomain._semigroup:
            raise ValueError("representations are not over the same quiver")
        self._quiver = domain._quiver
        self._semigroup = domain._semigroup

        # Check that the bases are compatible, and then initialise the homset:
        if codomain.base_ring() != domain.base_ring():
            raise ValueError("representations are not over the same base ring")
        Homset.__init__(self,
                        domain,
                        codomain,
                        category=category,
                        base=domain.base_ring())

        # To compute the Hom Space we set up a 'generic' homomorphism where the
        # maps at each vertex are described by matrices whose entries are
        # variables.  Then the commutativity of edge diagrams gives us a
        # system of equations whose solution space is the Hom Space we're
        # looking for.  The variables will be numbered consecutively starting
        # at 0, ordered first by the vertex the matrix occurs at, then by row
        # then by column.  We'll have to keep track of which variables
        # correspond to which matrices.

        # eqs will count the number of equations in our system of equations,
        # varstart will be a list whose ith entry is the number of the
        # variable located at (0, 0) in the matrix assigned to the
        # ith vertex. (So varstart[0] will be 0.)
        eqs = 0
        verts = domain._quiver.vertices()
        varstart = [0] * (len(verts) + 1)

        # First assign to varstart the dimension of the matrix assigned to the
        # previous vertex.
        for v in verts:
            varstart[verts.index(v) + 1] = domain._spaces[v].dimension(
            ) * codomain._spaces[v].dimension()
        for e in domain._quiver.edges():
            eqs += domain._spaces[e[0]].dimension() * codomain._spaces[
                e[1]].dimension()

        # After this cascading sum varstart[v] will be the sum of the
        # dimensions of the matrices assigned to vertices ordered before v.
        # This is equal to the number of the first variable assigned to v.
        for i in range(2, len(varstart)):
            varstart[i] += varstart[i - 1]

        # This will be the coefficient matrix for the system of equations.  We
        # start with all zeros and will fill in as we go.  We think of this
        # matrix as acting on the right so the columns correspond to equations,
        # the rows correspond to variables, and .kernel() will give a right
        # kernel as is needed.
        from sage.matrix.constructor import Matrix
        coef_mat = Matrix(codomain.base_ring(), varstart[-1], eqs)

        # eqn keeps track of what equation we are on.  If the maps X and Y are
        # assigned to an edge e and A and B are the matrices of variables that
        # describe the generic maps at the initial and final vertices of e
        # then commutativity of the edge diagram is described by the equation
        # AY = XB, or
        #
        #          Sum_k A_ik*Y_kj - Sum_k X_ik*B_kj == 0 for all i and j.
        #
        # Below we loop through these values of i,j,k and write the
        # coefficients of the equation above into the coefficient matrix.
        eqn = 0
        for e in domain._quiver.edges():
            X = domain._maps[e].matrix()
            Y = codomain._maps[e].matrix()
            for i in range(0, X.nrows()):
                for j in range(0, Y.ncols()):
                    for k in range(0, Y.nrows()):
                        coef_mat[varstart[verts.index(e[0])] + i * Y.nrows() +
                                 k, eqn] = Y[k, j]
                    for k in range(0, X.ncols()):
                        coef_mat[varstart[verts.index(e[1])] + k * Y.ncols() +
                                 j, eqn] = -X[i, k]
                    eqn += 1

        # Now we can create the hom space
        self._space = coef_mat.kernel()

        # Bind identity if domain = codomain
        if domain is codomain:
            self.identity = self._identity
 def _Hom_(X, Y, category):
     # here we overwrite the Rings._Hom_ implementation
     return Homset(X, Y, category=category)
Beispiel #17
0
    def __init__(self, domain):
        """
        The Python constructor

        EXAMPLES::

            sage: R = ZZ['a', 'b', 'c']['x', 'y', 'z']
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: FlatteningMorphism(R)
            Flattening morphism:
              From: Multivariate Polynomial Ring in x, y, z over Multivariate Polynomial Ring in a, b, c over Integer Ring
              To:   Multivariate Polynomial Ring in a, b, c, x, y, z over Integer Ring

        ::

            sage: R = ZZ['a']['b']['c']
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: FlatteningMorphism(R)
            Flattening morphism:
              From: Univariate Polynomial Ring in c over Univariate Polynomial Ring in b over Univariate Polynomial Ring in a over Integer Ring
              To:   Multivariate Polynomial Ring in a, b, c over Integer Ring

        ::

            sage: R = ZZ['a']['a','b']
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: FlatteningMorphism(R)
            Flattening morphism:
              From: Multivariate Polynomial Ring in a, b over Univariate Polynomial Ring in a over Integer Ring
              To:   Multivariate Polynomial Ring in a, a0, b over Integer Ring

        ::

            sage: K.<v> = NumberField(x^3 - 2)
            sage: R = K['x','y']['a','b']
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: f = FlatteningMorphism(R)
            sage: f(R('v*a*x^2 + b^2 + 1/v*y'))
            (v)*x^2*a + b^2 + (1/2*v^2)*y

        ::

            sage: R = QQbar['x','y']['a','b']
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: f = FlatteningMorphism(R)
            sage: f(R('QQbar(sqrt(2))*a*x^2 + b^2 + QQbar(I)*y'))
            1.414213562373095?*x^2*a + b^2 + I*y

        ::

            sage: R.<z> = PolynomialRing(QQbar,1)
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: f = FlatteningMorphism(R)
            sage: f.domain(), f.codomain()
            (Multivariate Polynomial Ring in z over Algebraic Field,
             Multivariate Polynomial Ring in z over Algebraic Field)

        ::

            sage: R.<z> = PolynomialRing(QQbar)
            sage: from sage.rings.polynomial.flatten import FlatteningMorphism
            sage: f = FlatteningMorphism(R)
            sage: f.domain(), f.codomain()
            (Univariate Polynomial Ring in z over Algebraic Field,
             Univariate Polynomial Ring in z over Algebraic Field)

        TESTS::

            sage: Pol = QQ['x']['x0']['x']
            sage: fl = FlatteningMorphism(Pol)
            sage: fl
            Flattening morphism:
              From: Univariate Polynomial Ring in x over Univariate Polynomial Ring in x0 over Univariate Polynomial Ring in x over Rational Field
              To:   Multivariate Polynomial Ring in x, x0, x1 over Rational Field
            sage: p = Pol([[[1,2],[3,4]],[[5,6],[7,8]]])
            sage: fl.section()(fl(p)) == p
            True
        """
        if not is_PolynomialRing(domain) and not is_MPolynomialRing(domain):
            raise ValueError("domain should be a polynomial ring")

        ring = domain
        variables = []
        intermediate_rings = []

        while is_PolynomialRing(ring) or is_MPolynomialRing(ring):
            intermediate_rings.append(ring)
            v = ring.variable_names()
            variables.extend(reversed(v))
            ring = ring.base_ring()
        self._intermediate_rings = intermediate_rings
        variables.reverse()
        for i, a in enumerate(variables):
            if a in variables[:i]:
                for index in itertools.count():
                    b = a + str(index)
                    if b not in variables:  # not just variables[:i]!
                        break
                variables[i] = b
        if is_MPolynomialRing(domain):
            codomain = PolynomialRing(ring, variables, len(variables))
        else:
            codomain = PolynomialRing(ring, variables)

        hom = Homset(domain, codomain, base=ring, check=False)
        Morphism.__init__(self, hom)
        self._repr_type_str = 'Flattening'
Beispiel #18
0
    def __init__(self, domain, codomain, category=None):
        """
        Initialize ``self``. Type ``QuiverHomSpace?`` for more information.

        TESTS::

            sage: Q = DiGraph({1:{2:['a', 'b']}}).path_semigroup()
            sage: H = Q.S(QQ, 2).Hom(Q.P(QQ, 1))
            sage: TestSuite(H).run()
        """
        # The data in the class is stored in the following private variables:
        #
        # * _base
        #      The base ring of the representations M and N.
        # * _codomain
        #      The QuiverRep object of the codomain N.
        # * _domain
        #      The QuiverRep object of the domain M.
        # * _quiver
        #      The quiver of the representations M and N.
        # * _space
        #      A free module with ambient space.
        #
        # The free module _space is the homomorphism space.  The ambient space
        # is k^n where k is the base ring and n is the sum of the dimensions of
        # the spaces of homomorphisms between the free modules attached in M
        # and N to the vertices of the quiver.  Each coordinate represents a
        # single entry in one of those matrices.

        # Get the quiver and base ring and check they they are the same for
        # both modules
        if domain._semigroup != codomain._semigroup:
            raise ValueError("representations are not over the same quiver")
        self._quiver = domain._quiver
        self._semigroup = domain._semigroup

        # Check that the bases are compatible, and then initialise the homset:
        if codomain.base_ring() != domain.base_ring():
            raise ValueError("representations are not over the same base ring")
        Homset.__init__(self, domain, codomain, category=category, base = domain.base_ring())

        # To compute the Hom Space we set up a 'generic' homomorphism where the
        # maps at each vertex are described by matrices whose entries are
        # variables.  Then the commutativity of edge diagrams gives us a
        # system of equations whose solution space is the Hom Space we're
        # looking for.  The variables will be numbered consecutively starting
        # at 0, ordered first by the vertex the matrix occurs at, then by row
        # then by column.  We'll have to keep track of which variables
        # correspond to which matrices.

        # eqs will count the number of equations in our system of equations,
        # varstart will be a list whose ith entry is the number of the
        # variable located at (0, 0) in the matrix assigned to the
        # ith vertex. (So varstart[0] will be 0.)
        eqs = 0
        verts = domain._quiver.vertices()
        varstart = [0]*(len(verts) + 1)

        # First assign to varstart the dimension of the matrix assigned to the
        # previous vertex.
        for v in verts:
            varstart[verts.index(v) + 1] = domain._spaces[v].dimension()*codomain._spaces[v].dimension()
        for e in domain._quiver.edges():
            eqs += domain._spaces[e[0]].dimension()*codomain._spaces[e[1]].dimension()

        # After this cascading sum varstart[v] will be the sum of the
        # dimensions of the matrices assigned to vertices ordered before v.
        # This is equal to the number of the first variable assigned to v.
        for i in range(2, len(varstart)):
            varstart[i] += varstart[i-1]

        # This will be the coefficient matrix for the system of equations.  We
        # start with all zeros and will fill in as we go.  We think of this
        # matrix as acting on the right so the columns correspond to equations,
        # the rows correspond to variables, and .kernel() will give a right
        # kernel as is needed.
        from sage.matrix.constructor import Matrix
        coef_mat = Matrix(codomain.base_ring(), varstart[-1], eqs)

        # eqn keeps track of what equation we are on.  If the maps X and Y are
        # assigned to an edge e and A and B are the matrices of variables that
        # describe the generic maps at the initial and final vertices of e
        # then commutativity of the edge diagram is described by the equation
        # AY = XB, or
        #
        #          Sum_k A_ik*Y_kj - Sum_k X_ik*B_kj == 0 for all i and j.
        #
        # Below we loop through these values of i,j,k and write the
        # coefficients of the equation above into the coefficient matrix.
        eqn = 0
        for e in domain._quiver.edges():
            X = domain._maps[e].matrix()
            Y = codomain._maps[e].matrix()
            for i in range(0, X.nrows()):
                for j in range(0, Y.ncols()):
                    for k in range(0, Y.nrows()):
                        coef_mat[varstart[verts.index(e[0])] + i*Y.nrows() + k, eqn] = Y[k, j]
                    for k in range(0, X.ncols()):
                        coef_mat[varstart[verts.index(e[1])] + k*Y.ncols() + j, eqn] = -X[i, k]
                    eqn += 1

        # Now we can create the hom space
        self._space = coef_mat.kernel()

        # Bind identity if domain = codomain
        if domain is codomain:
            self.identity = self._identity