# Basic cohomology code for non prime power groups¶

This module contains MODCOHO, that provides a framework for the computation of the cohomology rings with coefficients in $$\mathbb F_p$$ for any finite group.

It is based on the stable element method of Henri Cartan and Samuel Eilenberg [CartanEilenberg] and uses a completeness criterion based on the Poincaré series [King]. The stable element method involves the computation of cohomology rings of finite $$p$$-groups, which is based on the class COHO. See pGroupCohomology for an introduction.

AUTHORS:

pGroupCohomology.modular_cohomology.COHO_from_key(key)

Auxiliary function for getting a cohomology ring out of some internal description.

NOTE:

This function is only of internal use. In future, this function should be replaced by a relational data base. The function returns the completed cohomology ring.

TESTS:

sage: from pGroupCohomology import CohomologyRing
sage: from pGroupCohomology.modular_cohomology import COHO_from_key
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)
sage: H.make(3)


We remove H from the cache. The cohomology of its underlying subgroup is still there, and is returned by COHO_from_key:

sage: del CohomologyRing._cache[H._key]
sage: H.subgroup_cohomology() is COHO_from_key(H.subgroup_cohomology()._key)
True


When calling for the cohomology key of H, it can not be found in the cache. Instead, it is reloaded from disk:

sage: H is COHO_from_key(H._key)
False


In fact, it is not only reloaded, but it is completely computed, in contrast to H:

sage: print(H)
Cohomology ring of SmallGroup(720,763) with coefficients in GF(2)
<BLANKLINE>
Computed up to degree 3
Minimal list of generators:
[c_2_1: 2-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)),
b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
Minimal list of algebraic relations:
[]
sage: print(COHO_from_key(H._key))
Cohomology ring of SmallGroup(720,763) with coefficients in GF(2)
<BLANKLINE>
Computation complete
Minimal list of generators:
[c_2_1: 2-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)),
b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
Minimal list of algebraic relations:
[b_3_3*c_3_2+c_2_1*c_1_0*b_3_3]

class pGroupCohomology.modular_cohomology.MODCOHO(G, p, HP, Subgroup, **kwds)

Modular cohomology rings of finite groups that are not of prime power order.

Normally, instances of this class should be created using the constructor CohomologyRing(), since this takes care of uniqueness of parent structures. See CohomologyRing() and pGroupCohomology for an introduction.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: G = libgap.SmallGroup(48,36)
sage: H1 = CohomologyRing(G, prime=2, GroupName='SomeGroup', from_scratch=True)
sage: H1.make()
sage: H1.poincare_series()
1/(-t^3 + 3*t^2 - 3*t + 1)
sage: H2 = CohomologyRing(48,36, prime=2)   # indirect doctest


In order to save resources, the cohomology ring is cached and then reloaded even if a different definition is provided:

sage: H1 is H2
True
sage: print(H2)
Cohomology ring of SomeGroup with coefficients in GF(2)
<BLANKLINE>
Computation complete
Minimal list of generators:
[c_2_5: 2-Cocycle in H^*(SomeGroup; GF(2)),
b_1_0: 1-Cocycle in H^*(SomeGroup; GF(2)),
b_1_1: 1-Cocycle in H^*(SomeGroup; GF(2)),
c_1_2: 1-Cocycle in H^*(SomeGroup; GF(2))]
Minimal list of algebraic relations:
[b_1_0*b_1_1]
True

HilbertPoincareTest(forced=None)

Try to prove completeness of the ring structure using the Poincaré series.

OUTPUT:

True, False or None, depending on whether the Hilbert-Poincaré criterion proves completeness or incompleteness of the ring approximation or was not conclusive.

ASSUMPTION:

The generating set is already complete.

THEORY:

If the cohomology ring has depth at least $$D$$ and has a homogeneous system of parameters of degrees $$d_1,...,d_r$$ , and if the current approximation of the cohomology ring has a complete generating set and is known at least out to degree $$\sum d_i-D$$, then the approximation is complete if and only if its Poincaré series multiplied by $$\prod (1-t^{d_i})$$ is a polynomial of degree at most $$\sum d_i-D$$. See [King] for more details.

EXAMPLES:

We compute a cohmology ring step by step, in order to demonstrate what happens behind the scenes when launching make(). Be aware that this is not recommended.

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(384, 5602, prime=2, from_scratch=True)


In the following line, we are cheating a bit: Without it, other parameters would be found for $$H$$.

sage: H.sylow_cohomology().find_dickson()
True
sage: H.make(4)


In the current ring approximation, a degree bound for the generators was determined by generator_degbound() and stored in some attribute. Apparently, all generators have been found:

sage: H.degbound_for_gens
4
sage: H.all_generators_found
True
sage: H.degvec
[2, 2, 4, 1, 1, 3, 3, 3]


We did not bother to find filter regular parameters yet:

sage: H.filter_regular_parameters()


Indeed, we expect a relation in degree 6:

sage: H.expect_last_relation()
6


Nevertheless, it is possible to find filter regular parameters for the cohomology ring in this approximation. Again, this function would not be called in an automatic computation, thus resulting in different parameters:

sage: H.find_dickson()
True
sage: H.filter_regular_parameters()
['b_1_1^2*b_3_1^2+...',
'b_3_9^4+...',
'b_1_1^2*b_3_1^4+...',
'b_1_0^3*b_3_0^2*b_3_1^2+...']


So, they live in degrees 4, 12, 14 and 15. It would be possible to find a last filter-regular parameter in degree 1, but that would still not allow to apply the Benson criterion. When we invest considerably more time, we could find algebraically independent (but not necessarily filter-regular) parameters in much smaller degrees 4, 12, 2 and 1, by calling

sage: H.parameters()                    # not tested
['b_1_1^4+b_1_0^3*b_1_1+b_1_0^4+b_2_4*b_1_1^2+b_2_4*b_1_0^2+b_2_4^2+b_2_3^2+c_4_15',
'b_3_9^4+b_3_1^4+b_3_0^4+b_1_1^6*b_3_1^2+b_1_0^2*b_1_1^4*b_3_1^2+b_1_0^3*b_3_0^2*b_3_1+b_1_0^4*b_1_1^8+b_1_0^6*b_3_1^2+b_1_0^6*b_3_0*b_3_1+b_1_0^6*b_3_0^2+b_1_0^8*b_1_1^4+b_2_4*b_1_0^4*b_3_0*b_3_1+b_2_4*b_1_0^7*b_3_1+b_2_4^2*b_1_1^2*b_3_1^2+b_2_4^2*b_1_0^2*b_3_0^2+b_2_4^2*b_1_0^2*b_1_1^6+b_2_4^2*b_1_0^8+b_2_4^4*b_1_1^4+b_2_4^4*b_1_0^2*b_1_1^2+b_2_4^4*b_1_0^4+b_2_3*b_1_0^4*b_3_0^2+b_2_3*b_2_4*b_1_0^5*b_3_0+b_2_3^2*b_1_0^2*b_3_0^2+b_2_3^4*b_1_0^4+c_4_15*b_1_1^2*b_3_1^2+c_4_15*b_1_1^5*b_3_1+c_4_15*b_1_0*b_1_1^4*b_3_1+c_4_15*b_1_0*b_1_1^7+c_4_15*b_1_0^2*b_3_1^2+c_4_15*b_1_0^5*b_3_0+b_2_4*c_4_15*b_1_1^3*b_3_1+b_2_4*c_4_15*b_1_1^6+b_2_4*c_4_15*b_1_0*b_1_1^5+b_2_4*c_4_15*b_1_0^2*b_1_1*b_3_1+b_2_4^2*c_4_15*b_1_1*b_3_1+b_2_4^2*c_4_15*b_1_0*b_3_0+b_2_4^3*c_4_15*b_1_1^2+b_2_4^3*c_4_15*b_1_0*b_1_1+b_2_3*c_4_15*b_1_0^3*b_3_0+b_2_3*b_2_4*c_4_15*b_1_0^4+b_2_3^2*c_4_15*b_1_0*b_3_0+b_2_3^3*c_4_15*b_1_0^2+c_4_15^2*b_1_1*b_3_1+c_4_15^2*b_1_0*b_3_0+c_4_15^2*b_1_0^4+b_2_4*c_4_15^2*b_1_0*b_1_1+b_2_4*c_4_15^2*b_1_0^2+b_2_4^2*c_4_15^2+b_2_3^2*c_4_15^2',
'b_2_4+b_2_3',
'b_1_1+b_1_0']


