Quiver Morphisms¶
- class sage.quivers.morphism.QuiverRepHom(domain, codomain, data={})[source]¶
Bases:
CallMorphism
A homomorphism of quiver representations (of one and the same quiver) is given by specifying, for each vertex of the quiver, a homomorphism of the spaces assigned to this vertex such that these homomorphisms commute with the edge maps. The domain and codomain of the homomorphism are required to be representations of the same quiver over the same base ring.
INPUT:
domain
–QuiverRep
, the domain of the homomorphismcodomain
–QuiverRep
, the codomain of the homomorphismdata
– dict, list, orQuiverRepElement
(default: empty dict), with the following meaning:list:
data
can be a list of images for the generators of the domain. “Generators” means the output of thegens()
method. An error will be generated if the map so defined is not equivariant with respect to the action of the quiver.dictionary:
data
can be a dictionary associating to each vertex of the quiver either a homomorphism with domain and codomain the spaces associated to this vertex in the domain and codomain modules respectively, or a matrix defining such a homomorphism, or an object that sage can construct such a matrix from. Not all vertices must be specified, unspecified vertices are assigned the zero map, and keys not corresponding to vertices of the quiver are ignored. An error will be generated if these maps do not commute with the edge maps of the domain and codomain.QuiverRepElement
: if the domain is aQuiverRep_with_path_basis
thendata
can be a singleQuiverRepElement
belonging to the codomain. The map is then defined by sending each path,p
, in the basis todata*p
. Ifdata
is not an element of the codomain or the domain is not aQuiverRep_with_path_basis
then an error will be generated.QuiverRepHom
: the input can also be a map \(f : D \to C\) such that there is a coercion from the domain ofself
toD
and fromC
to the codomain ofself
. The composition of these maps is the result.
OUTPUT:
QuiverRepHom
EXAMPLES:
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)
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> spaces = {Integer(1): QQ**Integer(2), Integer(2): QQ**Integer(2), Integer(3):QQ**Integer(1)} >>> maps = {(Integer(1), Integer(2), 'a'): [[Integer(1), Integer(0)], [Integer(0), Integer(0)]], (Integer(1), Integer(2), 'b'): [[Integer(0), Integer(0)], [Integer(0), Integer(1)]], (Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(1)]]} >>> M = Q.representation(QQ, spaces, maps) >>> spaces2 = {Integer(2): QQ**Integer(1), Integer(3): QQ**Integer(1)} >>> S = Q.representation(QQ, spaces2)
With no additional data this creates the zero map:
sage: f = S.hom(M) sage: f.is_zero() True
>>> from sage.all import * >>> f = S.hom(M) >>> f.is_zero() True
We must specify maps at the vertices to get a nonzero homomorphism. Note that if the dimensions of the spaces assigned to the domain and codomain of a vertex are equal then Sage will construct the identity matrix from
1
:sage: maps2 = {2:[1, -1], 3:1} sage: g = S.hom(maps2, M)
>>> from sage.all import * >>> maps2 = {Integer(2):[Integer(1), -Integer(1)], Integer(3):Integer(1)} >>> g = S.hom(maps2, M)
Here we create the same map by specifying images for the generators:
sage: x = M({2: (1, -1)}) sage: y = M({3: (1,)}) sage: h = S.hom([x, y], M) sage: g == h True
>>> from sage.all import * >>> x = M({Integer(2): (Integer(1), -Integer(1))}) >>> y = M({Integer(3): (Integer(1),)}) >>> h = S.hom([x, y], M) >>> g == h True
If the domain is a module of type QuiverRep_with_path_basis (for example, the indecomposable projectives) we can create maps by specifying a single image:
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
>>> from sage.all import * >>> Proj = Q.P(GF(Integer(7)), Integer(3)) >>> Simp = Q.S(GF(Integer(7)), Integer(3)) >>> im = Simp({Integer(3): (Integer(1),)}) >>> Proj.hom(im, Simp).is_surjective() True
- algebraic_dual()[source]¶
Compute the algebraic dual \(f^t : N^t \to M^t\) of
self
= \(f : M \to N\) where \((-)^t = Hom_Q(-, kQ)\).OUTPUT:
QuiverRepHom
; the map \(f^t : N^t \to M^t\)Note
If \(e\) is an edge of the quiver \(Q\) and \(g\) is an element of \(Hom_Q(N, kQ)\) then we let \((ge)(m) = eg(m)\). This gives \(Hom_Q(N, kQ)\) its structure as a module over the opposite quiver
Q.reverse()
. The map \(Hom_Q(N, kQ) \to Hom_Q(M, kQ)\) returned sends \(g\) to \(gf\).EXAMPLES:
sage: Q = DiGraph({1:{2:['a'], 3:['b','c','d']}, 2:{4:['e','f']}, 3:{4:['g']}, 5:{2:['h','i']}}).path_semigroup() sage: P1 = Q.P(QQ, 4) sage: P1.algebraic_dual() Representation with dimension vector (5, 2, 1, 1, 4)
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a'], Integer(3):['b','c','d']}, Integer(2):{Integer(4):['e','f']}, Integer(3):{Integer(4):['g']}, Integer(5):{Integer(2):['h','i']}}).path_semigroup() >>> P1 = Q.P(QQ, Integer(4)) >>> P1.algebraic_dual() Representation with dimension vector (5, 2, 1, 1, 4)
The algebraic dual of an indecomposable projective is the indecomposable projective of the same vertex in the opposite quiver.
sage: Q.reverse().P(QQ, 4) Representation with dimension vector (5, 2, 1, 1, 4)
>>> from sage.all import * >>> Q.reverse().P(QQ, Integer(4)) Representation with dimension vector (5, 2, 1, 1, 4)
- base_ring()[source]¶
Return the base ring of the representation in the codomain.
OUTPUT: the base ring of the codomain
EXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: f = P.hom({1: 1, 2: 1, 3: 1}, P) sage: f.base_ring() is QQ True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> f = P.hom({Integer(1): Integer(1), Integer(2): Integer(1), Integer(3): Integer(1)}, P) >>> f.base_ring() is QQ True
- codomain()[source]¶
Return the codomain of the homomorphism.
OUTPUT:
QuiverRep
; the codomainEXAMPLES:
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: S = Q.representation(QQ) sage: g = S.hom(M) sage: g.codomain() is M True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> spaces = {Integer(1): QQ**Integer(2), Integer(2): QQ**Integer(2), Integer(3):QQ**Integer(1)} >>> maps = {(Integer(1), Integer(2), 'a'): [[Integer(1), Integer(0)], [Integer(0), Integer(0)]], (Integer(1), Integer(2), 'b'): [[Integer(0), Integer(0)], [Integer(0), Integer(1)]], (Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(1)]]} >>> M = Q.representation(QQ, spaces, maps) >>> S = Q.representation(QQ) >>> g = S.hom(M) >>> g.codomain() is M True
- cokernel()[source]¶
Return the cokernel of
self
.OUTPUT:
QuiverRep
; the cokernelNote
To get the factor map of the codomain,
D
, onto the cokernel,C
, useC.coerce_map_from(D)
.EXAMPLES:
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^2, 3: QQ^1} sage: N = Q.representation(QQ, spaces2, {(2, 3, 'c'): [[1], [0]]}) sage: maps2 = {2:[[1, 0], [0, 0]], 3:1} sage: g = N.hom(maps2, M) sage: g.cokernel().dimension_vector() (2, 1, 0)
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> spaces = {Integer(1): QQ**Integer(2), Integer(2): QQ**Integer(2), Integer(3):QQ**Integer(1)} >>> maps = {(Integer(1), Integer(2), 'a'): [[Integer(1), Integer(0)], [Integer(0), Integer(0)]], (Integer(1), Integer(2), 'b'): [[Integer(0), Integer(0)], [Integer(0), Integer(1)]], (Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(1)]]} >>> M = Q.representation(QQ, spaces, maps) >>> spaces2 = {Integer(2): QQ**Integer(2), Integer(3): QQ**Integer(1)} >>> N = Q.representation(QQ, spaces2, {(Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(0)]]}) >>> maps2 = {Integer(2):[[Integer(1), Integer(0)], [Integer(0), Integer(0)]], Integer(3):Integer(1)} >>> g = N.hom(maps2, M) >>> g.cokernel().dimension_vector() (2, 1, 0)
- direct_sum(maps, return_maps=False, pinch=None)[source]¶
Return the direct sum of
self
with the maps in the listmaps
.INPUT:
maps
–QuiverRepHom
or list ofQuiverRepHom
’sreturn_maps
– boolean (default:False
); ifFalse
, then the return value is aQuiverRepHom
which is the direct sum ofself
with theQuiverRepHoms
inmaps
. IfTrue
, then the return value is a tuple of length either 3 or 5. The first entry of the tuple is the QuiverRepHom giving the direct sum. Ifpinch
is eitherNone
or'codomain'
then the next two entries in the tuple are lists giving respectively the inclusion and the projection maps for the factors of the direct sum. Summands are ordered as given in maps withself
as the zeroth summand. Ifpinch
is eitherNone
or'domain'
then the next two entries in the tuple are the inclusion and projection maps for the codomain. Thus ifpinch
isNone
then the tuple will have length 5. Ifpinch
is either'domain'
or'codomain'
then the tuple will have length 3.pinch
– string orNone
(default:None
); if this is equal to'domain'
, then the domains ofself
and the given maps must be equal. The direct sum of \(f: A \to B\) and \(g: A \to C\) returned is then the map \(A \to B \oplus C\) defined by sending \(x\) to \((f(x), g(x))\). Ifpinch
equals'codomain'
, then the codomains ofself
and the given maps must be equal. The direct sum of \(f: A \to C\) and \(g: B \to C\) returned is then the map \(A \oplus B \to C\) defined by sending \((x, y)\) to \(f(x) + g(y)\). Finally, ifpinch
is anything other than'domain'
or'codomain'
, then the direct sum of \(f: A \to B\) and \(g: C \to D\) returned is the map \(A \oplus C \to B \oplus D\) defined by sending \((x, y)\) to \((f(x), g(y))\).
OUTPUT:
QuiverRepHom
or tupleEXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}}).path_semigroup() sage: P1 = Q.P(GF(3), 1) sage: P2 = Q.P(GF(3), 2) sage: S1 = P1/P1.radical() sage: S2 = P2/P2.radical() sage: pi1 = S1.coerce_map_from(P1) sage: pi2 = S2.coerce_map_from(P2) sage: f = pi1.direct_sum(pi2) sage: f.domain().dimension_vector() == Q.free_module(GF(3)).dimension_vector() True sage: f.is_surjective() True sage: id = P1.Hom(P1).identity() sage: g = pi1.direct_sum(id, pinch='domain') sage: g.is_surjective() False
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}}).path_semigroup() >>> P1 = Q.P(GF(Integer(3)), Integer(1)) >>> P2 = Q.P(GF(Integer(3)), Integer(2)) >>> S1 = P1/P1.radical() >>> S2 = P2/P2.radical() >>> pi1 = S1.coerce_map_from(P1) >>> pi2 = S2.coerce_map_from(P2) >>> f = pi1.direct_sum(pi2) >>> f.domain().dimension_vector() == Q.free_module(GF(Integer(3))).dimension_vector() True >>> f.is_surjective() True >>> id = P1.Hom(P1).identity() >>> g = pi1.direct_sum(id, pinch='domain') >>> g.is_surjective() False
- domain()[source]¶
Return the domain of the homomorphism.
OUTPUT:
QuiverRep
; the domainEXAMPLES:
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: S = Q.representation(QQ) sage: g = M.hom(S) sage: g.domain() is M True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> spaces = {Integer(1): QQ**Integer(2), Integer(2): QQ**Integer(2), Integer(3):QQ**Integer(1)} >>> maps = {(Integer(1), Integer(2), 'a'): [[Integer(1), Integer(0)], [Integer(0), Integer(0)]], (Integer(1), Integer(2), 'b'): [[Integer(0), Integer(0)], [Integer(0), Integer(1)]], (Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(1)]]} >>> M = Q.representation(QQ, spaces, maps) >>> S = Q.representation(QQ) >>> g = M.hom(S) >>> g.domain() is M True
- get_map(vertex)[source]¶
Return the homomorphism at the given vertex
vertex
.INPUT:
vertex
– integer; a vertex of the quiver
OUTPUT: the homomorphism associated to the given vertex
EXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: S = P/P.radical() sage: f = S.coerce_map_from(P) sage: f.get_map(1).is_bijective() True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> S = P/P.radical() >>> f = S.coerce_map_from(P) >>> f.get_map(Integer(1)).is_bijective() True
- get_matrix(vertex)[source]¶
Return the matrix of the homomorphism attached to vertex
vertex
.INPUT:
vertex
– integer; a vertex of the quiver
OUTPUT: the matrix representing the homomorphism associated to the given vertex
EXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: I = Q.I(QQ, 3) sage: M = I/I.radical() sage: f = M.coerce_map_from(I) sage: f.get_matrix(1) [1 0] [0 1]
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> I = Q.I(QQ, Integer(3)) >>> M = I/I.radical() >>> f = M.coerce_map_from(I) >>> f.get_matrix(Integer(1)) [1 0] [0 1]
- image()[source]¶
Return the image of
self
.OUTPUT:
QuiverRep
; the imageNote
To get the inclusion map of the image,
I
, into the codomain,C
, useC.coerce_map_from(I)
.EXAMPLES:
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^2, 3: QQ^1} sage: N = Q.representation(QQ, spaces2, {(2, 3, 'c'): [[1], [0]]}) sage: maps2 = {2:[[1, 0], [0, 0]], 3:1} sage: g = N.hom(maps2, M) sage: g.image().dimension_vector() (0, 1, 1)
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> spaces = {Integer(1): QQ**Integer(2), Integer(2): QQ**Integer(2), Integer(3):QQ**Integer(1)} >>> maps = {(Integer(1), Integer(2), 'a'): [[Integer(1), Integer(0)], [Integer(0), Integer(0)]], (Integer(1), Integer(2), 'b'): [[Integer(0), Integer(0)], [Integer(0), Integer(1)]], (Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(1)]]} >>> M = Q.representation(QQ, spaces, maps) >>> spaces2 = {Integer(2): QQ**Integer(2), Integer(3): QQ**Integer(1)} >>> N = Q.representation(QQ, spaces2, {(Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(0)]]}) >>> maps2 = {Integer(2):[[Integer(1), Integer(0)], [Integer(0), Integer(0)]], Integer(3):Integer(1)} >>> g = N.hom(maps2, M) >>> g.image().dimension_vector() (0, 1, 1)
- is_endomorphism()[source]¶
Test whether the homomorphism is an endomorphism.
OUTPUT: boolean;
True
if the domain equals the codomain,False
otherwiseEXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: f = P.hom({1: 1, 2: 1, 3: 1}, P) sage: f.is_endomorphism() True sage: S = P/P.radical() sage: g = S.coerce_map_from(P) sage: g.is_endomorphism() False
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> f = P.hom({Integer(1): Integer(1), Integer(2): Integer(1), Integer(3): Integer(1)}, P) >>> f.is_endomorphism() True >>> S = P/P.radical() >>> g = S.coerce_map_from(P) >>> g.is_endomorphism() False
- is_injective()[source]¶
Test whether the homomorphism is injective.
OUTPUT: boolean;
True
if the homomorphism is injective,False
otherwiseEXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: f = P.hom({1: 1, 2: 1, 3: 1}, P) sage: f.is_injective() True sage: g = P.hom(P) sage: g.is_injective() False
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> f = P.hom({Integer(1): Integer(1), Integer(2): Integer(1), Integer(3): Integer(1)}, P) >>> f.is_injective() True >>> g = P.hom(P) >>> g.is_injective() False
- is_isomorphism()[source]¶
Test whether the homomorphism is an isomorphism.
OUTPUT: boolean;
True
if the homomorphism is bijective,False
otherwiseEXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: f = P.hom({1: 1, 2: 1, 3: 1}, P) sage: f.is_isomorphism() True sage: g = P.hom(P) sage: g.is_isomorphism() False
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> f = P.hom({Integer(1): Integer(1), Integer(2): Integer(1), Integer(3): Integer(1)}, P) >>> f.is_isomorphism() True >>> g = P.hom(P) >>> g.is_isomorphism() False
- is_surjective()[source]¶
Test whether the homomorphism is surjective.
OUTPUT: boolean;
True
if the homomorphism is surjective,False
otherwiseEXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: f = P.hom({1: 1, 2: 1, 3: 1}, P) sage: f.is_surjective() True sage: g = P.hom(P) sage: g.is_surjective() False
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> f = P.hom({Integer(1): Integer(1), Integer(2): Integer(1), Integer(3): Integer(1)}, P) >>> f.is_surjective() True >>> g = P.hom(P) >>> g.is_surjective() False
- is_zero()[source]¶
Test whether the homomorphism is the zero homomorphism.
OUTPUT: boolean;
True
if the homomorphism is zero,False
otherwiseEXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: f = P.hom({1: 1, 2: 1, 3: 1}, P) sage: f.is_zero() False sage: g = P.hom(P) sage: g.is_zero() True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> f = P.hom({Integer(1): Integer(1), Integer(2): Integer(1), Integer(3): Integer(1)}, P) >>> f.is_zero() False >>> g = P.hom(P) >>> g.is_zero() True
- iscalar_mult(scalar)[source]¶
Multiply
self
byscalar
in place.EXAMPLES:
sage: Q = DiGraph({1:{2:['a','b']}}).path_semigroup() sage: M = Q.P(QQ, 1) sage: f = M.Hom(M).an_element() sage: x = M.an_element() sage: y = f(x) sage: f.iscalar_mult(6) sage: f(x) == 6*y True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a','b']}}).path_semigroup() >>> M = Q.P(QQ, Integer(1)) >>> f = M.Hom(M).an_element() >>> x = M.an_element() >>> y = f(x) >>> f.iscalar_mult(Integer(6)) >>> f(x) == Integer(6)*y True
- kernel()[source]¶
Return the kernel of
self
.OUTPUT:
QuiverRep
; the kernelNote
To get the inclusion map of the kernel,
K
, into the domain,D
, useD.coerce_map_from(K)
.EXAMPLES:
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^2, 3: QQ^1} sage: N = Q.representation(QQ, spaces2, {(2, 3, 'c'): [[1], [0]]}) sage: maps2 = {2:[[1, 0], [0, 0]], 3:1} sage: g = N.hom(maps2, M) sage: g.kernel().dimension_vector() (0, 1, 0)
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> spaces = {Integer(1): QQ**Integer(2), Integer(2): QQ**Integer(2), Integer(3):QQ**Integer(1)} >>> maps = {(Integer(1), Integer(2), 'a'): [[Integer(1), Integer(0)], [Integer(0), Integer(0)]], (Integer(1), Integer(2), 'b'): [[Integer(0), Integer(0)], [Integer(0), Integer(1)]], (Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(1)]]} >>> M = Q.representation(QQ, spaces, maps) >>> spaces2 = {Integer(2): QQ**Integer(2), Integer(3): QQ**Integer(1)} >>> N = Q.representation(QQ, spaces2, {(Integer(2), Integer(3), 'c'): [[Integer(1)], [Integer(0)]]}) >>> maps2 = {Integer(2):[[Integer(1), Integer(0)], [Integer(0), Integer(0)]], Integer(3):Integer(1)} >>> g = N.hom(maps2, M) >>> g.kernel().dimension_vector() (0, 1, 0)
- lift(x)[source]¶
Given an element \(x\) of the image, return an element of the domain that maps onto it under
self
.INPUT:
x
–QuiverRepElement
OUTPUT:
QuiverRepElement
EXAMPLES:
sage: Q = DiGraph({1:{2:['a','b']}, 2:{3:['c','d']}}).path_semigroup() sage: P = Q.P(QQ, 3) sage: S = P/P.radical() sage: proj = S.coerce_map_from(P) sage: x = S.an_element() sage: y = proj.lift(x) sage: proj(y) == x True sage: zero = S.hom(S, {}) sage: zero.lift(x) Traceback (most recent call last): ... ValueError: element is not in the image
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a','b']}, Integer(2):{Integer(3):['c','d']}}).path_semigroup() >>> P = Q.P(QQ, Integer(3)) >>> S = P/P.radical() >>> proj = S.coerce_map_from(P) >>> x = S.an_element() >>> y = proj.lift(x) >>> proj(y) == x True >>> zero = S.hom(S, {}) >>> zero.lift(x) Traceback (most recent call last): ... ValueError: element is not in the image
- linear_dual()[source]¶
Compute the linear dual \(Df : DN \to DM\) of
self
= \(f : M \to N\) where \(D(-) = Hom_k(-, k)\).OUTPUT:
QuiverRepHom
; the map \(Df : DN \to DM\)Note
If \(e\) is an edge of the quiver \(Q\) and \(g\) is an element of \(Hom_k(N, k)\) then we let \((ga)(m) = g(ma)\). This gives \(Hom_k(N, k)\) its structure as a module over the opposite quiver
Q.reverse()
. The map \(Hom_k(N, k) \to Hom_k(M, k)\) returned sends \(g\) to \(gf\).EXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: S = P/P.radical() sage: f = S.coerce_map_from(P)
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> S = P/P.radical() >>> f = S.coerce_map_from(P)
The dual of a surjective map is injective and vice versa:
sage: f.is_surjective() True sage: g = f.linear_dual() sage: g.is_injective() True
>>> from sage.all import * >>> f.is_surjective() True >>> g = f.linear_dual() >>> g.is_injective() True
The dual of a right module is a left module for the same quiver, Sage represents this as a right module for the opposite quiver:
sage: g.quiver().path_semigroup() is Q.reverse() True
>>> from sage.all import * >>> g.quiver().path_semigroup() is Q.reverse() True
The double dual of a map is the original representation:
sage: g.linear_dual() == f True
>>> from sage.all import * >>> g.linear_dual() == f True
- quiver()[source]¶
Return the quiver of the representations in the domain/codomain.
OUTPUT:
DiGraph
, the quiver of the representations in the domain and codomain
EXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: f = P.hom({1: 1, 2: 1, 3: 1}, P) sage: f.quiver() is Q.quiver() True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> f = P.hom({Integer(1): Integer(1), Integer(2): Integer(1), Integer(3): Integer(1)}, P) >>> f.quiver() is Q.quiver() True
- rank()[source]¶
Return the rank of the homomorphism
self
(as a \(k\)-linear map).OUTPUT: integer; the rank
EXAMPLES:
sage: Q = DiGraph({1:{2:['a', 'b']}, 2:{3:['c']}}).path_semigroup() sage: P = Q.P(QQ, 1) sage: S = P/P.radical() sage: f = S.coerce_map_from(P) sage: assert(f.rank() == 1)
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a', 'b']}, Integer(2):{Integer(3):['c']}}).path_semigroup() >>> P = Q.P(QQ, Integer(1)) >>> S = P/P.radical() >>> f = S.coerce_map_from(P) >>> assert(f.rank() == Integer(1))
- scalar_mult(scalar)[source]¶
Return the result of the scalar multiplication
scalar * self
, wherescalar
is an element of the base ring \(k\).EXAMPLES:
sage: Q = DiGraph({1:{2:['a','b']}}).path_semigroup() sage: M = Q.P(QQ, 1) sage: f = M.Hom(M).an_element() sage: x = M.an_element() sage: g = f.scalar_mult(6) sage: g(x) == 6*f(x) True
>>> from sage.all import * >>> Q = DiGraph({Integer(1):{Integer(2):['a','b']}}).path_semigroup() >>> M = Q.P(QQ, Integer(1)) >>> f = M.Hom(M).an_element() >>> x = M.an_element() >>> g = f.scalar_mult(Integer(6)) >>> g(x) == Integer(6)*f(x) True