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 = [])
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)
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'
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)
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)
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)
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
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
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
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)
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'
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