However, all the above effort was in vain (that’s why we removed that test), as The Poincaré series shows that the approximation cannot be complete: The Poincaré series’ denominator does not divide $$(1-t^{4})(1-t^{12})(1-t^{2})(1-t)$$, where the exponents are given by the degrees of the above set of algebraically independent parameters:

sage: p = H.poincare_series()
sage: t = p.parent().gen()
sage: (p*(1-t^4)*(1-t^12)*(1-t^2)*(1-t)).denominator().monic()
t^6 - 2*t^3 + 1


Let us continue the computation step by step. Of course, normally we would just do H.make() instead.

sage: H.next()
sage: H.next()
sage: H.knownDeg
6


The parameters found above are of high degrees, and hence it seems hopeless to apply any of our criteria with them. But we do find algebraically dependent parameters in relatively small degrees:

sage: H.dependent_parameters()
['b_1_0', 'b_1_1', 'c_4_15', 'b_3_1', 'b_3_9', 'b_2_3', 'b_2_4']


With these parameters, the Symonds criterion (see SymondsTest()) has a chance to apply in degrees strictly greater than $$0 + 0 + 3 + 2 + 2 + 1 + 1 = 9$$. However, in this example we could do better, with the Hilbert–Poincaré criterion and an existence proof of parameters over a finite extension field. Again, since the test would take a very long time, we remove it from our test suite.

sage: H.parameter_degrees_over_field_extension()    # not tested
((4, 2, 1, 3), 3, True)


This would indeed take so long that in practical computations one would be better off to apply an easier completeness criterion in higher degree see below.

Anyway, there is a finite extension field over which there is some hsop in degrees 4, 2, 1, and 3, the depth of the cohomology ring is at least three, and our heuristics did not find parameters in these degrees, i.e., we use an existence result of parameters over a finite extension field. Since $$4 + 2 + 1 + 3 - 3 = 7$$, we still can not prove completeness of the current degree six ring approximation, and thus compute the next degree. In order to avoid automatic application of a completeness criterion, we use the method next(). There are no further relations in degree 7, but finally the Poincaré series satisfies the condition of the completeness criterion:

sage: H.next()
sage: H.knownDeg
7
sage: H.last_interesting_degree()
6
sage: p = H.poincare_series()
sage: (p*(1-t^4)*(1-t^2)*(1-t)*(1-t^3)).denominator()
1
sage: H.knownDeg > (p*(1-t^4)*(1-t^2)*(1-t)*(1-t^3)).numerator().degree()
True


Thus the Hilbert–Poincaré criterion proves the completeness of the ring approximation, using parameters (over an extension field) in degrees 4, 2, 1, and 3.

It should be noted that the above example was rather artificial and does not show how one should compute a cohomology ring. So, in a last step, we compute the same ring again from scratch using the default algorithms.

sage: CohomologyRing.doctest_setup()
sage: Hdefault = CohomologyRing(384, 5602, prime=2, from_scratch=True)
sage: Hdefault.make()
sage: H == Hdefault
True
sage: Hdefault._method      # indirect doctest
'Hilbert-Poincar&eacute;'
sage: H.knownDeg
7
sage: Hdefault.knownDeg
9


The default way of computation verifies completeness only in degree 9, whereas our manual computation succeeded in degree 7. Nonetheless, the default computations is a lot faster, since the time spent to compute better parameters outweighs the time spent to compute two additional degrees of the ring structure. Interestingly, our heuristics to compute algebraically independent parameters can provide better parameters when using default algorithms, and is faster:

sage: Hdefault.parameters()
['c_4_15',
'b_1_0^2+b_2_4+b_2_3',
'b_3_9+b_3_1+b_3_0+b_2_4*b_1_0',
'b_1_1+b_1_0']

InitSubgroups()

Initialize data that are related with $$p$$-elementary abelian subgroups.

NOTE:

This method should only be of internal use.

TESTS:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(48,50,prime=2, from_scratch=True)


We destroy the subgroup information…

sage: H.subgps = None
sage: H.subg = None


… and reconstruct it:

sage: H.InitSubgroups()
sage: sorted(H.subgpDickson.items())
[((16, 14),
[D_0: 8-Cocycle in H^*(SmallGroup(16,14); GF(2)),
D_1: 12-Cocycle in H^*(SmallGroup(16,14); GF(2)),
D_2: 14-Cocycle in H^*(SmallGroup(16,14); GF(2)),
D_3: 15-Cocycle in H^*(SmallGroup(16,14); GF(2))])]
sage: sorted(H.subgps.items())
[((16, 14), H^*(SmallGroup(16,14); GF(2)))]

PrescribedRestrictions(L)

Try to construct a cochain of self that has given restrictions to the elementary abelian subgroups.

INPUT:

• L: a list of elements of the form [i,C], where
• i: the number of a special subgroup
• C: a cochain (type <MODCOCH>) of the i-th special 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, from_scratch=True)
sage: H.make(4)


We now want to construct an element of H that restricts to a Dickson element D of degree 4 in the maximal elementary abelian subgroups, which are all of rank 3.

sage: r1 = H.restriction_maps()[2][1]
sage: r2 = H.restriction_maps()[3][1]
sage: V = r1.codomain()
sage: from pGroupCohomology.cochain import MODCOCH
sage: D = MODCOCH(V,'c_1_2^4+c_1_1^2*c_1_2^2+c_1_1^4+c_1_0*c_1_1*c_1_2^2+c_1_0*c_1_1^2*c_1_2+c_1_0^2*c_1_2^2+c_1_0^2*c_1_1*c_1_2+c_1_0^2*c_1_1^2+c_1_0^4',name='D')
sage: D
D: 4-Cocycle in H^*(SmallGroup(8,5); GF(2))
sage: H.PrescribedRestrictions([[2,D],[3,D]])
(c_1_0)*(b_3_3)+((c_1_0)*(c_3_2))+((c_2_1)^2)+((c_1_0)^4): 4-Cocycle in H^*(SmallGroup(720,763); GF(2))

autosave_name()

Return the default file name for saving self.

NOTE:

The default folder is in the current workspace. The file name is derived from the given group name.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: tmp = tmp_dir()
sage: CohomologyRing.set_workspace(tmp)
sage: X = CohomologyRing(720,763,prime=2)
sage: G = libgap.SymmetricGroup(6)
sage: Y = CohomologyRing(G,prime=2,GroupName='SymmetricGroup(6)', from_scratch=True)
sage: X.autosave_name().startswith(tmp.replace('//','/'))
True
sage: X.autosave_name()
'.../H720gp763mod2.sobj'
sage: Y.autosave_name()
'.../HSymmetricGroup_6_mod2.sobj'

