Elements and maps of cohomology rings¶
AUTHORS:
Simon King <simon.king@uni-jena.de>
This module provides elements of modular cohomology rings of
groups of prime power order (COCH), of finite groups
that are not of prime power order (MODCOCH), induced
maps between cohomology rings (ChMap), and Yoneda
cochains for prime power groups (YCOCH). While Yoneda
cochains are just a tool for our implementation of Massey
products and Kraines’ restricted Massey powers, the other
three classes are vital for cohomology computations.
The class COCH provides elements of the mod-\(p\) cohomology of
a finite \(p\)-group \(P\). It is based on a minimal free resolutions of
\(F_pP\) provided by the class RESL.
The cup product is computed by standard constructions from homological
algebra.
In contrast, MODCOCH provides elements of the mod-\(p\)
cohomology of any finite group \(G\). The underlying data are stable
elements of the mod-\(p\) cohomology ring of a subgroup \(U\) of \(G\) whose
index is coprime to \(p\). This ring is represented in the Singular
interface. For instance, \(P\) may be a Sylow \(p\)-subgroup of \(G\). It is
allowed that \(G=U\) is a finite \(p\)-group, but in this case, the
cohomology ring of \(G\) must first be computed using COCH.
Group homomorphisms induce maps in cohomology, and this is provided by
ChMap. Induced homomorphisms are essential for the
computation of cohomology rings of finite groups that are not of prime
power order: The conditions defining stable elements are expressed in
terms of pairs of induced maps.
COCH, MODCOCH and ChMap can quite easily be
combined, which can be seen in the following examples.
EXAMPLES:
We define two groups (one of them is of prime power order) and compute their cohomology rings.
sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace
sage: S = libgap.SymmetricGroup(6)
sage: D = libgap.DihedralGroup(8)
sage: HS = CohomologyRing(S, prime=2, GroupName='Sym6', from_scratch=True)
sage: HS.make()
sage: HD = CohomologyRing(D, GroupName='D_8', from_scratch=True)
sage: HD.make()
We do some computations with cohomology elements, testing relations in
HS and HD:
sage: cD1 = HD.1+HD.2*HD.3; cD1
c_2_2+(b_1_0)*(b_1_1): 2-Cocycle in H^*(D_8; GF(2))
sage: cD2 = HD.1+HD.3^2; cD2
c_2_2+(b_1_1)**2: 2-Cocycle in H^*(D_8; GF(2))
sage: cD1 == cD2
True
sage: HD.rels()
['b_1_1^2+b_1_0*b_1_1']
sage: cS1 = HS.1*HS.2+HS.3; cS1
(c_2_1)*(c_1_0)+(b_3_2): 3-Cocycle in H^*(Sym6; GF(2))
sage: cS2 = HS.1*HS.2+HS.4; cS2
(c_2_1)*(c_1_0)+(b_3_3): 3-Cocycle in H^*(Sym6; GF(2))
sage: cS1*cS2 == HS.3*HS.4 + HS.1*HS.2*(HS.1*HS.2+HS.3+HS.4)
True
sage: HS.rels()
['b_3_2*b_3_3']
We define an embedding of D in S and compute the induced
map from HS to HD:
sage: emb = D.GroupHomomorphismByImages(S,D.GeneratorsOfGroup(),libgap.eval('[ (2,4), (1,2,3,4), (1,3)(2,4) ]'))
sage: resS_D = HS.hom(emb,HD)
sage: [resS_D(g).as_polynomial() for g in HS.gens()[1:]]
['b_1_0*b_1_1+b_1_0^2+c_2_2',
'b_1_1+b_1_0',
'c_2_2*b_1_1+c_2_2*b_1_0',
'b_1_0^2*b_1_1+c_2_2*b_1_1']
Note that the generators of HD are COCH, while those of
HS are MODCOCH. But the image of the induced map is
formed by MODCOCH:
sage: type(HD.1)
<type 'pGroupCohomology.cochain.COCH'>
sage: type(HS.1)
<class 'pGroupCohomology.cochain.MODCOCH'>
sage: type(resS_D(HS.1))
<class 'pGroupCohomology.cochain.MODCOCH'>
It is possible to mix both classes in arithmetic expressions:
sage: resS_D(HS.2) == HD.2+HD.3
True
sage: resS_D(HS.1)*resS_D(HS.2) == resS_D(HS.1)*HD.2+resS_D(HS.1)*HD.3
True
-
class
pGroupCohomology.cochain.COCH¶ COCH extension class representing elements of cohomology rings.
INPUT:
H– a cohomology ring (COHO)n– the degree of the cochain (integer)s– name of the \(n\)-cochain (string)M– data describing the cochain. Eithera \((1 \times d)\)
Matrix_gfpn_densematrix, ora \(d\)-tuple of integers
where \(d\) is the projective rank of the \(n\)-th term of the resolution that underlies
Hydeg(optional, defaultNone) – y-degree of the cochainrdeg(optional, defaultNone) – r-degree of the cochain
OUTPUT:
A degree \(n\) element of
Hof name s.NOTE:
Usually, a cochain will be created by doing algebra with the generators of a cohomology ring.
In our application (see
pGroupCohomology),rdeg==1if and only if the cochain is a Duflot regular generator of a cohomology ring;ydeg==1if and only if the cochain is a generator of a cohomology ring that is neither nilpotent nor Duflot regular.Every cochain is provided with a name. When a cochain is the result of a computation then its name will by default describe its construction. We think that this is a very useful feature.
EXAMPLES:
First, we show how one would usually create a cochain:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: C = H.2 sage: D = H.3 sage: C b_1_0: 1-Cocycle in H^*(D8; GF(2)) sage: D b_1_1: 1-Cocycle in H^*(D8; GF(2)) sage: C+D b_1_0+b_1_1: 1-Cocycle in H^*(D8; GF(2)) sage: C*D (b_1_0)*(b_1_1): 2-Cocycle in H^*(D8; GF(2)) sage: print(C^3) 3-Cocycle in H^*(D8; GF(2)), represented by [1 0 0 0] sage: print(D^3) 3-Cocycle in H^*(D8; GF(2)), represented by [0 1 0 0]
Next, we show a non-commutative example. Just for documentation, we create the cochains more directly:
sage: H = CohomologyRing(27,3, from_scratch=True) sage: print(H.resolution()) Resolution: 0 <- GF(3) <- GF(3)[E27]
Incidentally, we know that the projective rank of the second term of the resolution is four. So, we can define:
sage: from pGroupCohomology.cochain import COCH sage: C = COCH(H,2,'first',(1,0,1,2))
Now, the resolution is computed out to the second term, and the cochain
Chas the name ‘first’:sage: print(H.resolution()) Resolution: 0 <- GF(3) <- GF(3)[E27] <- rank 2 <- rank 4 sage: C first: 2-Cocycle in H^*(E27; GF(3)) sage: print(C) 2-Cocycle in H^*(E27; GF(3)), represented by [1 0 1 2]
Using
Matrix_gfpn_densematrices, we provide a slightly different way to create a cochain. The matrix must be immutable:sage: from sage.matrix.matrix_gfpn_dense import Matrix_gfpn_dense as MTX sage: D = COCH(H,2,'second', MTX(MatrixSpace(GF(3),1,4, implementation=MTX), [[0,1,0,1]], mutable=False))
Now, we can add or subtract the cochains:
sage: C+D first+second: 2-Cocycle in H^*(E27; GF(3)) sage: print(C+D) 2-Cocycle in H^*(E27; GF(3)), represented by [1 1 1 0] sage: print(C-D) 2-Cocycle in H^*(E27; GF(3)), represented by [1 2 1 1]
Scalar multiplication works as well:
sage: 2*C 2*(first): 2-Cocycle in H^*(E27; GF(3)) sage: print(C*2) 2-Cocycle in H^*(E27; GF(3)), represented by [2 0 2 1]
But certainly, in cohomology computations the cup-product is the most interesting:
sage: C*D (first)*(second): 4-Cocycle in H^*(E27; GF(3)) sage: print(H.resolution()) Resolution: 0 <- GF(3) <- GF(3)[E27] <- rank 2 <- rank 4 <- rank 6 <- rank 7 sage: E = C^2 sage: E = C^2+D*C*2 sage: E (first)**2+((second)*(first))*2: 4-Cocycle in H^*(E27; GF(3)) sage: print(E) 4-Cocycle in H^*(E27; GF(3)), represented by [2 2 0 1 0 0 2]
Since \(p>2\) in this example, the cohomology ring is non-commutative:
sage: X = COCH(H,3,'X',(1,1,1,0,0,0)) sage: Y = COCH(H,3,'Y',(0,0,0,1,1,1)) sage: print(X*Y) 6-Cocycle in H^*(E27; GF(3)), represented by [2 1 1 0 0 0 0 0 0] sage: print(Y*X) 6-Cocycle in H^*(E27; GF(3)), represented by [1 2 2 0 0 0 0 0 0]
The name (which by default describes the construction of the cochain) can be overwritten:
sage: E.name() '(first)**2+((second)*(first))*2' sage: E.setname('foo') sage: E foo: 4-Cocycle in H^*(E27; GF(3))
-
MTX(*args, **kwds)¶ COCH.MTX(self) -> Matrix_gfpn_dense
Return the
Matrix_gfpn_densematrix by whichselfis defined.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: C = H.2*H.1 sage: print(C.MTX()) [0 0 1 0]
-
as_polynomial()¶ Return a string that represents
selfas a polynomial in its parent.NOTE:
The name of
selfwill be modified inplaceEXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: c = H.1*H.2+H.3^3 sage: c (c_2_2)*(b_1_0)+(b_1_1)**3: 3-Cocycle in H^*(D8; GF(2)) sage: c.setname('foo') sage: c foo: 3-Cocycle in H^*(D8; GF(2)) sage: c.as_polynomial() 'b_1_1^3+c_2_2*b_1_0' sage: c b_1_1^3+c_2_2*b_1_0: 3-Cocycle in H^*(D8; GF(2))
-
deg()¶ Return the degree of
self.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: C=H.2*H.1 sage: C.deg() 3
-
is_nilpotent()¶ Tells whether this cocycle is nilpotent.
An elemenet of a mod-\(p\) cohomology ring of a finite group is nilpotent if and only if the restrictions to all maximal \(p\)-elementary abelian subgroups are.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace
An example in even characteristic:
sage: H = CohomologyRing(64,242) sage: H.make() sage: H.nil_radical() b_1_0*b_1_2+b_1_0^2, b_1_0*b_1_3+b_1_0*b_1_1+b_1_0^2 sage: H('b_1_0*b_1_2+b_1_0^2').is_nilpotent() True sage: H('b_1_0*b_1_3+b_1_0*b_1_2').is_nilpotent() False sage: H('b_1_0*b_1_3+b_1_0*b_1_1+b_1_0^2').is_nilpotent() True
An example in odd characteristic:
sage: H = CohomologyRing(81,13) sage: H.make() sage: H.nil_radical() a_1_0, a_1_1, a_1_2, a_3_6, a_5_10 sage: c = H('a_1_2*a_5_10') sage: bool(c) True sage: c.is_nilpotent() True sage: c.nilpotency_degree() 2
Two abelian examples, that gave a wrong answer with previous versions of the spkg:
sage: H = CohomologyRing(3^4,gap.NumberSmallGroups(3^4)) sage: H.make() sage: (H.5*H.6+H.7*H.8).is_nilpotent() True sage: (H.5*H.6+H.7*H.8).nilpotency_degree() 3 sage: H = CohomologyRing(16,2) sage: H.make() sage: H.3.is_nilpotent() True sage: H.3.nilpotency_degree() 2
-
label()¶ COCH.name(self)
Return the name of
self.NOTE:
When a
COCHinstance is created by invoking the init method, a name must be given. When furtherCOCHinstances are created by arithmetic operations, the name of the result describes its construction.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: C=H.2*H.1 sage: print(C.name()) (b_1_0)*(c_2_2) sage: H(C.name()) == C True
Note that there is no automatic simplification when the result represents the trivial cochain:
sage: (C*2).name() '((b_1_0)*(c_2_2))*0' sage: print(C*2) 3-Cocycle in H^*(D8; GF(2)), represented by [0 0 0 0]
-
massey_power(i=1)¶ Return the \(p^i\)-fold restricted Massey product of
self, orNoneif it does not exist.INPUT:
i(optional integer, default 1)OUTPUT:
A cochain with the same parent as
self, named"<%s; %d>"%(self.name(),i).NOTE:
We refer to the \(p^i\)-fold restricted Massey product as the \(i\)-th restricted Massey power.
According to [Kraines], for \(p > 2\), the 1st restricted Massey power of a cocycle \(C\) of odd degree in a cohomology ring with coefficients in \(\mathbb F_p\) is minus the Bockstein of the Steenrod \(p\)-th power, \(-\beta P^1(C)\).
EXAMPLES:
First, we study an example in the cohomology ring of an elementary abelian \(p\)-group. The cohomology ring is simple enough to allow for an explicit computation of Bockstein and Steenrod powers.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(9,2) sage: H.make() sage: H.gens() [1, c_2_1: 2-Cocycle in H^*(SmallGroup(9,2); GF(3)), c_2_2: 2-Cocycle in H^*(SmallGroup(9,2); GF(3)), a_1_0: 1-Cocycle in H^*(SmallGroup(9,2); GF(3)), a_1_1: 1-Cocycle in H^*(SmallGroup(9,2); GF(3))]
We compute the 1st restricted Massey powers of the degree one generators. Of course, the degree two generators have no Massey power, as they are not nilpotent.
sage: print(H.1.massey_power()) None sage: H.element_as_polynomial(H.3.massey_power()) -c_2_1: 2-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: H.element_as_polynomial(H.4.massey_power()) -c_2_2: 2-Cocycle in H^*(SmallGroup(9,2); GF(3))
Since indeed \(c_{2,1}\) and \(c_{2,2}\) are the Bocksteins of \(a_{1,0}\) and \(a_{1,1}\), Kraines’ formula is verified in degree one. But it also holds in degree three, as we are now going to show.
We consider \(C = a_{1,0}c_{2,1}\). By Cartan formula and since \(P^0\) is the identity, we have \(P^1(C) = P^1(a_{1,0})c_{2,1} + a_{1,0}P(c_{2,1})\). Since \(P^1\) vanishes in degree one and acts as the \(p\)-th power in degree two, we get \(P^1(C) = a_{1,0}c_{2,1}^3\). Applying the Bockstein operator \(\beta\), we get \(\beta P^1(C) = c_{2,1}^4\), since \(\beta(c_{2,1}) = \beta^2(c_{1,0}) = 0\) and since \(\beta(xy)=\beta(x)y + (-1)^{\deg x}x\beta(y)\). Hence, according to Kraines, we should get \(\langle a_{1,0}c_{2,1}; 1\rangle = - c_{2,1}^4\). And indeed:
sage: (H.1*H.3).massey_power() <(c_2_1)*(a_1_0); 1>: 8-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: H.element_as_polynomial(_) -c_2_1^4: 8-Cocycle in H^*(SmallGroup(9,2); GF(3))
We now consider a more advanced example, namely the extraspecial 3-group of order 27 and exponent 3:
sage: H = CohomologyRing(27,3) sage: H.make()
We compute generators for the nil radical of
Hand compute the 3-fold Massey product for each generator that is of degree not more than 5:sage: singular(H).set_ring() sage: N = [H(str(X)) for X in H.nil_radical()] sage: MP = [X.massey_power() for X in N] sage: MP [<a_1_0; 1>: 2-Cocycle in H^*(E27; GF(3)), <a_1_1; 1>: 2-Cocycle in H^*(E27; GF(3)), <a_3_4; 1>: 8-Cocycle in H^*(E27; GF(3)), <a_3_5; 1>: 8-Cocycle in H^*(E27; GF(3))]
After expressing them as polynomials in the cohomology generators, we obtain
sage: [H.element_as_polynomial(X) for X in MP] [-b_2_0: 2-Cocycle in H^*(E27; GF(3)), -b_2_3: 2-Cocycle in H^*(E27; GF(3)), b_2_0^2*a_1_1*a_3_5+b_2_0^2*a_1_0*a_3_4+b_2_0*c_6_8: 8-Cocycle in H^*(E27; GF(3)), -b_2_0^3*b_2_2-b_2_0^2*a_1_1*a_3_5-b_2_0^2*a_1_0*a_3_5+b_2_3*c_6_8+b_2_0*c_6_8: 8-Cocycle in H^*(E27; GF(3))]
Hence, particularly interesting seems to be the first restricted Massey power of the degree three generators of
H. We take the restriction maps to the four classes of maximal elementary abelian subgroups, which are all of order 9:sage: r1 = H.restriction_maps()[2][1] sage: r1 Induced homomorphism of degree 0 from H^*(E27; GF(3)) to H^*(SmallGroup(9,2); GF(3)) sage: r2 = H.restriction_maps()[3][1] sage: r3 = H.restriction_maps()[4][1] sage: r4 = H.restriction_maps()[5][1] sage: C = H.8 sage: C a_3_4: 3-Cocycle in H^*(E27; GF(3)) sage: U = r1.codomain() sage: U.element_as_polynomial(r1(C)) 0: 3-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: U.element_as_polynomial(r2(C)) -c_2_2*a_1_0+c_2_1*a_1_1: 3-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: U.element_as_polynomial(r3(C)) -c_2_2*a_1_0+c_2_1*a_1_1: 3-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: U.element_as_polynomial(r4(C)) c_2_2*a_1_1-c_2_2*a_1_0+c_2_1*a_1_1: 3-Cocycle in H^*(SmallGroup(9,2); GF(3))
Hence, after computing Bockstein and Steenrod power in
Uas above, and since Steenrod power and Bockstein commute with restriction maps, the theorem of Kraines tells us that \(\langle C; 1\rangle\) should restrict to \(0\), \(c_{2,1}c_{2,2}^3 - c_{2,1}^3c_{2,2}\), \(c_{2,1}c_{2,2}^3 - c_{2,1}^3c_{2,2}\), and \(-c_{2,2}^4 - c_{2,1}c_{2,2}^3 + c_{2,1}^3c_{2,2}\). It does:sage: CP = C.massey_power() sage: U.element_as_polynomial(r1(CP)) 0: 8-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: U.element_as_polynomial(r2(CP)) c_2_1*c_2_2^3-c_2_1^3*c_2_2: 8-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: U.element_as_polynomial(r3(CP)) c_2_1*c_2_2^3-c_2_1^3*c_2_2: 8-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: U.element_as_polynomial(r4(CP)) -c_2_2^4+c_2_1*c_2_2^3-c_2_1^3*c_2_2: 8-Cocycle in H^*(SmallGroup(9,2); GF(3))
It is known that for this group, a cocycle is uniquely determined by its restrictions to the maximal elementary abelian subgroups. Hence, we have verified the computation of the first restricted Massey power of
C.We don’t know of general results in the case of even characteristic. However, even in this case, we find that cocycles of higher degree can be produced by restricted Massey powers, for example for the cohomology ring of \(C_4\times C_4\):
sage: H = CohomologyRing(16,2) sage: H.make() sage: x,a,b,c,d = H.gens() sage: c c_1_0: 1-Cocycle in H^*(SmallGroup(16,2); GF(2)) sage: d c_1_1: 1-Cocycle in H^*(SmallGroup(16,2); GF(2)) sage: H.element_as_polynomial(c.massey_power()) 0: 2-Cocycle in H^*(SmallGroup(16,2); GF(2)) sage: H.element_as_polynomial(d.massey_power()) 0: 2-Cocycle in H^*(SmallGroup(16,2); GF(2)) sage: H.element_as_polynomial(c.massey_power(2)) c_2_1: 2-Cocycle in H^*(SmallGroup(16,2); GF(2)) sage: H.element_as_polynomial(d.massey_power(2)) c_2_2: 2-Cocycle in H^*(SmallGroup(16,2); GF(2))
We verify that the result is consistent with the set-valued non-restricted Massey products:
sage: sorted(list(H.massey_products(c,c,c,c))) [c_2_1: 2-Cocycle in H^*(SmallGroup(16,2); GF(2)), c_2_1+c_1_0*c_1_1: 2-Cocycle in H^*(SmallGroup(16,2); GF(2))] sage: sorted(list(H.massey_products(d,d,d,d))) [c_2_2: 2-Cocycle in H^*(SmallGroup(16,2); GF(2)), c_2_2+c_1_0*c_1_1: 2-Cocycle in H^*(SmallGroup(16,2); GF(2))]
-
name()¶ Return the name of
self.NOTE:
When a
COCHinstance is created by invoking the init method, a name must be given. When furtherCOCHinstances are created by arithmetic operations, the name of the result describes its construction.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: C=H.2*H.1 sage: print(C.name()) (b_1_0)*(c_2_2) sage: H(C.name()) == C True
Note that there is no automatic simplification when the result represents the trivial cochain:
sage: (C*2).name() '((b_1_0)*(c_2_2))*0' sage: print(C*2) 3-Cocycle in H^*(D8; GF(2)), represented by [0 0 0 0]
-
nilpotency_degree()¶ The smallest exponent by which this cocycle becomes zero.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(64,18) sage: H.make() sage: H.nil_radical() a_1_0, a_1_1, a_2_0, a_2_1, a_5_5, a_5_8, a_6_7, a_6_10 sage: c = H('a_5_5') sage: c.nilpotency_degree() 4
The following takes quite long, as it is needed to compute the resolution of this cohomology ring out to degree 20. However, it confirms the stated nilpotency degree:
sage: bool(c^2), bool(c^3), bool(c^4) (True, True, False)
If the cocycle is not nilpotent, infinity is returned:
sage: c = H('b_2_3') sage: c.is_nilpotent() False sage: c.nilpotency_degree() +Infinity
Of course, a zero cochain has nilpotency degree one:
sage: (c*0).nilpotency_degree() 1
-
normalize()¶ Scale
selfinplace so that its leading coefficient is 1 (if non-zero).OUTPUT:
Trueif self is a null-cochain, andNoneotherwiseEXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(27,3) sage: H.make() sage: C=2*H.1+H.2 sage: print(C) 2-Cocycle in H^*(E27; GF(3)), represented by [2 1 0 0] sage: C.normalize() sage: print(C) 2-Cocycle in H^*(E27; GF(3)), represented by [1 2 0 0] sage: C (2*(b_2_0)+b_2_1)/2: 2-Cocycle in H^*(E27; GF(3)) sage: D = 0*H.2 sage: D.normalize() True sage: D 0*(b_2_1): 2-Cocycle in H^*(E27; GF(3))
-
rdeg()¶ Return the \(r\)-degree of
self.NOTE:
The r-degree plays an important role in the computation of cohomology rings. A generator of a cohomology ring has
rdeg==1if and only if it is a Duflot regular generator, which means that its restriction to the greatest central elementary abelian subgroup is not nilpotent.EXAMPLES:
The example produces files. For safety reasons, we choose files in a temporary directory; it will be removed as soon as Sage is quit:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: H.1.rdeg() 1 sage: H.2.rdeg() 0 sage: H.3.rdeg() 0
-
resolution()¶ Return the underlying resolution.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3, from_scratch=True) sage: from pGroupCohomology.cochain import COCH sage: C=COCH(H,2,'foo',(1,1,0))
Note that the needed terms of the resolution are automatically computed:
sage: print(C.resolution()) Resolution: 0 <- GF(2) <- GF(2)[D8] <- rank 2 <- rank 3 sage: C.resolution() is H.resolution() True
-
right_multiplication()¶ Return the cohomology ring endomorphism given by right-multiplication with
self.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: print(H) Cohomology ring of Dihedral group of order 8 with coefficients in GF(2) <BLANKLINE> Computation complete Minimal list of generators: [c_2_2: 2-Cocycle in H^*(D8; GF(2)), b_1_0: 1-Cocycle in H^*(D8; GF(2)), b_1_1: 1-Cocycle in H^*(D8; GF(2))] Minimal list of algebraic relations: [b_1_0*b_1_1] sage: x,a,b,c = H.gens() sage: B = b.right_multiplication() sage: C = c.right_multiplication() sage: B(a) == a*b True sage: A = a.right_multiplication() sage: BA = A(B) sage: BA(a) == a*a*b True sage: r = H.restriction_maps()[2][1] sage: rB = r(B) sage: r(a)*r(b) == rB(a) True
-
set_latex_name(s)¶ Declare how self should be typeset in LaTeX.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: latex(H.2) b_{1,0} sage: (H.2).set_latex_name('H_2') sage: latex(H.2) H_2
-
setname(s, is_polyrep=False)¶ Set the name of
self.INPUT:
s – a string providing the new name
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: C=H.2*H.1 sage: C (b_1_0)*(c_2_2): 3-Cocycle in H^*(D8; GF(2)) sage: C.setname('foo') sage: C foo: 3-Cocycle in H^*(D8; GF(2))
-
ydeg()¶ Return the \(y\)-degree of
self.NOTE:
The y-degree plays an important role in the computation of cohomology rings. A generator of a cohomology ring has
ydeg==1if and only if it is nilpotent.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(16,3) sage: H.make() sage: print(H) Cohomology ring of Small Group number 3 of order 16 with coefficients in GF(2) <BLANKLINE> Computation complete Minimal list of generators: [b_2_1: 2-Cocycle in H^*(SmallGroup(16,3); GF(2)), c_2_2: 2-Cocycle in H^*(SmallGroup(16,3); GF(2)), c_2_3: 2-Cocycle in H^*(SmallGroup(16,3); GF(2)), a_1_0: 1-Cocycle in H^*(SmallGroup(16,3); GF(2)), b_1_1: 1-Cocycle in H^*(SmallGroup(16,3); GF(2))] Minimal list of algebraic relations: [a_1_0^2, a_1_0*b_1_1, b_2_1*a_1_0, b_2_1^2+c_2_2*b_1_1^2] sage: H.1.rdeg(),H.1.ydeg() (0, 0) sage: H.2.rdeg(),H.2.ydeg() (1, 0) sage: H.4.rdeg(),H.4.ydeg() (0, 1)
-
yoneda_cocycle()¶ Express
selfas a Yoneda cocycle.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: Y21 = H.2.yoneda_cocycle()*H.1.yoneda_cocycle() sage: X21 = (H.2*H.1).yoneda_cocycle() sage: Y21[0] == X21[0] True sage: Y21[1] == X21[1] True sage: Y21[2] == X21[2] True
-
class
pGroupCohomology.cochain.COCH_unpickle_class¶ Unpickling a cochain.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3, from_scratch=True) sage: H.make() sage: C=H.2 sage: type(C) <type 'pGroupCohomology.cochain.COCH'> sage: D = loads(dumps(C)) #indirect doctest sage: print(C) 1-Cocycle in H^*(D8; GF(2)), represented by [1 0] rdeg = 0 ydeg = 0 sage: print(D) 1-Cocycle in H^*(D8; GF(2)), represented by [1 0] rdeg = 0 ydeg = 0
CandDare different objects, but of course their parents are the same, and the cochains are equal:sage: D is C False sage: D.parent() is C.parent() True sage: D == C True
-
class
pGroupCohomology.cochain.ChMap¶ Extension class representing induced homomorphisms of cohomology rings.
EXAMPLES:
Usually, an induced homomorphism is created by defining two groups and a homomorphism between them, computing the cohomology rings of the groups, and then invoking the
hom`()method of cohomology rings.We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make()
In order to obtain reproducible doc tests, we switch to permutation groups that are, from the perspective of our programs, equivalent to
G1andG2, and provide an explicit group isomorphism:sage: phi = libgap.eval('GroupHomomorphismByImages( Group( [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ] ), Group( [ (1,5)(2,6)(3,8)(4,7), (1,3,2,4)(5,7,6,8) ] ), [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ], [ (1,7)(2,8)(3,5)(4,6), (1,6)(2,5)(3,7)(4,8) ] )') sage: H1.group()==phi.Source() True sage: H2.group().canonicalIsomorphism(phi.Range()) [ (1,2)(3,8)(4,6)(5,7), (1,3,4,7)(2,5,6,8) ] -> [ (1,5)(2,6)(3,8)(4,7), (1,3,2,4)(5,7,6,8) ] sage: phi.IsInjective() true sage: phi.IsSurjective() true
After ensuring that
phiis printed nicely, we obtain the induced map:sage: phi.SetName('phi') sage: phi_star = H2.hom(phi,H1) #indirect doctest sage: phi_star phi^* sage: phi_star.domain() H^*(DihedralGroup(8); GF(2)) sage: phi_star.codomain() H^*(D8; GF(2)) sage: print([H1.element_as_polynomial(phi_star(X)) for X in H2.gens()]) [1: 0-Cocycle in H^*(D8; GF(2)), b_1_0^2+c_2_2: 2-Cocycle in H^*(D8; GF(2)), b_1_1+b_1_0: 1-Cocycle in H^*(D8; GF(2)), b_1_0: 1-Cocycle in H^*(D8; GF(2))]
Similarly, we get the induced map of the inverse map:
sage: Src = phi.Source() sage: Rng = phi.Range() sage: Gens = Rng.GeneratorsOfGroup() sage: phi_inv = Rng.GroupHomomorphismByImages(Src, Gens, [phi.PreImagesRepresentative(g) for g in Gens]) sage: phi_star_inv = H1.hom(phi_inv,H2) sage: print([H2.element_as_polynomial(phi_star_inv(X)) for X in H1.gens()]) [1: 0-Cocycle in H^*(DihedralGroup(8); GF(2)), b_1_0*b_1_1+c_2_2: 2-Cocycle in H^*(DihedralGroup(8); GF(2)), b_1_1: 1-Cocycle in H^*(DihedralGroup(8); GF(2)), b_1_1+b_1_0: 1-Cocycle in H^*(DihedralGroup(8); GF(2))]
One can compose induced maps by multiplication respectively by applying one map to the other. Here, we test that the composition of the induced map and its inverse is the identity:
sage: [X == phi_star_inv(phi_star(X)) == (phi_star_inv*phi_star)(X) == phi_star_inv(phi_star)(X) for X in H2.gens()] [True, True, True, True] sage: [X == phi_star(phi_star_inv(X)) == (phi_star*phi_star_inv)(X) == phi_star(phi_star_inv)(X) for X in H1.gens()] [True, True, True, True]
It is possible to convert an induced homomorphism into a map of quotient rings in the Singular interface. This allows for working with cohomology ring elements of very high degrees. However, it is always needed to take care of the
baseringin Singular:sage: S_phi_star = singular(phi_star) sage: singular(H2).set_ring() sage: I = singular.ideal(['c_2_2^50','b_1_0^50','b_1_1^50']) sage: singular(H1).set_ring() sage: imI = S_phi_star(I)
Note that Singular does pfte not do automatic reduction in quotient rings. So, eventually we do the reductions explicitly, in two ways, with the same result:
sage: imI.reduce(singular('ideal(0)')) b_1_0^100+c_2_2^2*b_1_0^96+c_2_2^16*b_1_0^68+c_2_2^18*b_1_0^64+c_2_2^32*b_1_0^36+c_2_2^34*b_1_0^32+c_2_2^48*b_1_0^4+c_2_2^50, b_1_1^50+b_1_0^50, b_1_0^50 sage: singular(H2).set_ring() sage: I_red = I.reduce(singular('ideal(0)')) sage: singular(H1).set_ring() sage: S_phi_star(I_red).reduce(singular('ideal(0)')) b_1_0^100+c_2_2^2*b_1_0^96+c_2_2^16*b_1_0^68+c_2_2^18*b_1_0^64+c_2_2^32*b_1_0^36+c_2_2^34*b_1_0^32+c_2_2^48*b_1_0^4+c_2_2^50, b_1_1^50+b_1_0^50, b_1_0^50
-
G_map()¶ Return the underlying homomorphism of group algebras (given by a
Matrix_gfpn_densematrix).EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: G2 = libgap.DihedralGroup(8) sage: H1 = CohomologyRing(8,3) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H1.make() sage: H2.make()
In order to obtain reproducible doc tests, we switch to permutation groups that are, from the perspective of our programs, equivalent to
G1andG2, and provide an explicit group isomorphism:sage: phi = libgap.eval('GroupHomomorphismByImages( Group( [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ] ), Group( [ (1,5)(2,6)(3,8)(4,7), (1,3,2,4)(5,7,6,8) ] ), [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ], [ (1,7)(2,8)(3,5)(4,6), (1,6)(2,5)(3,7)(4,8) ] )') sage: H1.group()==phi.Source() True sage: H2.group().canonicalIsomorphism(phi.Range()) != libgap.eval('fail') True sage: phi.IsInjective() true sage: phi.IsSurjective() true sage: phi_star = H2.hom(phi,H1) sage: print(phi_star.G_map()) [1 0 0 0 0 0 0 0] [0 1 1 1 1 1 1 1] [0 1 0 0 1 1 0 0] [0 0 0 1 0 0 1 1] [0 0 0 1 1 0 0 1] [0 0 0 0 0 1 1 0] [0 0 0 0 0 1 0 1] [0 0 0 0 0 0 0 1]
-
apply_to_chain(d, C)¶ Apply the underlying chain map of
selfto a \(d\)-chain.INPUT:
d, the degree of the chainC, a \((r\times |G|)\)Matrix_gfpn_densematrix, where \(r\) is the rank of the \(d\)-th term of the resolution, and \(|G|\) is the group order.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: from sage.matrix.matrix_gfpn_dense import Matrix_gfpn_dense as MTX sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: f = H.2.right_multiplication() sage: print(f.apply_to_chain(1, MTX(MatrixSpace(GF(2),2,8, implementation=MTX), [[0,1,0,1,0,1,0,1],[1,0,1,0,1,0,1,0]]))) [0 1 0 1 0 1 0 1]
-
deg()¶ Return the degree of
self.NOTE:
An induced homomorphism always is of degree zero. We provide this method since
ChMapin principle also works for more general maps so that the image has a different degree from the source.EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = G1.IsomorphismGroups(G2) sage: phi_star = H2.hom(phi,H1) sage: phi_star.deg() 0
-
exportData(f)¶ Store data describing the induced map into files.
INPUT:
f- a string, providing the path and the beginning of the name of the files into which the terms ofselfshall be savedOUTPUT:
The matrix
self[i]is saved to the filef+repr(i).NOTE:
This method is internally used, in order to save memory by disposing of data that are currently not needed. So, a user would normally not directly invoke the method.
TESTS:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H1 = CohomologyRing(8,3) sage: H1.make() sage: G = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = libgap.eval('GroupHomomorphismByImages( Group( [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ] ), Group( [ (1,5)(2,6)(3,8)(4,7), (1,3,2,4)(5,7,6,8) ] ), [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ], [ (1,7)(2,8)(3,5)(4,6), (1,6)(2,5)(3,7)(4,8) ] )') sage: phi_star = H2.hom(phi,H1) sage: print(phi_star(H2.1)) 2-Cocycle in H^*(D8; GF(2)), represented by [1 0 1] sage: print(phi_star.__getitem_name__(1)) [1 0 0 0 0 0 0 0] [1 1 1 1 1 1 0 0] [1 0 0 0 0 0 0 0] [0 0 1 1 0 0 0 0] sage: f = tmp_dir() sage: phi_star.exportData(f) sage: phi_star.__getitem_name__(1) == f+'1' True
-
kernel()¶ Compute the kernel.
TEST:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(81,8) sage: H.make() sage: H.restriction_maps()[2][1].kernel() a_1_1, a_2_1, a_2_2, a_3_2, b_4_2-a_4_1, a_5_3+a_5_2, b_6_3-a_1_0*a_5_2, a_7_5+b_2_0*a_5_2+c_6_4*a_1_0 sage: H.restriction_maps()[2][1]( H('b_6_3-a_1_0*a_5_2') ) (b_6_3-((a_1_0)*(a_5_2)))_: 6-Cocycle in H^*(SmallGroup(9,2); GF(3)) sage: _.MTX() [0 0 0 0 0 0 0]
-
knownDeg()¶ Return the degree out to which
selfwas constructed.EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make()
In order to obtain reproducible doc tests, we switch to permutation groups that are, from the perspective of our programs, equivalent to
G1andG2, and provide an explicit group isomorphism:sage: phi = libgap.eval('GroupHomomorphismByImages( Group( [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ] ), Group( [ (1,5)(2,6)(3,8)(4,7), (1,3,2,4)(5,7,6,8) ] ), [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ], [ (1,7)(2,8)(3,5)(4,6), (1,6)(2,5)(3,7)(4,8) ] )') sage: H1.group()==phi.Source() True sage: H2.group().canonicalIsomorphism(phi.Range()) != libgap.eval('fail') True sage: phi.IsInjective() true sage: phi.IsSurjective() true sage: phi_star = H2.hom(phi,H1) sage: phi_star.knownDeg() 0 sage: print(phi_star(H2.1)) 2-Cocycle in H^*(D8; GF(2)), represented by [1 0 1] sage: phi_star.knownDeg() 2
-
label()¶ Provide a short description of this chain map, using a name when available.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H1 = CohomologyRing(8,3) sage: H1.make() sage: G = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = libgap.eval('GroupHomomorphismByImages( Group( [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ] ), Group( [ (1,5)(2,6)(3,8)(4,7), (1,3,2,4)(5,7,6,8) ] ), [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ], [ (1,7)(2,8)(3,5)(4,6), (1,6)(2,5)(3,7)(4,8) ] )') sage: phi_star = H2.hom(phi,H1) sage: phi_star.label() 'Map H^*(DihedralGroup_8_; GF(2)) -> H^*(8gp3; GF(2))' sage: phi_star.set_name('phi^*') sage: phi_star.label() 'phi^*'
-
lift()¶ Compute the next unknown term of
self.EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make()
In order to obtain reproducible doc tests, we switch to permutation groups that are, from the perspective of our programs, equivalent to
G1andG2, and provide an explicit group isomorphism:sage: phi = libgap.eval('GroupHomomorphismByImages( Group( [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ] ), Group( [ (1,5)(2,6)(3,8)(4,7), (1,3,2,4)(5,7,6,8) ] ), [ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ], [ (1,7)(2,8)(3,5)(4,6), (1,6)(2,5)(3,7)(4,8) ] )') sage: H1.group()==phi.Source() True sage: H2.group().canonicalIsomorphism(phi.Range()) != libgap.eval('fail') True sage: phi.IsInjective() true sage: phi.IsSurjective() true sage: phi_star = H2.hom(phi,H1) sage: phi_star.lift() sage: phi_star.knownDeg() 1 sage: phi_star[1] [1 0 0 0 0 0 0 0] [1 1 1 1 1 1 0 0] [1 0 0 0 0 0 0 0] [0 0 1 1 0 0 0 0]
-
name()¶ Return the name of
self.NOTE:
Since induced homomorphisms are cached, there can not be two equal induced homomorphisms with a different name.
EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = G1.IsomorphismGroups(G2) sage: phi.SetName('phi') sage: phi_star = H2.hom(phi,H1) sage: phi_star.name() 'phi^*'
-
poincare_of_image()¶ Poincaré series of the image of
self(which is a sub-ring of the codomain ofself).THEORY:
The kernel of self is computed, using Singular. Together with the relation ideal of the domain of self, it allows to compute the Poincaré series of the quotient of the domain by the kernel, which is isomorphic to the image of self.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make()
We study the restriction to one maximal elementary abelian subgroup:
sage: phi = H.restriction_maps()[2][1] sage: phi Induced homomorphism of degree 0 from H^*(D8; GF(2)) to H^*(SmallGroup(4,2); GF(2)) sage: [phi.codomain().element_as_polynomial(phi(X)) for X in H.gens()] [1: 0-Cocycle in H^*(SmallGroup(4,2); GF(2)), c_1_0*c_1_1+c_1_0^2: 2-Cocycle in H^*(SmallGroup(4,2); GF(2)), c_1_1: 1-Cocycle in H^*(SmallGroup(4,2); GF(2)), 0: 1-Cocycle in H^*(SmallGroup(4,2); GF(2))]
Apparently, the image has dimension one in degree one (given by
c_1_1) and dimension two in degree two (given byc_1_1^2andc_1_0*c_1_1+c_1_0^2). And this can be verified using the Poincaré series of the image:sage: phi.poincare_of_image() 1/(t^3 - t^2 - t + 1) sage: R.<t> = PowerSeriesRing(QQ) sage: (1/(t^3 - t^2 - t + 1))[1] 1 sage: (1/(t^3 - t^2 - t + 1))[2] 2
SEE ALSO:
-
preimage(Item=None, Id=None)¶ ASSUMPTION:
self.codomain()is completely computed.INPUT:
Item– (optional) element insingular(self.codomain())or element of
self.codomain().
Id– (optional) ideal (given by a list of strings) in the codomain, so that lift ofItemwill be done modulo that ideal. Only available ifItemis not provided as an element ofself.codomain()but as element in Singular.
OUTPUT:
Return the preimage of
Iteminsingular(self.domain()), ifself.domain()is completely known, and in the current basering ofself.domain()otherwise.If
Itemis not provided, the kernel ofselfresp. the preimage of the ideal given byIdis returned as an ideal insingular(self.codomain()).If
Itemis a single element andIdisNone, a representative of the preimage ofItemis returned, orNoneif there is no preimage.If
Itemis a single element andIddefines an ideal, a pair is returned, namely one element of the preimage (orNone, if there is no preimage) and the preimage of the ideal given byId).
ALGORITHM:
According to chapter 4.3 of [Green].
EXAMPLE:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(16,3) sage: H.make() sage: r = H.restriction_maps()[1][1] sage: r Induced homomorphism of degree 0 from H^*(SmallGroup(16,3); GF(2)) to H^*(SmallGroup(4,2); GF(2)) sage: singular(r.codomain()).set_ring() sage: p = singular((r.codomain().1+r.codomain().2)^2); p c_1_1^2+c_1_0^2 sage: I = singular.maxideal(2); I c_1_1^2, c_1_0*c_1_1, c_1_0^2 sage: singular(H).set_ring() sage: r.preimage() a_1_0, b_1_1, b_2_1 sage: r.preimage(p) (c_2_3+c_2_2, a_1_0, b_1_1, b_2_1) sage: r.preimage(Id=I) a_1_0, b_1_1, c_2_2, c_2_3, b_2_1
If both an element and an ideal are provided, one preimage of the preimage of the coset ‘element + ideal’ is returned, together with the preimage of the ideal. Here, the preimage of
pfound above is contained in the preimage of the idealI:sage: r.preimage(p,Id=I) (0, a_1_0, b_1_1, c_2_2, c_2_3, b_2_1)
We verify these findings. The kernel:
sage: [r(H(t)).as_polynomial() for t in ['a_1_0','b_1_1','b_2_1']] ['0', '0', '0']
The preimage of
I:sage: [r(H(t)).as_polynomial() for t in ['a_1_0','b_1_1','c_2_2','c_2_3','b_2_1']] ['0', '0', 'c_1_1^2', 'c_1_0^2', '0']
The preimage of
p:sage: r(H('c_2_3+c_2_2')).as_polynomial() 'c_1_1^2+c_1_0^2'
-
rank_of_image(d)¶ Rank of the image of term number \(d\) of
self.THEORY:
The rank of the image is computed by applying some linear algebra to the
d-th term of self.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make()
We study the restriction to one maximal elementary abelian subgroup:
sage: phi = H.restriction_maps()[2][1] sage: phi Induced homomorphism of degree 0 from H^*(D8; GF(2)) to H^*(SmallGroup(4,2); GF(2)) sage: [phi.codomain().element_as_polynomial(phi(X)) for X in H.gens()] [1: 0-Cocycle in H^*(SmallGroup(4,2); GF(2)), c_1_0*c_1_1+c_1_0^2: 2-Cocycle in H^*(SmallGroup(4,2); GF(2)), c_1_1: 1-Cocycle in H^*(SmallGroup(4,2); GF(2)), 0: 1-Cocycle in H^*(SmallGroup(4,2); GF(2))]
Apparently, the image has dimension one in degree one (given by
c_1_1) and dimension two in degree two (given byc_1_1^2andc_1_0*c_1_1+c_1_0^2). And this can be verified using the Poincaré series of the image:sage: phi.rank_of_image(1) 1 sage: phi.rank_of_image(2) 2
SEE ALSO:
-
set_name(s)¶ Give
selfa name.NOTE:
Since induced homomorphisms are cached, there can not be two equal induced homomorphisms with a different name. If the
hom()method is called, the name will be reset.EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = G1.IsomorphismGroups(G2) sage: phi.SetName('phi') sage: phi_star = H2.hom(phi,H1) sage: phi_star.name() 'phi^*' sage: phi_star.set_name('foobar') sage: phi_star.name() 'foobar' sage: H2.hom(phi,H1).name() 'phi^*' sage: phi_star.name() 'phi^*'
-
src()¶ Return the source of the underlying chain map (type
RESL).NOTE:
Since cohomology is a contravariant functor, the output of
src()is the resolution of the codomain.EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = G1.IsomorphismGroups(G2) sage: phi_star = H2.hom(phi,H1) sage: print(phi_star.src()) Resolution: 0 <- GF(2) <- GF(2)[D8] <- rank 2 <- rank 3 <- rank 4 sage: phi_star.src() is phi_star.codomain().resolution() True
-
tgt()¶ Return the codomain of the underlying chain map (type
RESL).NOTE:
Since cohomology is a contravariant functor, the output of
tgt()is the resolution of the domain.EXAMPLES:
We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = G1.IsomorphismGroups(G2) sage: phi_star = H2.hom(phi,H1) sage: print(phi_star.tgt()) Resolution: 0 <- GF(2) <- GF(2)[DihedralGroup(8)] <- rank 2 <- rank 3 <- rank 4 sage: phi_star.tgt() is phi_star.domain().resolution() True
-
-
class
pGroupCohomology.cochain.ChMap_unpickle_class¶ Unpickling an instance of
ChMap, representing an induced homomorphism.EXAMPLES:
Usually, an induced homomorphism is created by defining two groups and a homomorphism between them, computing the cohomology rings of the groups, and then invoking the
hom()method of cohomology rings.We first create the cohomology rings for two different presentations of the dihedral group of order 8.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G1 = libgap.SmallGroup(8,3) sage: H1 = CohomologyRing(8,3, from_scratch=True) sage: H1.make() sage: G2 = libgap.DihedralGroup(8) sage: H2 = CohomologyRing(G2, GroupName = 'DihedralGroup(8)', from_scratch=True) sage: H2.make() sage: phi = G1.IsomorphismGroups(G2)
After ensuring that
phiis printed nicely, we obtain the induced map and see that it is cached:sage: phi.SetName('phi') sage: phi_star = H2.hom(phi,H1) sage: phi_star is loads(dumps(phi_star)) # indirect doctest True
-
class
pGroupCohomology.cochain.CohomologyHomset(X, Y, category=None)¶ Set of Homomorphisms between Modular Cohomology Rings of Finite \(p\)-Groups.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace
We consider the dihedral group of order 8 and will study the restriction maps to representatives for all conjugacy classes of non-trivial subgroups.
sage: G = libgap.DihedralGroup(8) sage: H = CohomologyRing(G,GroupName = 'D8', from_scratch=True) sage: H.make() sage: SubG = [X.RepresentativeSmallest() for X in G.ConjugacyClassesSubgroups()] sage: SubG = [X.MinimalGeneratingSet().Group() for X in SubG if X.Order()>1] sage: for i in range(len(SubG)): ....: SubG[i].SetName('U%d'%(i+1)) sage: HSubG = [CohomologyRing(X, from_scratch=True) for X in SubG] sage: for X in HSubG: ....: X.make() sage: IncG = [X.GroupHomomorphismByImages(G,X.GeneratorsOfGroup(),X.GeneratorsOfGroup()) for X in SubG] sage: for i in range(len(IncG)): ....: IncG[i].SetName('i_%d'%(i+1)) sage: ResG = [H.hom(IncG[i], HSubG[i]) for i in range(len(HSubG))] # indirect doctest
Now, we can apply the maps to elements of
H:sage: ResG[2](H.2+H.3) i_3^*(b_1_0+b_1_1): 1-Cocycle in H^*(SmallGroup(2,1); GF(2))
The image of an element of the base field is mapped to itself, while cochains of degree 0 are properly mapped:
sage: ResG[2](H.0) 1 sage: ResG[2](H(1)) i_3^*(1): 0-Cocycle in H^*(SmallGroup(2,1); GF(2))
Finally, we show how the images of non-scalar generators of
Hunder the various restrictions maps can be expressed as elements of the cohomology rings of the subgroups:sage: for f in ResG: ....: print([f.codomain().element_as_polynomial(f(X)).name() for X in H.gens()[1:]]) ['c_1_0^2', '0', '0'] ['0', 'c_1_0', '0'] ['c_1_0^2', 'c_1_0', 'c_1_0'] ['c_1_1^2+c_1_0*c_1_1', 'c_1_0', '0'] ['c_2_0', '0', 'c_1_0'] ['c_1_1^2+c_1_0*c_1_1+c_1_0^2', 'c_1_1', 'c_1_1'] ['c_2_2', 'b_1_0', 'b_1_1']
-
class
pGroupCohomology.cochain.MODCOCH(parent, value, deg=None, name=None, S=None, rdeg=None, ydeg=None, is_polyrep=False, is_NF=None)¶ Elements of modular cohomology rings of finite groups.
See
pGroupCohomologyorMODCOHOfor examples of cohomology computations.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: H.2 c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)) sage: print(H('b_3_3*c_3_2+c_2_1^2*c_1_0^2')) #indirect doctest (b_3_3)*(c_3_2)+(((c_2_1)^2)*((c_1_0)^2)): 6-Cocycle in H^*(SmallGroup(720,763); GF(2)) defined by b_1_1^4*c_1_2^2+b_1_0^4*c_1_2^2+c_2_5*b_1_0^3*c_1_2+c_2_5^2*b_1_1^2+c_2_5^2*b_1_0*c_1_2+b_1_1^2*c_1_2^4+c_2_5^2*c_1_2^2
-
as_cocycle_in_subgroup()¶ Represent
selfas stable cocycle of the chosen subgroup.OUTPUT:
The element (
MODCOCH) ofself.parent().subgroup_cohomology()by whichselfis defined.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G = libgap.AlternatingGroup(8) sage: H = CohomologyRing(G,prime=2,GroupName='A8') # long time sage: H.make() # long time sage: H.subgroup_cohomology() H^*(SmallGroup(192,1493); GF(2)) sage: H.1.as_cocycle_in_subgroup() (b_1_0)^2+(b_2_2)+(b_2_1): 2-Cocycle in H^*(SmallGroup(192,1493); GF(2)) sage: H.subgroup_cohomology()('b_1_0^2+b_2_2+b_2_1')*H.2.as_cocycle_in_subgroup() == (H.1*H.2).as_cocycle_in_subgroup() True
-
as_cocycle_in_sylow()¶ Represent
selfas stable cocycle of the Sylow subgroup.OUTPUT:
The element (
MODCOCH) ofself.parent().sylow_cohomology()that corresponds toself.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: G = libgap.AlternatingGroup(8) sage: H = CohomologyRing(G,prime=2,GroupName='A8') # long time sage: H.make() # long time sage: H.1.as_cocycle_in_sylow() b_1_1*b_1_2+b_1_1^2+b_1_0^2+b_2_5+b_2_4: 2-Cocycle in H^*(SmallGroup(64,138); GF(2)) sage: H.sylow_cohomology()('b_1_1*b_1_2+b_1_1^2+b_1_0^2+b_2_5+b_2_4')*H.2.as_cocycle_in_sylow() == (H.1*H.2).as_cocycle_in_sylow() True
-
as_polynomial()¶ Find a polynomial representation of
self.OUTPUT: A string that defines a polynomial, expressed in the given generator names of the cohomology ring
NOTE: The name of the cohomology ring element will be changed into the polynomial expression.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: c = H.2 sage: c.setname('charly') sage: c charly: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)) sage: c.name() 'charly' sage: c.as_polynomial() 'c_1_0' sage: c c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2))
-
coef(m)¶ The coefficient of a monomial.
INPUT:
m: A monomial of the underlying cohomology ring of a subgroup (String or SingularOUTPUT:
selfcan be considered as a stable element of the cohomology of a subgroup. Return the coefficient ofmin the normal form of that stable element.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(400,206,prime=5) sage: H.make() sage: c = H.2*H.3*H.1 sage: print(c) ((c_8_0)*(c_16_1))*(a_6_0): 30-Cocycle in H^*(SmallGroup(400,206); GF(5)) defined by c_2_1^3*c_2_2^11*a_1_0*a_1_1-c_2_1^11*c_2_2^3*a_1_0*a_1_1
We can use a monomial in the Singular interface
sage: c.coef(c.lm()) 1
or given by a string:
sage: c.coef('c_2_1^11*c_2_2^3*a_1_0*a_1_1') -1
-
coef_list(M)¶ Return the list of coefficients.
INPUT:
A list of standard monomials (represented by strings) of the cohomology ring of the underlying subgroup
OUTPUT:
A list of integers, providing the coefficients of the given monomials in the stable element (normal form) that corresponds to
self.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(400,206,prime=5) sage: H.make() sage: c = H.2*H.3*H.1 sage: print(c) ((c_8_0)*(c_16_1))*(a_6_0): 30-Cocycle in H^*(SmallGroup(400,206); GF(5)) defined by c_2_1^3*c_2_2^11*a_1_0*a_1_1-c_2_1^11*c_2_2^3*a_1_0*a_1_1
We wish to get the list of coefficients of
cfor all standard monomials of the underlying subgroup:sage: M = H.subgroup_cohomology().standard_monomials(30); M ['c_2_2^14*a_1_0*a_1_1', 'c_2_1*c_2_2^13*a_1_0*a_1_1', 'c_2_1^2*c_2_2^12*a_1_0*a_1_1', 'c_2_1^3*c_2_2^11*a_1_0*a_1_1', 'c_2_1^4*c_2_2^10*a_1_0*a_1_1', 'c_2_1^5*c_2_2^9*a_1_0*a_1_1', 'c_2_1^6*c_2_2^8*a_1_0*a_1_1', 'c_2_1^7*c_2_2^7*a_1_0*a_1_1', 'c_2_1^8*c_2_2^6*a_1_0*a_1_1', 'c_2_1^9*c_2_2^5*a_1_0*a_1_1', 'c_2_1^10*c_2_2^4*a_1_0*a_1_1', 'c_2_1^11*c_2_2^3*a_1_0*a_1_1', 'c_2_1^12*c_2_2^2*a_1_0*a_1_1', 'c_2_1^13*c_2_2*a_1_0*a_1_1', 'c_2_1^14*a_1_0*a_1_1', 'c_2_2^15', 'c_2_1*c_2_2^14', 'c_2_1^2*c_2_2^13', 'c_2_1^3*c_2_2^12', 'c_2_1^4*c_2_2^11', 'c_2_1^5*c_2_2^10', 'c_2_1^6*c_2_2^9', 'c_2_1^7*c_2_2^8', 'c_2_1^8*c_2_2^7', 'c_2_1^9*c_2_2^6', 'c_2_1^10*c_2_2^5', 'c_2_1^11*c_2_2^4', 'c_2_1^12*c_2_2^3', 'c_2_1^13*c_2_2^2', 'c_2_1^14*c_2_2', 'c_2_1^15'] sage: c.coef_list(M) [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-
deg()¶ Degree of a cohomology element.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: H('c_3_2^2+b_3_3*c_3_2+c_2_1*c_1_0*c_3_2').deg() 6
The degree may be explicitly provided in the definition of the cohomology ring element, even if it is not clear from its given value:
sage: from pGroupCohomology.cochain import MODCOCH sage: c = MODCOCH(H, '0', deg=15) sage: c.deg() 15
-
is_nilpotent()¶ Tells whether this cocycle is nilpotent.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(60,3,prime=2) sage: H.make() sage: singular(H).set_ring() sage: H.nil_radical() c_1_0 sage: H.gens() [1, c_2_0: 2-Cocycle in H^*(SmallGroup(60,3); GF(2)), c_1_0: 1-Cocycle in H^*(SmallGroup(60,3); GF(2))] sage: H.gen(1).is_nilpotent() False sage: H.gen(2).is_nilpotent() True sage: bool(H.gen(2)^2) False
An example in odd characteristic:
sage: H = CohomologyRing(1620, 23, prime=3) sage: H.make() sage: H.1.is_nilpotent() True sage: bool(H.1^2) True sage: bool(H.1^3) False sage: H.2.is_nilpotent() False
-
lc()¶ Leading coefficient of
self(type <int>).OUTPUT:
An element of a modular cohomology ring of a finite group is given by a stable element in the cohomology ring of a suitable subgroup. Expressing the stable element as a polynomial, this method returns its leading coefficient, as an int.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(400,206,prime=5) sage: H.make() sage: singular(H.subgroup_cohomology()).set_ring() sage: (H.6*H.8).lc() 2
-
lm()¶ Leading monomial (no coefficient) of
self.OUTPUT:
An element of a modular cohomology ring of a finite group is given by a stable element in the cohomology ring of a suitable subgroup. Expressing the stable element as a polynomial, this method returns its leading monomial, as an element of the Singular interface.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(72,40,prime=3) sage: H.make() sage: singular(H.subgroup_cohomology()).set_ring() sage: H.4.lm() c_2_1*c_2_2^2*a_1_0
-
lm_string()¶ Leading monomial (no coefficient) of
self(type <string>).OUTPUT:
An element of a modular cohomology ring of a finite group is given by a stable element in the cohomology ring of a suitable subgroup. Expressing the stable element as a polynomial, this method returns its leading monomial, as a string.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(72,40,prime=3) sage: H.make() sage: H.4.lm_string() 'c_2_1*c_2_2^2*a_1_0'
-
lt()¶ Leading term of the underlying cohomology element.
OUTPUT:
An element of a modular cohomology ring of a finite group is given by a stable element in the cohomology ring of a suitable subgroup. Expressing the stable element as a polynomial, this method returns its leading term (i.e., the product of coefficient and monomial), as an element in the Singular interface.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(400,206,prime=5) sage: H.make() sage: singular(H.subgroup_cohomology()).set_ring() sage: (H.6*H.8).lt() 2*c_2_1^5*c_2_2^5*a_1_0*a_1_1
-
massey_power(i=1)¶ Experimental: Restricted Massey power.
ALGORITHM:
A cocycle
Cis expressed as a (stable) element of the cohomology of the Sylow subgroup. The Massey power is computed there (seemassey_power()).NOTE:
We did not prove that the result always is a stable element. But if it is, it yields the restricted Massey power of
C. Therefore, this method is merely experimental.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(432,234,prime=3) sage: H.make() sage: c = H.5; c a_3_0: 3-Cocycle in H^*(SmallGroup(432,234); GF(3)) sage: cS = c.as_cocycle_in_sylow(); cS b_2_3*a_1_1+b_2_0*a_1_0: 3-Cocycle in H^*(E27; GF(3)) sage: cM = c.massey_power(); cM b_4_0*b_4_1+b_4_0^2: 8-Cocycle in H^*(SmallGroup(432,234); GF(3)) sage: cSM = cS.massey_power(); cSM <(b_2_3)*(a_1_1)+(b_2_0)*(a_1_0); 1>: 8-Cocycle in H^*(E27; GF(3)) sage: cM.as_cocycle_in_sylow() == cSM True
-
name()¶ Return the name of the cohomology ring element.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: c = H.2 sage: c.name() 'c_1_0' sage: c.setname('charly') sage: c charly: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)) sage: c.name() 'charly' sage: c.as_polynomial() 'c_1_0' sage: c c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2))
-
nilpotency_degree()¶ The smallest exponent by which this cocycle becomes zero.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(60,3,prime=2) sage: H.make() sage: singular(H).set_ring() sage: H.nil_radical() c_1_0 sage: H.gens() [1, c_2_0: 2-Cocycle in H^*(SmallGroup(60,3); GF(2)), c_1_0: 1-Cocycle in H^*(SmallGroup(60,3); GF(2))] sage: H.1.is_nilpotent() False sage: H.1.nilpotency_degree() +Infinity sage: (H.1*0).nilpotency_degree() 1 sage: H.2.is_nilpotent() True sage: bool(H.2^2) False sage: H.2.nilpotency_degree() 2
An example in odd characteristic:
sage: H = CohomologyRing(1620, 23, prime=3) sage: H.make() sage: for g in H.Gen: ....: if g.nilpotency_degree() == 3: ....: break ....: sage: bool(g^2) True sage: bool(g^3) False sage: H.2.is_nilpotent() False sage: H.2.nilpotency_degree() +Infinity sage: (H.2*0).nilpotency_degree() 1
-
nilreduce()¶ Inplace reduction of
self’s value by the ideal generated by nilpotent generators.OUTPUT:
self. Before, all nilpotent generators of the cohomology containingself.value()are killed inself.value().EXAMPLES:
Since this test relies on the ring presentation of the cohomology of a certain subgroup, we compute it from scratch, rather than relying on potentially outdated data in the local sources.
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: X = CohomologyRing(81,8, from_scratch=True) sage: X.make() sage: H = CohomologyRing(648,132,prime=3, from_scratch=True) sage: H.make() sage: c = copy(H.5) sage: c c_6_0: 6-Cocycle in H^*(SmallGroup(648,132); GF(3))
cis a regular element (marked by the letter ‘c’ in its name). We took a copy of the generator ofHsincecwill be changed inplace. Interpreted as an element of the cohomology of the underlying subgroup, it has one nilpotent summand:sage: c.as_cocycle_in_subgroup() b_6_3+a_1_0*a_5_2-c_6_4: 6-Cocycle in H^*(SmallGroup(81,8); GF(3))
We kill this summand:
sage: c.nilreduce() c_6_0: 6-Cocycle in H^*(SmallGroup(648,132); GF(3)) sage: c.as_cocycle_in_subgroup() b_6_3-c_6_4: 6-Cocycle in H^*(SmallGroup(81,8); GF(3))
Indeed, the value of
chas changed:sage: c == H.5 False
-
rdeg()¶ \(r\)-degree.
This is supposed to be 1 for Duflot elements, i.e., for those elements that have a non-zero restrictions to the centre of a Sylow subgroup.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: [t.rdeg() for t in H.Gen] [1, 1, 0, 1]
So, the restriction of all but the third generator to the centre of a Sylow subgroup should be non-zero:
sage: r = H.restriction_maps()[1][1] sage: r Induced homomorphism of degree 0 from H^*(SmallGroup(720,763); GF(2)) to H^*(SmallGroup(4,2); GF(2)) sage: print(r(H.1)._NF_()) c_1_1^2: 2-Cocycle in H^*(SmallGroup(4,2); GF(2)) defined by c_1_1^2 sage: print(r(H.2)._NF_()) c_1_0: 1-Cocycle in H^*(SmallGroup(4,2); GF(2)) defined by c_1_0 sage: print(r(H.3)._NF_()) 0: 3-Cocycle in H^*(SmallGroup(4,2); GF(2)) defined by 0 sage: print(r(H.4)._NF_()) c_1_0*c_1_1^2: 3-Cocycle in H^*(SmallGroup(4,2); GF(2)) defined by c_1_0*c_1_1^2
-
set_latex_name(s)¶ Declare how self should be typeset in LaTeX.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: latex(H.2) b_{1,0} sage: (H.2).set_latex_name('H_2') sage: latex(H.2) H_2
-
setname(s, is_polyrep=False)¶ Set the name of a cohomology ring element.
INPUT:
s(string), new namme of the elementis_polyrep(optional boolean, defaultFalse): IfTrue, the user asserts that the new name provides a polynomial representation of the element, expressed in the given generator names of the cohomology ring
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: c = H.2 sage: c.setname('charly') sage: c charly: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)) sage: c.name() 'charly' sage: c.as_polynomial() 'c_1_0' sage: c c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2))
-
val_str()¶ A polynomial representation as stable element.
OUTPUT:
A string that provides a polynomial representation for the cohomology ring element, expressed as a (stable) cocycle of the underlying subgroup.
NOTE:
In general, the normal form is not computed before returning the result.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: (H.1*H.2)._NF_().val_str() 'b_1_1^2*c_1_2+b_1_0^2*c_1_2+c_2_5*b_1_1+b_1_1*c_1_2^2+c_2_5*c_1_2' sage: H.one().val_str() '1'
-
value()¶ The value of self in the Singular interface.
NOTE:
By “value”, we mean its representation in the Singular interface as a stable element in the cohomology ring of the chosen subgroup.
This value is not unique, as the cohomology ring of the subgroup is a quotient ring. Thus, the value is a coset representative, and it is not necessarily in normal form.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: singular(H.subgroup_cohomology()).set_ring() sage: (H.1*H.2+H.3)._NF_().value() b_1_1^2*c_1_2+b_1_0^2*c_1_2+c_2_5*b_1_1+c_2_5*b_1_0+b_1_1*c_1_2^2+c_2_5*c_1_2
Note that if Singular crashed, it is attempted to reconstructed the value. However, this is only possible if
val_str()was called before.sage: c = (H.1*H.2+H.3)._NF_() sage: c.val_str() 'b_1_1^2*c_1_2+b_1_0^2*c_1_2+c_2_5*b_1_1+c_2_5*b_1_0+b_1_1*c_1_2^2+c_2_5*c_1_2' sage: singular.quit() sage: CohomologyRing.global_options('info') sage: c.value() H^*(D8xC2; GF(2)): Reconstructing data in the Singular interface b_1_1^2*c_1_2+b_1_0^2*c_1_2+c_2_5*b_1_1+c_2_5*b_1_0+b_1_1*c_1_2^2+c_2_5*c_1_2 sage: CohomologyRing.global_options('warn')
-
ydeg()¶ \(y\)-degree.
This is supposed to be 1 for nilpotent elements.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=3) sage: H.make() sage: [t.ydeg() for t in H.Gen] [0, 0, 1, 1]
Indeed, the last two generators are nilpotent:
sage: print(H.3**2) (a_3_0)^2: 6-Cocycle in H^*(SmallGroup(720,763); GF(3)) defined by 0 sage: print(H.4**2) (a_7_1)^2: 14-Cocycle in H^*(SmallGroup(720,763); GF(3)) defined by 0
-
-
pGroupCohomology.cochain.MODCOCH_unpickle(L0, L1, L2, L3, L4, L5, L6=False, L7=None)¶ Auxiliary function for unpickling
MODCOCH.TESTS:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(720,763,prime=2) sage: H.make() sage: H.1 == loads(dumps(H.1)) #indirect doctest True sage: H.1 is loads(dumps(H.1)) #indirect doctest False
-
class
pGroupCohomology.cochain.YCOCH¶ Yoneda cochains.
This is an auxiliary class to facilitate the computation of Massey products.
A Yoneda \(i\)-cochain is a collection of maps from the \((i+n)\)-the term to the \(n\)-th term of a resolution of a group algebra, \(n=0,1,2,...\). There is no compatibility condition whatsoever (e.g., the maps are not supposed to commute with the boundary maps of the resolution).
Yoneda cochains form a cocomplex, equipped with the coboundary map \(\partial\) defined by \((\partial \phi^i)_n = \phi_n\circ d_{n+i+1} - (-1)^i d_{n-i+1}\circ \phi_{n+1}^i\) where
\(P_\ast\) is a resolution
\(\phi^i\) is a Yoneda \(i\)-cochain, \(\phi^i_n: P_{i+n}\to P_n\) for \(n=0,1,2,...\)
\(\phi_n\\circ d_{n+i+1}\) means \(d_{n+i+1}\) followed by \(\phi_n\).
If \(Y_1,Y_2\) are two Yoneda cochains, then \(Y_1*Y_2\) is their composition, where we use the convention first \(Y_2\) then \(Y_1\).
INPUT:
R: a resolution (RESL)n: the degree of the Yoneda cochain (non-negative integer)M_0,M_1,...,M_i,...: a list ofMatrix_gfpn_densematrices defining maps from the \((n+i)\)-th to the \(i\)-th term ofR.coboundary=None(optional): If it is given, it must be a Yoneda cocycle that is the coboundary of selfconstruction=None(optional): If it is given, it is a list describing its construction. Either:['+',Y1,Y2](self is sum of Yoneda cochainsY1, Y2),['-',Y1,Y2](self isY1-Y2),['-',Y](self is-Y),['*',Y1,Y2](self is the composition of two Yoneda cochains,Y2followed byY1), or['D',Y](self is the coboundary of the Yoneda cochainY).
NOTE:
The optional parameters are internally used in
coboundary(),find_cobounding_yoneda_cochains()and when adding or composing Yoneda cochains. We however document some of the options here.We did not implement comparisons between Yoneda cochains, simply since they morally have infinitely many terms, and if two Yoneda cochains have a different construction, it would thus hardly be possible to prove equality, in general.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: from pGroupCohomology.cochain import YCOCH sage: from sage.matrix.matrix_gfpn_dense import Matrix_gfpn_dense as MTX sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: R = H.resolution() sage: R Resolution of GF(2)[D8] sage: Y = YCOCH(R,1, MTX(MatrixSpace(GF(2),2,8, implementation=MTX), [[1,0,1,0,1,0,1,0],[1,0,1,0,1,0,1,0]])) sage: len(Y) 1
If higher terms of
Yare required, they are automatically computed. Since no construction and no coboundary was provided in the definition ofY, it is lifted so that its coboundary is zero.sage: Y[1] [1 0 0 0 0 0 0 0] [0 1 0 0 0 1 0 0] [0 0 0 0 0 0 0 0] [1 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 1 0 1 0 0] sage: len(Y) 2 sage: Y[0] [1 0 1 0 1 0 1 0] [1 0 1 0 1 0 1 0] sage: Y.coboundary()[0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
Next, we provide all terms explicitly, yielding a Yoneda cochain that is not a cocycle:
sage: tmpM1 = MTX(MatrixSpace(GF(2),2,8, implementation=MTX), [[1,0,1,0,1,0,1,0],[1,0,1,0,1,0,1,0]]) sage: tmpM2 = MTX(MatrixSpace(GF(2),6,8, implementation=MTX), [[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0],[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0]]) sage: Y = YCOCH(R,1,tmpM1,tmpM2) sage: Y Yoneda 1-cochain on a resolution of GF(2)[D8] sage: Y[0] [1 0 1 0 1 0 1 0] [1 0 1 0 1 0 1 0] sage: Y[1] [0 1 1 0 0 1 1 0] [1 1 0 0 1 1 0 0] [1 0 1 0 1 0 1 0] [0 1 1 0 0 1 1 0] [1 1 0 0 1 1 0 0] [1 0 1 0 1 0 1 0] sage: Y.coboundary()[0] [0 1 1 1 0 0 0 1] [0 1 1 1 1 1 1 0] [0 1 1 0 0 0 1 1] sage: Y.coboundary()[1] [0 0 0 0 1 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 1 0 0] [0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0]
Of course, the coboundary of the coboundary vanishes:
sage: Y.coboundary().coboundary()[0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] sage: Y.coboundary().coboundary()[1] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
Here is what happens internally when defining the composition of
Ywith itself:sage: YY = YCOCH(R, 2, construction=['*',Y,Y]) sage: YY[0] [1 0 0 0 0 0 1 1] [1 1 1 0 1 1 1 1] [0 1 1 0 1 1 0 0] sage: YY[1] [0 1 0 0 0 0 0 0] [0 1 0 0 1 0 0 1] [1 1 1 1 1 1 1 1] [1 0 0 0 1 0 0 0] [0 1 1 1 1 1 0 1] [1 0 0 0 1 1 1 0] [0 1 0 1 0 0 1 0] [1 1 0 1 0 0 1 0]
However, usually one would define the composition like that:
sage: YY = Y*Y sage: YY[0] [1 0 0 0 0 0 1 1] [1 1 1 0 1 1 1 1] [0 1 1 0 1 1 0 0] sage: YY[1] [0 1 0 0 0 0 0 0] [0 1 0 0 1 0 0 1] [1 1 1 1 1 1 1 1] [1 0 0 0 1 0 0 0] [0 1 1 1 1 1 0 1] [1 0 0 0 1 1 1 0] [0 1 0 1 0 0 1 0] [1 1 0 1 0 0 1 0]
Internally, the coboundary of
YYwould be constructed like that:sage: DYY = YCOCH(YY.resolution(), YY.deg()+1, construction=['D',YY]) sage: DYY[0] [0 1 0 0 1 0 0 1] [0 1 0 0 0 1 1 0] [0 0 1 1 1 1 1 1] [0 0 1 1 1 1 0 1] sage: DYY[1] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 1 1 0 0 1 1] [0 0 1 0 0 0 1 0] [0 0 0 1 1 0 1 0] [0 1 1 0 0 1 1 0] [0 1 0 1 0 0 1 0] [0 0 1 1 1 0 1 1] [0 1 0 1 0 0 1 0] [0 0 1 0 1 0 1 1]
Of course, for the user it is easier to just do
sage: DYY = YY.coboundary() sage: DYY[0] [0 1 0 0 1 0 0 1] [0 1 0 0 0 1 1 0] [0 0 1 1 1 1 1 1] [0 0 1 1 1 1 0 1]
-
append(M)¶ append further terms to
self.INPUT:
M:Matrix_gfpn_densematrix defining the next term of selfNOTE:
Actually an immutable copy of
Mis appended.Warning: It is strongly recommended to not use this method manually, as it is not checked whether the appended term fits to the construction of the Yoneda cochain.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: from sage.matrix.matrix_gfpn_dense import Matrix_gfpn_dense as MTX sage: from pGroupCohomology.cochain import YCOCH sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: tmpM1 = MTX(MatrixSpace(GF(2),2,8, implementation=MTX), [[1,0,1,0,1,0,1,0],[1,0,1,0,1,0,1,0]]) sage: tmpM2 = MTX(MatrixSpace(GF(2),6,8, implementation=MTX), [[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0],[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0]]) sage: Y = YCOCH(H.resolution(), 1, tmpM1, tmpM2) sage: M = MTX(MatrixSpace(GF(2),12,8, implementation=MTX), [[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0],[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0],[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0],[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0]]) sage: Y.append(M) sage: Y[2]==M True
-
coboundary()¶ Return the Yoneda coboundary of
self.THEORY:
If \(d_\ast: P_\ast \to P_{\ast-1}\) denotes the boundary maps of \(P_\ast\) and \(\phi^i\) is a Yoneda \(i\)-cochain with \(\phi^i_n: P_{i+n}\to P_n\) then \((\partial \phi^i)_n = \phi_n\circ d_{n+i+1} - (-1)^i d_{n-i+1}\circ \phi_{n+1}^i\), which is a Yoneda \((i+1)\)-cocycle.
NOTE:
Coboundary and lifting commute, see
lift().EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: from sage.matrix.matrix_gfpn_dense import Matrix_gfpn_dense as MTX sage: from pGroupCohomology.cochain import YCOCH sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: tmpM1 = MTX(MatrixSpace(GF(2),2,8, implementation=MTX), [[1,0,1,0,1,0,1,0],[1,0,1,0,1,0,1,0]]) sage: tmpM2 = MTX(MatrixSpace(GF(2),6,8, implementation=MTX), [[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0],[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0]]) sage: Y = YCOCH(H.resolution(),1,tmpM1, tmpM2) sage: YC = Y.coboundary() sage: YC Yoneda 2-cochain on a resolution of GF(2)[D8] sage: print(YC[0]) [0 1 1 1 0 0 0 1] [0 1 1 1 1 1 1 0] [0 1 1 0 0 0 1 1] sage: print(YC[1]) [0 0 0 0 1 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 1 0 1 0 0] [0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0] sage: print(YC[2]) [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 1 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 1 1 0 0 0 0 0]
The coboundary of the coboundary vanishes:
sage: YCC = YC.coboundary() sage: print(YCC[0]) [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] sage: print(YCC[1]) [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]
-
deg()¶ Return the degree of
self.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: from pGroupCohomology.cochain import YCOCH sage: from sage.matrix.matrix_gfpn_dense import Matrix_gfpn_dense as MTX sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: Y = YCOCH(H.resolution(),2,H.resolution().CochainToChainmap(2,H.1.MTX())[2]) sage: Y.deg() 2
-
find_cobounding_yoneda_cochains(all=True)¶ Construct Yoneda cochains whose coboundary is
self.ASSUMPTION:
selfis a Yoneda cocycle. Note that this assumption is not verified.OUTPUT:
A list of Yoneda cochains whose coboundary is
self.If the optional parameter
allisTrue(which is default) then a list of Yoneda cochains is returned that are pairwise not cohomologous (i.e., the pairwise difference is not a coboundary). Otherwise, the list will only contain at most one Yoneda cochain.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: H.gens() [1, c_2_2: 2-Cocycle in H^*(D8; GF(2)), b_1_0: 1-Cocycle in H^*(D8; GF(2)), b_1_1: 1-Cocycle in H^*(D8; GF(2))] sage: H.rels() ['b_1_0*b_1_1'] sage: Y1 = H.2.yoneda_cocycle() sage: Y2 = H.3.yoneda_cocycle() sage: Y12 = Y1*Y2 sage: Y12.find_cobounding_yoneda_cochains() [Yoneda 1-cochain on a resolution of GF(2)[D8], Yoneda 1-cochain on a resolution of GF(2)[D8], Yoneda 1-cochain on a resolution of GF(2)[D8], Yoneda 1-cochain on a resolution of GF(2)[D8]] sage: C1, C2, C3, C4 = _
Indeed, the pairwise differences are no coboundaries:
sage: print(C1[0]) [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] sage: print(C2[0]) [1 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] sage: print(C3[0]) [0 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] sage: print(C4[0]) [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0]
But the coboundary of
C1,...,C4isY12:sage: print(C1.coboundary()[1]) [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0] sage: Y12[1] == C1.coboundary()[1] True sage: Y12[0] == C1.coboundary()[0] True sage: Y12[1] == C1.coboundary()[1] True sage: Y12[2] == C1.coboundary()[2] True sage: Y12[0] == C2.coboundary()[0] True sage: Y12[1] == C2.coboundary()[1] True sage: Y12[2] == C2.coboundary()[2] True sage: Y12[0] == C3.coboundary()[0] True sage: Y12[1] == C3.coboundary()[1] True sage: Y12[2] == C3.coboundary()[2] True sage: Y12[0] == C4.coboundary()[0] True sage: Y12[1] == C4.coboundary()[1] True sage: Y12[2] == C4.coboundary()[2] True
-
lift(check=False)¶ Compute the next term of
self.THEORY:
If the coboundary of self vanishes, then the next term is chosen so that the coboundary still vanishes. In the general case, since the coboundary of a Yoneda cochain is a cocycle, we can lift the coboundary according to the previously stated property. Then, the next term is chosen such that the lift and the coboundary map commute.
EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: from sage.matrix.matrix_gfpn_dense import Matrix_gfpn_dense as MTX sage: from pGroupCohomology.cochain import YCOCH sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: tmpM1 = MTX(MatrixSpace(GF(2),2,8, implementation=MTX), [[1,0,1,0,1,0,1,0],[1,0,1,0,1,0,1,0]]) sage: tmpM2 = MTX(MatrixSpace(GF(2),6,8, implementation=MTX), [[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0],[0,1,1,0,0,1,1,0],[1,1,0,0,1,1,0,0],[1,0,1,0,1,0,1,0]]) sage: Y = YCOCH(H.resolution(), 1, tmpM1, tmpM2) sage: YC = Y.coboundary() sage: len(YC) 1
We compute the third term of
YCand verify that this is the same as computing the fourth term ofYand then taking the third term of the coboundary of the extended version ofY. Note that when asking for a term that has not been computed yet (e.g.,YC[2]) then lifting is done automatically.sage: print(YC[2]) [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 1 1 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0] [0 1 1 0 0 0 0 0] sage: Y.lift() sage: Y.lift() sage: len(Y) 4
Now, as four terms of
Yare known, the third term of its coboundary is known even without lifting. But it coincides with the third term obtained by liftingYC:sage: YC[2] == Y.coboundary()[2] True
-
resolution()¶ Return the resolution over which
selfis defined.EXAMPLES:
sage: from pGroupCohomology import CohomologyRing sage: from pGroupCohomology.cochain import YCOCH sage: CohomologyRing.doctest_setup() # reset, block web access, use temporary workspace sage: H = CohomologyRing(8,3) sage: H.make() sage: Y = YCOCH(H.resolution(),2,H.resolution().CochainToChainmap(2,H.1.MTX())[2]) sage: print(Y.resolution()) Resolution: 0 <- GF(2) <- GF(2)[D8] <- rank 2 <- rank 3 <- rank 4