def __init__(self, domain, codomain, data={}): """ Initialize ``self``. Type ``QuiverRepHom?`` for more information. TESTS:: sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: spaces = {1: QQ^2, 2: QQ^2, 3:QQ^1} sage: maps = {(1, 2, 'a'): [[1, 0], [0, 0]], (1, 2, 'b'): [[0, 0], [0, 1]], (2, 3, 'c'): [[1], [1]]} sage: M = Q.representation(QQ, spaces, maps) sage: spaces2 = {2: QQ^1, 3: QQ^1} sage: S = Q.representation(QQ, spaces2) sage: f = S.hom(M) sage: f.is_zero() True sage: maps2 = {2:[1, -1], 3:1} sage: g = S.hom(maps2, M) sage: x = M({2: (1, -1)}) sage: y = M({3: (1,)}) sage: h = S.hom([x, y], M) sage: g == h True sage: Proj = Q.P(GF(7), 3) sage: Simp = Q.S(GF(7), 3) sage: im = Simp({3: (1,)}) sage: Proj.hom(im, Simp).is_surjective() True :: sage: Q = DiGraph({1:{2:['a']}}).path_semigroup() sage: H1 = Q.P(GF(3), 2).Hom(Q.S(GF(3), 2)) sage: H2 = Q.P(GF(3), 2).Hom(Q.S(GF(3), 1)) sage: H1.an_element() in H1 # indirect doctest True """ # The data of a representation is held in the following private # variables: # # * _quiver # The quiver of the representation. # * _base_ring # The base ring of the representation. # * _domain # The QuiverRep object that is the domain of the homomorphism. # * _codomain # The QuiverRep object that is the codomain of the homomorphism. # * _vector # A vector in some free module over the base ring of a length such # that each coordinate corresponds to an entry in the matrix of a # homomorphism attached to a vertex. # # The variable data can also be a vector of appropriate length. When # this is the case it will be loaded directly into _vector and then # _assert_valid_hom is called. from sage.quivers.representation import QuiverRepElement, QuiverRep_with_path_basis self._domain = domain self._codomain = codomain self._quiver = domain._quiver self._base_ring = domain.base_ring() # Check that the quiver and base ring match if codomain._quiver != self._quiver: raise ValueError( "the quivers of the domain and codomain must be equal") if codomain.base_ring() != self._base_ring: raise ValueError( "the base ring of the domain and codomain must be equal") # Get the dimensions of the spaces mat_dims = {} domain_dims = {} codomain_dims = {} for v in self._quiver: domain_dims[v] = domain._spaces[v].dimension() codomain_dims[v] = codomain._spaces[v].dimension() mat_dims[v] = domain_dims[v] * codomain_dims[v] total_dim = sum(mat_dims.values()) # Handle the case when data is a vector if data in self._base_ring**total_dim: self._vector = data self._assert_valid_hom() super(QuiverRepHom, self).__init__(domain.Hom(codomain)) return # If data is not a dict, create one if isinstance(data, dict): maps_dict = data else: # If data is not a list create one, then create a dict from it if isinstance(data, list): im_list = data else: # If data is a QuiverRepHom, create a list from it if isinstance(data, QuiverRepHom): f = data._domain.coerce_map_from(domain) g = self._codomain.coerce_map_from(data._codomain) im_list = [g(data(f(x))) for x in domain.gens()] # The only case left is that data is a QuiverRepElement else: if not isinstance(data, QuiverRepElement): raise TypeError("input data must be dictionary, list, " "QuiverRepElement or vector") if not isinstance(domain, QuiverRep_with_path_basis): raise TypeError( "if data is a QuiverRepElement then domain " "must be a QuiverRep_with_path_basis.") if data not in codomain: raise ValueError( "if data is a QuiverRepElement then it must " "be an element of codomain") im_list = [ codomain.right_edge_action(data, p) for v in domain._quiver for p in domain._bases[v] ] # WARNING: This code assumes that the function QuiverRep.gens() returns # the generators ordered first by vertex and then by the order of the # gens() method of the space associated to that vertex. In particular # this is the order that corresponds to how maps are represented via # matrices # Get the gens of the domain and check that im_list is the right length dom_gens = domain.gens() if len(im_list) != len(dom_gens): raise ValueError( ("domain is dimension {} but only {} images" " were supplied").format(len(dom_gens), len(im_list))) # Get the matrices of the maps start_index = 0 maps_dict = {} for v in self._quiver: maps_dict[v] = [] dim = domain._spaces[v].dimension() for i in range(start_index, start_index + dim): if len(im_list[i].support()) != 0 and im_list[i].support( ) != [v]: # If the element doesn't have the correct support raise # an error here, otherwise we might create a valid hom # that does not map the generators to the supplied # images raise ValueError( ("generator supported at vertex {} cannot" " map to element with support {}").format( v, im_list[i].support())) else: # If the support works out add the images coordinates # as a row of the matrix maps_dict[v].append(codomain._spaces[v].coordinates( im_list[i]._elems[v])) start_index += dim # Get the coordinates of the vector from sage.categories.map import is_Map vector = [] for v in self._quiver: if v in maps_dict: if is_Map(maps_dict[v]): try: m = maps_dict[v].matrix() except (AttributeError, ValueError): gens_images = [ codomain._spaces[v].coordinate_vector( maps_dict[v](x)) for x in domain._spaces[v].gens() ] m = Matrix(self._base_ring, domain_dims[v], codomain_dims[v], gens_images) else: m = Matrix(self._base_ring, domain_dims[v], codomain_dims[v], maps_dict[v]) else: m = Matrix(self._base_ring, domain_dims[v], codomain_dims[v]) for i in range(0, domain_dims[v]): vector += list(m[i]) # Wrap as a vector, check it, and return self._vector = (self._base_ring**total_dim)(vector) self._assert_valid_hom() super(QuiverRepHom, self).__init__(domain.Hom(codomain))
def __init__(self, domain, codomain, data={}): """ Initialize ``self``. Type ``QuiverRepHom?`` for more information. TESTS:: sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: spaces = {1: QQ^2, 2: QQ^2, 3:QQ^1} sage: maps = {(1, 2, 'a'): [[1, 0], [0, 0]], (1, 2, 'b'): [[0, 0], [0, 1]], (2, 3, 'c'): [[1], [1]]} sage: M = Q.representation(QQ, spaces, maps) sage: spaces2 = {2: QQ^1, 3: QQ^1} sage: S = Q.representation(QQ, spaces2) sage: f = S.hom(M) sage: f.is_zero() True sage: maps2 = {2:[1, -1], 3:1} sage: g = S.hom(maps2, M) sage: x = M({2: (1, -1)}) sage: y = M({3: (1,)}) sage: h = S.hom([x, y], M) sage: g == h True sage: Proj = Q.P(GF(7), 3) sage: Simp = Q.S(GF(7), 3) sage: im = Simp({3: (1,)}) sage: Proj.hom(im, Simp).is_surjective() True :: sage: Q = DiGraph({1:{2:['a']}}).path_semigroup() sage: H1 = Q.P(GF(3), 2).Hom(Q.S(GF(3), 2)) sage: H2 = Q.P(GF(3), 2).Hom(Q.S(GF(3), 1)) sage: H1.an_element() in H1 # indirect doctest True """ # The data of a representation is held in the following private # variables: # # * _quiver # The quiver of the representation. # * _base_ring # The base ring of the representation. # * _domain # The QuiverRep object that is the domain of the homomorphism. # * _codomain # The QuiverRep object that is the codomain of the homomorphism. # * _vector # A vector in some free module over the base ring of a length such # that each coordinate corresponds to an entry in the matrix of a # homomorphism attached to a vertex. # # The variable data can also be a vector of appropriate length. When # this is the case it will be loaded directly into _vector and then # _assert_valid_hom is called. from sage.quivers.representation import QuiverRepElement, QuiverRep_with_path_basis self._domain = domain self._codomain = codomain self._quiver = domain._quiver self._base_ring = domain.base_ring() # Check that the quiver and base ring match if codomain._quiver != self._quiver: raise ValueError("the quivers of the domain and codomain must be equal") if codomain.base_ring() != self._base_ring: raise ValueError("the base ring of the domain and codomain must be equal") # Get the dimensions of the spaces mat_dims = {} domain_dims = {} codomain_dims = {} for v in self._quiver: domain_dims[v] = domain._spaces[v].dimension() codomain_dims[v] = codomain._spaces[v].dimension() mat_dims[v] = domain_dims[v]*codomain_dims[v] total_dim = sum(mat_dims.values()) # Handle the case when data is a vector if data in self._base_ring**total_dim: self._vector = data self._assert_valid_hom() super(QuiverRepHom, self).__init__(domain.Hom(codomain)) return # If data is not a dict, create one if isinstance(data, dict): maps_dict = data else: # If data is not a list create one, then create a dict from it if isinstance(data, list): im_list = data else: # If data is a QuiverRepHom, create a list from it if isinstance(data, QuiverRepHom): f = data._domain.coerce_map_from(domain) g = self._codomain.coerce_map_from(data._codomain) im_list = [g(data(f(x))) for x in domain.gens()] # The only case left is that data is a QuiverRepElement else: if not isinstance(data, QuiverRepElement): raise TypeError("input data must be dictionary, list, " "QuiverRepElement or vector") if not isinstance(domain, QuiverRep_with_path_basis): raise TypeError("if data is a QuiverRepElement then domain " "must be a QuiverRep_with_path_basis.") if data not in codomain: raise ValueError("if data is a QuiverRepElement then it must " "be an element of codomain") im_list = [codomain.right_edge_action(data, p) for v in domain._quiver for p in domain._bases[v]] # WARNING: This code assumes that the function QuiverRep.gens() returns # the generators ordered first by vertex and then by the order of the # gens() method of the space associated to that vertex. In particular # this is the order that corresponds to how maps are represented via # matrices # Get the gens of the domain and check that im_list is the right length dom_gens = domain.gens() if len(im_list) != len(dom_gens): raise ValueError(("domain is dimension {} but only {} images" " were supplied").format(len(dom_gens), len(im_list))) # Get the matrices of the maps start_index = 0 maps_dict = {} for v in self._quiver: maps_dict[v] = [] dim = domain._spaces[v].dimension() for i in range(start_index, start_index + dim): if len(im_list[i].support()) != 0 and im_list[i].support() != [v]: # If the element doesn't have the correct support raise # an error here, otherwise we might create a valid hom # that does not map the generators to the supplied # images raise ValueError(("generator supported at vertex {} cannot" " map to element with support {}").format( v, im_list[i].support())) else: # If the support works out add the images coordinates # as a row of the matrix maps_dict[v].append(codomain._spaces[v].coordinates(im_list[i]._elems[v])) start_index += dim # Get the coordinates of the vector from sage.categories.map import is_Map vector = [] for v in self._quiver: if v in maps_dict: if is_Map(maps_dict[v]): if hasattr(maps_dict[v], 'matrix'): m = maps_dict[v].matrix() else: gens_images = [codomain._spaces[v].coordinate_vector(maps_dict[v](x)) for x in domain._spaces[v].gens()] m = Matrix(self._base_ring, domain_dims[v], codomain_dims[v], gens_images) else: m = Matrix(self._base_ring, domain_dims[v], codomain_dims[v], maps_dict[v]) else: m = Matrix(self._base_ring, domain_dims[v], codomain_dims[v]) for i in range(0, domain_dims[v]): vector += list(m[i]) # Wrap as a vector, check it, and return self._vector = (self._base_ring**total_dim)(vector) self._assert_valid_hom() super(QuiverRepHom, self).__init__(domain.Hom(codomain))