decomposable_classes(n, forced=False)

Vector space basis of the degree $$n$$ part of self, expressed as polynomials.

INPUT:

• n (integer): The degree to be studied.
• forced (optional boolean, default False): If True, force re-computation.

OUTPUT:

A list of degree-n elements of self that are expressed as polynomials in the generators of self and form a vector space basis for the n-th cohomology group.

ASSUMPTION:

The ring structure must be known at least out to degree n. Otherwise, a RuntimeError is raised.

TESTS:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)


We compute the ring structure only to degree 2 and then ask for the decomposable classes in degree 3, which yields an error:

sage: H.make(2)
sage: H.decomposable_classes(3)
Traceback (most recent call last):
...
RuntimeError: Ring structure in degree 3 is not known yet


We fool H into believing that it is known in degree 3, and try again:

sage: H.knownDeg = 3
sage: sorted(H.decomposable_classes(3))
[c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]


This result is wrong, since there are further cohomology elements in degree 3. But the result is cached. So, when we now really compute the ring structure in degree 3 and ask again, we still get the wrong answer:

sage: H.knownDeg = 2
sage: H.next()
sage: sorted(H.decomposable_classes(3))
[c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]


The correct answer is given when we force re-computation, and then the correct result is in the cache:

sage: sorted(H.decomposable_classes(3,forced=True))
[b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2+c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
sage: sorted(H.decomposable_classes(3))
[b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2+c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]

dickson_in_subgroup(id)

Compute Dickson classes for an elementary abelian group, considered as subgroup of the group of self.

INPUT:

• id: the small groups address (pair of integers) of some elementary abelian subgroup of self

OUTPUT:

Let $$G$$ be the finite group whose cohomology ring self represents. The attribute subgbDickson of self is changed and contains elements of degree $$p^{r}-p^{r-i}$$ of the cohomology ring of the elementary abelian group $$V$$ described by id, where $$r$$ is the $$p$$-rank of $$G$$, and $$i = 1,...,r$$. These elements are constructed using Dickson invariants in the polynomial part of the cohomology of $$V$$.

NOTE:

For the completeness criteria we are using, it is essential to construct homogeneous systems of parameters for the ring approximation that give rise to parameters of the cohomology ring. Using simultaneous lifts of (powers of) the Dickson elements in the special subgroups found with dickson_in_subgroup, one can even find a hsop that is filter regular. However, if $$p^{r}-p^{r-i}$$ is too large, one should use find_dickson(), that avoids the construction of elements of high degrees.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(162,19,prime=3)
sage: sorted(H.subgroups().items())
[((3, 1), H^*(SmallGroup(3,1); GF(3))),
((9, 2), H^*(SmallGroup(9,2); GF(3))),
((27, 5), H^*(SmallGroup(27,5); GF(3)))]
sage: H.dickson_in_subgroup((9,2))
sage: H.dickson_in_subgroup((27,5))
sage: sorted(H.subgpDickson.items())
[((9, 2),
[D_0: 36-Cocycle in H^*(SmallGroup(9,2); GF(3)),
D_1: 48-Cocycle in H^*(SmallGroup(9,2); GF(3)),
D_2: 52-Cocycle in H^*(SmallGroup(9,2); GF(3))]),
((27, 5),
[D_0: 36-Cocycle in H^*(SmallGroup(27,5); GF(3)),
D_1: 48-Cocycle in H^*(SmallGroup(27,5); GF(3)),
D_2: 52-Cocycle in H^*(SmallGroup(27,5); GF(3))])]

duflot_regular_sequence()

Return a Duflot regular sequence.

NOTE:

A Duflot regular sequence is a sequence of elements that restricts to a regular sequence in the cohomology of the greatest central elementary abelian subgroup of a Sylow subgroup. It is known that a Duflot regular sequence of length equal to the rank of the centre of a Sylow subgroup exists.

A Duflot regular sequence is actually regular, but in general the length of a maximal regular sequence exceeds the length of a Duflot regular sequence.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: X = CohomologyRing(720,763,prime=2)
sage: X.make()
sage: X.duflot_regular_sequence()
['c_1_0', 'c_2_1']


Actually, the cohomology ring is Cohen-Macaulay, hence, we have a regular sequence of length three:

sage: X.filter_regular_parameters()
['c_1_0', 'c_2_1', 'b_3_3+c_3_2']
sage: X.a_invariants()
[-Infinity, -Infinity, -Infinity, -3]


However, this regular sequence is not Duflot regular, because the restriction to the first special subgroup, which is the greatest central elementary abelian subgroup of the Sylow subgroup, does not form a regular sequence:

sage: from pGroupCohomology.cohomology import is_filter_regular_parameter_system
sage: r = X.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: rest = [r(X(p)).as_polynomial() for p in X.filter_regular_parameters()]; rest
['c_1_0', 'c_1_1^2', 'c_1_0*c_1_1^2']
sage: singular(r.codomain()).set_ring()


The fact that the annulator of the last parameter has dimension one in degrees zero and one means that the last parameter is filter regular, but not regular.

sage: is_filter_regular_parameter_system(‘std(0)’, rest) [[0], [0], [1, 1], [1, 1]]

Often, a Duflot regular sequence can be formed by generators of the cohomology ring. Actually, to some extent this is how the generators are chosen. However, in general the Duflot regular elements returned by this method are not generators:

sage: H = CohomologyRing(48,50, prime=2)
sage: H.make()
sage: H.duflot_regular_sequence()
['c_2_3', 'c_2_2', 'c_3_1', 'c_3_7+(c_3_0)']

element_as_polynomial(c)

Express an element of self as a polynomial in the generators.

INPUT:

c of type MODCOCH: An element of self

OUTPUT:

c, after changing its name so that it describes c as a polynomial.

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.1*H.2+H.3+H.4
sage: c.setname('foobar')
sage: c
foobar: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))
sage: H.element_as_polynomial(c)
b_3_3+c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))
sage: c
b_3_3+c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))

find_relations(n, rank=None)

Determine cohomology relations and optionally a basis for the decomposable subspace in a given degree.

INPUT:

• n (integer): The degree to be studied.
• rank (optional integer, default None): The dimension of the n-th cohomology group (if this happens to be known).

OUPUT:

The relation ideal in the underlying Singular session is updated, and two lists D and R are returned, where D can also be None.

If the optional parameter rank is provided, then it will be assumed that it is the dimension of the n-th cohomology group (considered as a vector space). If it is found that all stable elements in the cohomology of the underlying subgroup are decomposable and if rank is None, then D is None, indicating that the cohomology ring being studied has no minimal generator in degree n. Otherwise, D is a list of MODCOCH providing a basis for the decomposable subspace of the $$n$$-th cohomology group.

The list R provides algebraic relations in degree n that hold between the cohomology generators.

NOTE:

This method should only be of internal use. The relation ideal in the Singular interface is updated (since it reduces traffic in the interface if this is done as soon as the relations are computed), but the list of relations is not updated. This may yield unexpected behaviour.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)


There are no generators yet, and by consequence there are no decomposable elements or relations:

sage: H.find_relations(1)
([], [])


After computing degree 1, it turns out that the only decomposable element (i.e., an element that can be expressed as a polynomial of previously found generators) is the degree-1 generator, and there are of course no relations:

sage: H.make(1)
sage: H.find_relations(1)
([c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2))], [])


We happen to know that the dimension of $$H^2$$ is two. So, in degree two, the decomposable elements are returned, since there will be a generator in that degree:

sage: H.find_relations(2, rank=2)
([c_1_0^2: 2-Cocycle in H^*(SmallGroup(720,763); GF(2))], [])


We happen to know that the last generator is in degree three, while the dimension of $$H^6$$ is ten. There is a relation in degree six. Since there are no generators in degree six, the decomposable subspace is not provided:

sage: H.make(3)
sage: H.find_relations(6, rank=10)
(None, ['b_3_3*c_3_2+c_2_1*c_1_0*b_3_3'])


The ideal in the Singular session is updated, but the list of relations isn’t:

sage: H.rels()
[]
sage: H.set_ring()
sage: H.relation_ideal()
b_3_3*c_3_2+c_2_1*c_1_0*b_3_3


Therefore, when we now repeat the quest for relations, we don’t find any. However, this method can still be used for getting the decomposable subspace, by dropping the optional parameter:

sage: H.find_relations(6)
([c_1_0^3*b_3_3: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2^2+c_2_1*c_1_0*c_3_2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
b_3_3^2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_2_1*c_1_0*b_3_3: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2^2+c_2_1*c_1_0*c_3_2+c_1_0^3*c_3_2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2^2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2^2+c_2_1^2*c_1_0^2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_2_1*c_1_0^4: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
b_3_3^2+c_3_2^2+c_2_1*c_1_0*c_3_2+c_2_1^3: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2^2+c_2_1^2*c_1_0^2+c_1_0^6: 6-Cocycle in H^*(SmallGroup(720,763); GF(2))],
[])

generator_degbound()

Find a bound for the degree of cohomology generators.

THEORY:

IF H is a modular cohomology ring of a non prime power group, computed as a sub-ring of H.subgroup_cohomology(), then the latter is a finitely generated module over the former, via the restriction map. One can show that a minimal generating set of H has degrees bounded by the maximal degree of a module generator of H.subgroup_cohomology().

OUTPUT:

None. Attributes degbound_for_gens (the currently found maximal possible degree of a generator) and all_generators_found (True, if there will be no further generators) are set, and there is some log.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: G = libgap.MathieuGroup(11)
sage: H = CohomologyRing(G,prime=2,GroupName='M11', from_scratch=True)
sage: H.make(4)
sage: CohomologyRing.global_options('info')
sage: H.generator_degbound()
H^*(M11; GF(2)):
New generators will be found at most in degree 5
sage: CohomologyRing.global_options('warn')
sage: H.degbound_for_gens
5
sage: print(H.all_generators_found)
None


So, there may be further generators in degree 5. Indeed, there are:

sage: H.make(5)
sage: H.generator_degbound()
sage: H.all_generators_found
True
sage: sorted(H.gens())
[1,
b_3_0: 3-Cocycle in H^*(M11; GF(2)),
c_4_0: 4-Cocycle in H^*(M11; GF(2)),
b_5_0: 5-Cocycle in H^*(M11; GF(2))]


These are all generators, and completeness of the ring structure is proved in degree 10:

sage: H.make()
sage: H.knownDeg
10
sage: sorted(H.gens())
[1,
b_3_0: 3-Cocycle in H^*(M11; GF(2)),
c_4_0: 4-Cocycle in H^*(M11; GF(2)),
b_5_0: 5-Cocycle in H^*(M11; GF(2))]

group()

Return a permutation group equivalent to the one defining self.

NOTE:

“Equivalent” means that mapping an initial segment of the list of generators results in a group isomorphism. It is cached. If GAP crashes, the group is reconstructed.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: X = CohomologyRing(720,763,prime=2)
sage: G = X.group()
sage: G
Group([ (1,2), (1,2,3,4,5,6) ])
sage: G is X.group()
True

make(max_deg=-1)

Compute the cohomology ring structure, either completely or out to a specific degree.

INPUT:

max_deg (optional integer): If provided, compute at most out to this degree.

EXAMPLES:

The group we are using in this example is MathieuGroup(12).

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: G = libgap.eval('Group([(1,2,3,4,5,6,7,8,9,10,11),(3,7,11,8)(4,10,5,6),(1,12)(2,11)(3,6)(4,8)(5,9)(7,10)])')
sage: H = CohomologyRing(G,prime=3,GroupName='M12', from_scratch=True)


We let compute the ring structure out to degree 16. The program tries to find parameters and tests whether there will be further generators.

sage: H.make(16)
sage: H.filter_regular_parameters()
['b_4_0^3-c_12_0', 'b_16_3-b_16_1+b_4_0^4-b_4_0*c_12_0']
sage: H.all_generators_found
True


Using make without an optional argument results in a complete computation. Completeness is proved in degree 32, which is exactly where the last relation can be found:

sage: H.make()
sage: H.completed
True
sage: H.knownDeg
32
sage: H.lastRel
32


We devise two methods to prove completeness of the ring structure for non prime power groups: The Hilbert–Poincaré criterion and the Symonds criterion. We start with Hilbert–Poincaré:

sage: p = H.poincare_series(); p
(t^24 - 2*t^23 + 3*t^22 - 3*t^21 + 5*t^20 - 6*t^19 + 7*t^18 - 7*t^17 + 9*t^16 - 9*t^15 + 12*t^14 - 11*t^13 + 12*t^12 - 11*t^11 + 12*t^10 - 9*t^9 + 9*t^8 - 7*t^7 + 7*t^6 - 6*t^5 + 5*t^4 - 3*t^3 + 3*t^2 - 2*t + 1)/(t^26 - 2*t^25 + 3*t^24 - 4*t^23 + 5*t^22 - 6*t^21 + 7*t^20 - 8*t^19 + 9*t^18 - 10*t^17 + 11*t^16 - 12*t^15 + 12*t^14 - 12*t^13 + 12*t^12 - 12*t^11 + 11*t^10 - 10*t^9 + 9*t^8 - 8*t^7 + 7*t^6 - 6*t^5 + 5*t^4 - 4*t^3 + 3*t^2 - 2*t + 1)
sage: H.parameters()
['b_4_0^3-c_12_0', 'b_16_3-b_16_1+b_4_0^4-b_4_0*c_12_0']
sage: t = p.parent().gen(0)
sage: p*(1-t^12)*(1-t^16)
t^26 + t^23 + 2*t^22 + t^21 + t^19 + 2*t^18 + 2*t^17 + 3*t^16 + 4*t^15 + 2*t^14 + 2*t^13 + 2*t^12 + 4*t^11 + 3*t^10 + 2*t^9 + 2*t^8 + t^7 + t^5 + 2*t^4 + t^3 + 1
sage: H.knownDeg >= (12 + 16) - H.depth()
True
sage: 26 <= H.knownDeg
True


The last few lines actually prove that the ring structure is complete—see HilbertPoincareTest() for the background. In this example, the Hilbert Poincaré test has actually been used when calling make():

sage: H._method
'Hilbert-Poincar&eacute;'


We have parameters in degree 12 and 16. We need to know the ring structure at least out to degree $$(12-1)+(16-1)+1=27$$, and we need to show that as a module over these parameters, the ring approximation is generated in at most the degree out to which we know the ring structure. This is indeed the case:

sage: H.knownDeg
32
sage: H.set_ring()
sage: B = (H.relation_ideal()+singular.ideal(H.parameters())).groebner().kbase()
sage: max([int(p.deg()) for p in B])
26


Given these data, it may surprise why it was needed to compute out to degree 32 and not just 27. But simply there is a relation in degree 32, and without the final relation, the module structure of the ring approximation would not be finitely generated:

sage: (singular.ideal(H.rels()[:-1])+singular.ideal(H.parameters())).groebner().GKdim()
1


TESTS:

In the following example, one of our criteria correctly determined the degree bound 19 when being called in degree 18. But after finding the last relation in degree 19, the previously obtained degree bound has not been used and the completion test has not been repeated. This is fixed now:

sage: H = CohomologyRing(1620, 244, prime=3, from_scratch=True)
sage: H.make()
sage: H.knownDeg
19
sage: print(H)
Cohomology ring of SmallGroup(1620,244) with coefficients in GF(3)
<BLANKLINE>
Computation complete
Minimal list of generators:
[a_2_1: 2-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
b_2_0: 2-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
c_4_3: 4-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_6_1: 6-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
c_8_4: 8-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
c_12_11: 12-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_1_0: 1-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_3_0: 3-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_3_1: 3-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_3_4: 3-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_7_0: 7-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_7_4: 7-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_7_5: 7-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
a_11_4: 11-Cocycle in H^*(SmallGroup(1620,244); GF(3))]
Minimal list of algebraic relations:
[a_2_1^2,
a_2_1*b_2_0,
a_2_1*a_3_0,
a_2_1*a_3_1,
a_2_1*a_3_4,
b_2_0*a_3_0,
b_2_0*a_3_4,
a_3_0*a_3_4,
a_3_1*a_3_4-a_2_1*c_4_3,
a_2_1*a_6_1,
a_2_1*a_7_0,
a_2_1*a_7_4,
a_2_1*a_7_5,
a_6_1*a_3_0,
a_6_1*a_3_1-b_2_0*a_6_1*a_1_0,
a_6_1*a_3_4,
b_2_0*a_7_5,
a_3_0*a_7_0,
a_3_0*a_7_5,
a_3_1*a_7_4-b_2_0*a_1_0*a_7_4,
a_3_1*a_7_5+a_2_1*c_8_4,
a_3_4*a_7_0,
a_3_4*a_7_4+a_2_1*c_8_4,
a_3_4*a_7_5,
b_2_0^2*a_6_1-a_3_1*a_7_0+b_2_0*a_1_0*a_7_0+c_4_3*a_6_1,
c_8_4*a_3_4+c_4_3*a_7_5,
b_2_0^2*a_7_4-c_8_4*a_3_1+c_4_3*a_7_4+b_2_0*c_8_4*a_1_0,
a_6_1^2,
a_2_1*a_11_4,
a_6_1*a_7_0,
a_6_1*a_7_4,
a_6_1*a_7_5,
a_3_0*a_11_4,
a_3_1*a_11_4-b_2_0*a_1_0*a_11_4-a_6_1*c_8_4,
a_3_4*a_11_4,
a_7_0*a_7_4+a_6_1*c_8_4,
a_7_0*a_7_5,
a_7_4*a_7_5+a_2_1*c_12_11,
c_12_11*a_3_1-c_8_4*a_7_4-b_2_0*c_12_11*a_1_0,
c_12_11*a_3_4+c_8_4*a_7_5,
b_2_0^2*a_11_4-c_8_4*a_7_0+c_4_3*a_11_4,
b_2_0^2*c_12_11-c_8_4^2+c_4_3*c_12_11,
a_6_1*a_11_4,
a_7_0*a_11_4,
a_7_4*a_11_4-a_6_1*c_12_11,
a_7_5*a_11_4,
c_12_11*a_7_0-c_8_4*a_11_4]

next(Forced=False, KeepDecomposables=False)

Compute the next degree of the cohomology ring approximation.

NOTE:

There is no comppletion test performed.

EXAMPLES:

First, we take care that the state of the cohomology rings of the elementary abelian subgroups and of the Sylow subgroup are in a well defined state, independent of the content of the local sources. In this example, we also illustrate logging.

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: X = CohomologyRing(4,2, from_scratch=True)
sage: X.make()
sage: X = CohomologyRing(8,5, from_scratch=True)
sage: X.make()
sage: X = CohomologyRing(16,11, from_scratch=True)
sage: X.make()
sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)
sage: CohomologyRing.global_options('info')
sage: H.next()
H^*(SmallGroup(720,763); GF(2)):
Computing ring approximation in degree 1
Determining stable subspace in degree 1
H^*(D8xC2; GF(2)):
Determine degree 1 standard monomials
H^*(SmallGroup(8,5); GF(2)):
Determine degree 1 standard monomials
H^*(SmallGroup(4,2); GF(2)):
Determine degree 1 standard monomials
H^*(SmallGroup(720,763); GF(2)):
Setting up conditions to determine stable elements
Solving equations
We have to choose 1 new generator in degree 1
H^*(SmallGroup(4,2); GF(2)):
Determine degree 1 standard monomials
H^*(SmallGroup(8,5); GF(2)):
Determine degree 1 standard monomials
H^*(SmallGroup(720,763); GF(2)):
> There are 0 nilpotent generators in degree 1
> There are 0 "boring" generators in degree 1
> There is 1 Duflot generator in degree 1
Try to find new Duflot-regular element in degree 1
explore_one_parameter:
1 = (2-1)^1 parameter candidates
We found a parameter.
> It is regular.
H^*(SmallGroup(720,763); GF(2)):
Found extension of the Duflot regular sequence
Degree 1 of the visible ring structure is computed!
Storing ring approximation
sage: H.next()
Computing ring approximation in degree 2
Determining stable subspace in degree 2
H^*(D8xC2; GF(2)):
Determine degree 2 standard monomials
H^*(SmallGroup(8,5); GF(2)):
Determine degree 2 standard monomials
H^*(SmallGroup(4,2); GF(2)):
Determine degree 2 standard monomials
H^*(SmallGroup(720,763); GF(2)):
Setting up conditions to determine stable elements
Solving equations
Exploring relations in degree 2
Determine degree 2 standard monomials
Express 1 standard monomial as cocycle
Found 0 relations in degree 2
We have to choose 1 new generator in degree 2
H^*(SmallGroup(4,2); GF(2)):
Determine degree 2 standard monomials
H^*(SmallGroup(8,5); GF(2)):
Determine degree 2 standard monomials
H^*(SmallGroup(720,763); GF(2)):
> There are 0 nilpotent generators in degree 2
> There are 0 "boring" generators in degree 2
> There is 1 Duflot generator in degree 2
Try to find new Duflot-regular element in degree 2
explore_one_parameter:
1 = (2-1)^1 parameter candidates
We found a parameter.
> It is regular.
H^*(SmallGroup(720,763); GF(2)):
Found extension of the Duflot regular sequence
Degree 2 of the visible ring structure is computed!
Storing ring approximation


So, apparently the stable subspace of the cohomology ring of the underlying subgroup D8xC2 is computed in each degree, then it is determined how much of it is decomposable, and new generators are chosen accordingly.

We continue the computation out to degree 5, turning off the log. There is still no relation:

sage: CohomologyRing.global_options('warn')
sage: H.make(5)
sage: print(H)
Cohomology ring of SmallGroup(720,763) with coefficients in GF(2)
<BLANKLINE>
Computed up to degree 5
Minimal list of generators:
[c_2_1: 2-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)),
b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
Minimal list of algebraic relations:
[]


Resuming logging, we compute the next degree. Meanwhile the program has tested that it found all generators. Thus, it is not needed to compute the stable subspace in advance, as can be seen in the log.

sage: CohomologyRing.global_options('info')
sage: H.next()
H^*(SmallGroup(720,763); GF(2)):
Computing ring approximation in degree 6
All generators are known
Exploring relations in degree 6
Determine degree 6 standard monomials
Express 11 standard monomials as cocycles
Found 1 relations in degree 6
There is no new generator in degree 6
Try to lift 1st power of 1st Dickson invariant
Exploring relations in degree 6
Determine degree 6 standard monomials
Express 10 standard monomials as cocycles
Found 0 relations in degree 6
Factorising an element; it can be interrupted with Ctrl-c
Degree 6 of the visible ring structure is computed!
Storing ring approximation


There is no completion test performed. But in fact, the completion test is successful:

sage: H.completed
False
sage: H.test_for_completion()
Compute dependent_parameters
Try to find a set of generators over which the cohomology ring is finite.
Computing complete Groebner basis
Trying Symonds' criterion
Successful application of the Symonds criterion
True
sage: H.completed
True

parameter_degrees_over_field_extension(forced=False)

Temporarily cached method: Returns the degrees of parameters over a field extension.

INPUT:

• forced: If True then the cache is overridden.

OUTPUT:

• A tuple of integers providing the degrees of a homogeneous system of algebraically independent parameters that exist when replacing the base field of this cohomology ring by a finite field extension.
• An integer, providing a lower bound for the depth of this cohomology ring.
• A bool, which is True if an existence proof was used, and False if the parameters have actually been constructed without extending the base field.

Three times None is returned, if no parameters could be found.

TODO:

Find a better example! Here, we do parts of the quest for parameters in a non-automatic way. This is to get a good example, in which it is possible to benefit from an existence proof of parameters over a finite extension field. However, the automatically chosen parameters happen to be good enough, so that an application of Symonds’ completeness criterion, without using an existence proof, is the easiest way to prove completeness.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(384,5602, prime=2, from_scratch=True)


In the following line, we are cheating a bit. Without it, other parameters would be found for $$H$$.

sage: H.sylow_cohomology().find_dickson()
True
sage: H.make(3)


The degree is too low, hence, no parameters can be found:

sage: H.parameter_degrees_over_field_extension()
(None, None, None)


After computing out to degree six, parameters in degrees 4, 6, 1 and 4 can be explicitly constructed:

sage: H.make(6)
sage: H.parameters()
['b_1_1^4+b_1_0^3*b_1_1+b_1_0^4+b_2_4*b_1_1^2+b_2_4*b_1_0^2+b_2_4^2+b_2_3^2',
'b_3_9^2+b_3_1^2+b_1_0*b_1_1^2*b_3_1+b_1_0^6+b_2_4*b_1_0*b_3_1+b_2_4*b_1_0*b_3_0+b_2_4*b_1_0*b_1_1^3+b_2_4*b_1_0^4+b_2_4^2*b_1_1^2+b_2_4^3+b_2_3*b_2_4^2+b_2_3^2*b_2_4',
'b_1_1+b_1_0',
'c_4_15']


But it can be shown that there exists a field extension over which there exist parameters in smaller degrees:

sage: H.sylow_cohomology().depth()
3
sage: H.parameter_degrees_over_field_extension()
((4, 1, 4, 3), 3, True)


These return values tell us that there is a finite field extension over which there exists parameters in degrees 4, 1, 4, 3, that the depth of the cohomology ring is at least three (which is the depth of the cohomology ring of a Sylow 2-subgroup), and that such low parameter degrees seem impossible to achieve without extending the base field. By the Hilbert-Poincaré criterion, we may hope to prove completeness of the ring presentation in degree $$4+1+4+3-3$$, hence, in degree 9. This is indeed possible:

sage: H.make()
sage: H.knownDeg
9
sage: H._method
'Hilbert-Poincar&eacute;'
sage: CohomologyRing.set_local_sources(False)

parameters_from_sylow_subgroup()

Try to obtain filter regular parameters from those of a Sylow subgroup.

THEORY:

In the case of a prime power group, a filter regular homogeneous system of parameters can be obtained by starting with the Duflot generators (they form a regular sequence) together with lifts of Dickson elements in the cohomology of maximal elementary abelian subgroups, restricted to a complement of the center.

For non prime power groups, the situation is more difficult. We do find a Duflot regular sequence, but it is, in general, not formed by generators — see duflot_regular_sequence(). And in general, it is impossible to lift the Dickson elements restricted to a complement of the centre of the Sylow subgroup. Therefore, the default construction of a filter regular homogeneous system of parameters relies on the Dickson elements, without restriction.

These may be of rather high degree. Therefore, we always try whether by chance the restricted Dickson elements found for the Sylow subgroup happen to be stable. If only the last parameter can not be lifted, find_small_last_parameter() may help to find a filter regular homogeneous system of parameters in small degrees.

EXAMPLE:

Since the construction depends on data in the cohomology ring of a subgroup, we ensure that this ring is not simply taken from the local sources, and compute it from scratch:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: X = CohomologyRing(64,138,from_scratch=True)
sage: H = CohomologyRing(576,204,prime=2)
sage: H.make()


In this example, all but the last parameter from the Sylow subgroup can be lifted. A last parameter can be easily found. Theorems imply that, we thus obtain a filter regular system of parameters, which we can verify:

sage: P = H.parameters_from_sylow_subgroup(); P
['c_4_6',
'b_1_0*b_3_0+b_1_0^4+b_2_2^2+b_2_0^2',
'b_3_1*b_3_2+b_3_1^2+b_3_0^2+b_1_0^3*b_3_0+b_2_2*b_1_0*b_3_0+b_2_2^2*b_1_0^2+b_2_0*b_2_2^2+b_2_0^3+c_4_6*b_1_0^2',
None]
sage: P[-1] = H.find_small_last_parameter(P)
sage: P
['c_4_6',
'b_1_0*b_3_0+b_1_0^4+b_2_2^2+b_2_0^2',
'b_3_1*b_3_2+b_3_1^2+b_3_0^2+b_1_0^3*b_3_0+b_2_2*b_1_0*b_3_0+b_2_2^2*b_1_0^2+b_2_0*b_2_2^2+b_2_0^3+c_4_6*b_1_0^2',
'b_1_0']
sage: H.raw_filter_degree_type(P)
([-1, -1, -1, 9, 11],
[[0],
[0],
[0],
[0, 0, 1, 3, 2, 4, 4, 2, 3, 1],
[1, 0, 2, 4, 2, 5, 5, 2, 4, 2, 0, 1]],
[4, 4, 6, 1])


The degrees are 4, 4, 6, 1. The degrees of the original parameters, namely obtained by unrestricted Dickson elements, are 8, 12, 14, 15, the last Dickson element being replacable by a factor in degree 1:

sage: H.find_dickson()
True
sage: H.Dickson
['b_1_0^2*b_3_0^2+b_1_0^8+b_2_2^4+b_2_0^4+c_4_6*b_1_0*b_3_0+b_2_2*c_4_6*b_1_0^2+c_4_6^2',
'b_3_1^3*b_3_2+b_1_0^3*b_3_0^3+b_1_0^6*b_3_0^2+b_6_9*b_3_0^2+b_6_9^2+b_2_2*b_1_0*b_3_0^3+b_2_2*b_6_9*b_1_0*b_3_0+b_2_2^2*b_1_0^2*b_3_0^2+b_2_2^3*b_3_0^2+b_2_2^4*b_1_0^4+b_2_0^2*b_2_2^4+b_2_0^3*b_3_1^2+b_2_0^6+c_4_6*b_1_0^2*b_3_0^2+c_4_6*b_1_0^5*b_3_0+c_4_6*b_6_9*b_1_0^2+b_2_2*c_4_6*b_1_0^6+b_2_2^2*c_4_6*b_1_0*b_3_0+c_4_6^2*b_1_0*b_3_0+c_4_6^2*b_1_0^4+b_2_2^2*c_4_6^2+b_2_0^2*c_4_6^2',
'b_1_0^5*b_3_0^3+b_6_9*b_1_0^2*b_3_0^2+b_6_9^2*b_1_0^2+b_2_2*b_1_0^3*b_3_0^3+b_2_2*b_6_9*b_1_0^3*b_3_0+b_2_2^2*b_1_0^4*b_3_0^2+b_2_2^3*b_1_0^2*b_3_0^2+c_4_6*b_1_0*b_3_0^3+c_4_6*b_1_0^4*b_3_0^2+c_4_6*b_6_9*b_1_0^4+c_4_6^2*b_3_1*b_3_2+c_4_6^2*b_3_1^2+c_4_6^2*b_3_0^2+b_2_2*c_4_6^2*b_1_0*b_3_0+b_2_2*c_4_6^2*b_1_0^4+b_2_2^2*c_4_6^2*b_1_0^2+b_2_0*b_2_2^2*c_4_6^2+b_2_0^3*c_4_6^2+c_4_6^3*b_1_0^2',
'b_1_0']

set_ring()

Set the underlying ring in the Singular interface.

TESTS:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(48,48,prime=2, from_scratch=True)
sage: H.make(2)
sage: H.set_ring()


This is the underlying ring out to degree 2:

sage: singular('basering')
polynomial ring, over a field, global ordering
// coefficients: ZZ/2
// number of vars : 3
//        block   1 : ordering M
//                  : names    c_2_3 b_1_0 c_1_1
//                  : weights      2     1     1
//                  : weights     -1     0    -1
//                  : weights     -1     0     0
//        block   2 : ordering C


There are more generators in higher degree:

sage: H.make()
sage: H.set_ring()
sage: singular('basering')
polynomial ring, over a field, global ordering
// coefficients: ZZ/2
// number of vars : 4
//        block   1 : ordering M
//                  : names    c_2_3 b_1_0 c_1_1 c_3_6
//                  : weights      2     1     1     3
//                  : weights     -1     0    -1    -1
//                  : weights     -1     0     0     0
//                  : weights      0    -1     0     0
//        block   2 : ordering C


A Groebner basis of the cohomology ring’s relation ideals is available as follows:

sage: H.relation_ideal()
b_1_0*c_3_6+c_2_3*b_1_0*c_1_1

stable_space(n)

return a basis for the subspace of stable cocycles of the underlying subgroup in a given degree.

INPUT:

n, the degree (integer)

OUTPUT:

• a list of elements (MODCOCH) of self whose restriction to the underlying subgroup yield a basis for the space of stable elements in degree n.
• a list of standard monomials of the underlying cohomology ring of a subgroup
• a list of those standard monomials of the underlying cohomology ring of a subgroup that occur as leading monomials of stable elements

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: G = libgap.MathieuGroup(11)
sage: H = CohomologyRing(G,prime=2,GroupName='M11', from_scratch=True)


It may easily be that there are no stable cocycles in a given degree:

sage: H.stable_space(1)
([], [], [])
sage: H.stable_space(2)
([], [], [])


The first stable element, yielding the first generator of H, can be found in degree 3:

sage: g,M,MS = H.stable_space(3)
sage: g
[Gen1: 3-Cocycle in H^*(M11; GF(2))]
sage: M
['b_3_0', 'b_1_0^3']
sage: M == H._HP.standard_monomials(3)
True
sage: g[0].val_str()
'b_3_0'


Here, the stable element of H._HP happens to be a monomial. This is not always the case:

sage: g,M,MS = H.stable_space(4)
sage: g[0].val_str()
'b_1_0^4+c_4_2'
sage: MS
['b_1_0^4']

stable_to_polynomial(c, verify=True)

Express a stable cohomology element of a subgroup as a polynomial in the generators of self.

INPUT:

• c: an element of self or of the cohomology ring of one of the subgroups used to compute self.
• verify (optional boolean): If true (default), test whether c really is stable, before trying to express it in self.

OUTPUT:

An element of self (type MODCOCH) corresponding to c, or None if c is not stable and if verify is true. If c is not stable and verify is not true, then an error is raised.

EXAMPLES:

We work with the mod-2 cohomology of the Mathieu group $$M_{12}$$.

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()   # Reset and disallow web access
sage: G = libgap.eval('Group([(1,2,3,4,5,6,7,8,9,10,11), (3,7,11,8)(4,10,5,6), (1,12)(2,11)(3,6)(4,8)(5,9)(7,10)])')
sage: H = CohomologyRing(G,prime=2,GroupName='M12', from_scratch=True)
sage: H.make()
sage: HS = H.sylow_cohomology()
sage: HU = H.subgroup_cohomology()


We first consider elements of HS and HU that are stable:

sage: H.stable_to_polynomial(HS('b_1_2^6+b_1_1^2*b_1_2^4+b_1_1^6+b_2_4^2*b_1_1*b_1_2+b_2_4^3'))
b_3_0*b_3_1+b_2_0^3: 6-Cocycle in H^*(M12; GF(2))
sage: H.stable_to_polynomial(HU('b_2_0*b_2_2*b_3_4+c_4_6*b_3_1'))
c_4_0*b_3_1: 7-Cocycle in H^*(M12; GF(2))


An element of H is simply expressed as a polynomial, changing its name accordingly:

sage: cG = H.1*H.2+H.3+H.4*H.5
sage: cG.setname('foobar')
sage: cG
foobar: 6-Cocycle in H^*(M12; GF(2))
sage: H.stable_to_polynomial(cG)
b_3_0*b_3_1+b_6_3+b_2_0*c_4_0: 6-Cocycle in H^*(M12; GF(2))
sage: cG
b_3_0*b_3_1+b_6_3+b_2_0*c_4_0: 6-Cocycle in H^*(M12; GF(2))


By default, it is tested whether the input is stable. If it isn’t, it is stated in the log, and None is returned.

sage: cS2 = HS('b_2_4^2*b_1_1*b_1_2+b_2_4^2*b_2_5+b_2_4^3+c_4_14*b_1_2^2')
sage: CohomologyRing.global_options('debug')
sage: print(H.stable_to_polynomial(cS2))
H^*(M12; GF(2)):
Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
H^*(SmallGroup(192,1494); GF(2)):
Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
Stability condition #0 is violated
None
sage: CohomologyRing.global_options('warn')
sage: cS3 = HS('c_4_14*b_1_0')
sage: CohomologyRing.global_options('debug')
sage: print(H.stable_to_polynomial(cS3))
H^*(M12; GF(2)):
Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
H^*(SmallGroup(192,1494); GF(2)):
Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
Input is indeed stable in this ring...
H^*(M12; GF(2)):
Stability condition #0 is violated
None
sage: CohomologyRing.global_options('warn')


According to the log, cS3 can be expressed in HU (not in H, however), and indeed:

sage: HU.stable_to_polynomial(cS3)
c_4_6*b_1_0: 5-Cocycle in H^*(SmallGroup(192,1494); GF(2))


Using the option verify=False will be a little faster, since it is not verified whether the input is stable before trying to lift. If it isn’t, an error is raised.

sage: HU.stable_to_polynomial(cS3, verify=False)
c_4_6*b_1_0: 5-Cocycle in H^*(SmallGroup(192,1494); GF(2))
sage: H.stable_to_polynomial(cS3, verify=False)
Traceback (most recent call last):
...
ValueError: Apparently the given cochain does not belong to H^*(M12; GF(2))

subgroup()

Return the subgroup to which the stable element method is applied.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(1440,80,prime=2)
sage: H.subgroup().IdGroup()
[ 288, 46 ]
sage: H.subgroup_cohomology()
H^*(SmallGroup(288,46); GF(2))
sage: H.group().IsSubgroup(H.subgroup())
true
sage: H.subgroup().IsSubgroup(H.sylow_subgroup())
true

subgroup_cohomology()

Return the cohomology of the subgroup to which the stable element method is applied.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: tmp = tmp_dir()
sage: CohomologyRing.set_workspace(tmp)
sage: H = CohomologyRing(1440,80,prime=2)
sage: H.subgroup().IdGroup()
[ 288, 46 ]
sage: H.subgroup_cohomology()
H^*(SmallGroup(288,46); GF(2))
sage: H.group().IsSubgroup(H.subgroup())
true
sage: H.subgroup().IsSubgroup(H.sylow_subgroup())
true

sylow_cohomology()

Return the cohomology ring of a Sylow subgroup.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(1440,80,prime=2)
sage: H.sylow_subgroup().IdGroup()
[ 32, 3 ]
sage: H.sylow_cohomology()
H^*(SmallGroup(32,3); GF(2))

sylow_subgroup()

Return the Sylow subgroup which is used to compute self

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(1440,80,prime=2)
sage: H.sylow_subgroup().IdGroup()
[ 32, 3 ]
sage: H.sylow_cohomology()
H^*(SmallGroup(32,3); GF(2))
sage: H.group().IsSubgroup(H.sylow_subgroup())
true

test_for_completion(forced=False)

Perform completion tests.

OUTPUT:

True (complete), False (incomplete), None (can’t be decided yet) The attribute completed is set accordingly.

NOTE:

This method first invokes generator_degbound() to test whether all generators are known. If this is the case, the last degree of relations is estimated. Eventually, either SymondsTest() or HilbertPoincareTest() is called.

EXAMPLES:

This example shows what happens behind the scenes when H.make() is called. We use MathieuGroup(11).

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: G = libgap.MathieuGroup(11)
sage: H = CohomologyRing(G,prime=2,GroupName='M11', from_scratch=True)
sage: H.make(3)
sage: H.test_for_completion()
False


The reason is that there is no maximal Duflot regular sequence yet:

sage: H.duflot_regular_sequence()
[]


So, we proceed to degree 4:

sage: H.next()
sage: H.duflot_regular_sequence()
['c_4_0']


We have a Duflot regular sequence, but it is possible that there are more generators in degree 5:

sage: CohomologyRing.global_options('info')
sage: H.test_for_completion()
H^*(M11; GF(2)):
Try to find a bound for the degree of generators
> New generators will be found at most in degree 5
False


In degree 5, it turns out that parameters can be found. But, since we expect a relation at least in degree 10, the completion criterion is still not invoked. However, there are now nice filter regular parameters:

sage: CohomologyRing.global_options('warn')
sage: H.next()
sage: CohomologyRing.global_options('info')
sage: H.test_for_completion()
H^*(M11; GF(2)): We expect a relation in degree at least 10
sage: H.filter_regular_parameters()
Compute filter_regular_parameters
Trying to lift the parameters of H^*(SD16; GF(2))
H^*(SmallGroup(48,29); GF(2)):
Exploring relations in degree 1
Determine degree 1 standard monomials
Express 1 standard monomial as cocycle
Found 0 relations in degree 1
H^*(M11; GF(2)):
One parameter could not be lifted
Testing whether parameters of the cohomology ring can be found
> Yes
Compute find_small_last_parameter
Computing complete Groebner basis
Compute _parameter_restrictions
Induced homomorphism of degree 0 from H^*(M11; GF(2)) to H^*(SmallGroup(4,2); GF(2)):
Compute restricted parameters
H^*(M11; GF(2)):
Compute _get_obvious_parameter
Compute _parameter_restrictions
compute radicals of restricted parameter ideal
Compute _parameter_restrictions
Induced homomorphism of degree 0 from H^*(M11; GF(2)) to H^*(SmallGroup(4,2); GF(2)):
Compute restricted parameters
H^*(M11; GF(2)):
Determine degree 1 standard monomials
Compute _get_obvious_parameter
Determine degree 2 standard monomials
Compute _get_obvious_parameter
Determine degree 3 standard monomials
--> Last parameter found in degree 3
['c_4_0', 'b_3_0']


We continue out to degree 10, and then test again. In this case, the Symonds criterion is chosen for the test:

sage: CohomologyRing.global_options('warn')
sage: H.next()
sage: H.next()
sage: H.next()
sage: H.next()
sage: H.next()
sage: CohomologyRing.global_options('info')
sage: H.test_for_completion()
H^*(M11; GF(2)):
Compute dependent_parameters
Try to find a set of generators over which the cohomology ring is finite.
Computing complete Groebner basis
Trying Symonds' criterion
Successful application of the Symonds criterion
True
sage: CohomologyRing.global_options('warn')
sage: H.completed
True


In the following example, it occurs that the ring approximation out to degree 10 does contain elements that give rise to parameters for the cohomology ring:

sage: H = CohomologyRing(864*2,206,prime=2)
sage: H.make(10)
sage: H.verify_parameters_exist()
True
sage: H.dependent_parameters()
['b_1_0', 'c_6_13', 'c_4_5', 'c_2_1']


But the dependent parameters of the ring approximation are not enough to apply the Symonds criterion:

sage: H.SymondsTest(H.dependent_parameters(), [1,6,6,4,2]) is None
True


In fact, it turns out that the simultaneous lifts of Dickson invariants, that are guaranteed to yield parameters of the cohomology ring, are not parameters of the ring approximation:

sage: H.find_dickson()
True
sage: H.Dickson
['...b_1_0^8+...',
'...c_4_5^2*b_1_0^4+...',
'...c_2_1*c_6_12^2+...',
'b_1_0']
sage: H.set_ring()
sage: singular.ideal(H.Dickson+H.rels()).groebner().dim() > 0
True


we can find smaller elements that are guaranteed to yield parameters of the complete cohomology ring, but of course the ring approximation is not complete yet:

sage: H.parameters()
['c_2_1', 'c_4_5', 'c_6_13', 'b_1_0']
sage: H.test_for_completion()
False


It turns out that the last relation is in fact found in degree 12, and then of course the complete cohomology ring is finite over both the elements obtained from the Dickson invariants and the system of parameters in smaller degrees:

sage: H.make()
sage: H.last_interesting_degree()
12
sage: H.rels()[-1]
'...c_6_12^2+...'
sage: H.parameters()
['c_2_1', 'c_4_5', 'c_6_13', 'b_1_0']
sage: H.set_ring()
sage: singular.ideal(H.Dickson+H.rels()).groebner().dim()
0
sage: singular.ideal(H.parameters()+H.rels()).groebner().dim()
0

pGroupCohomology.modular_cohomology.MODCOHO_unpickle(*L)

COHO_unpickle.

TESTS:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)
sage: H.make(3)
sage: H is loads(dumps(H)) #indirect doctest
True