# Constructing Cohomology Rings¶

AUTHORS:

This module provides a constructor for modular cohomology rings of finite groups, that takes care of caching. The constructor is an instance CohomologyRing() of the class CohomologyRingFactory.

pGroupCohomology.factory.CohomologyRing(*args, **kwds)

Constructor for modular cohomology rings of finite groups.

This constructor is an instance of CohomologyRingFactory. See there and see pGroupCohomology for more examples.

The constructor can be called directly. Then, it is first checked whether the completely computed cohomology ring of the given group is part of some database, or whether it can be downloaded. If this is not the case, a new cohomology ring is created, being part of the user’s workspace.

Using set_workspace(), the location of the user’s workspace can be changed. By from_workspace(), one can explicitly ask for taking data from the workspace. The input formats for calling CohomologyRing() and for calling from_workspace() or from_local_sources() are the same.

INPUT:

Parameters describing the group

• A finite group $$G$$ , either
• given by an integer q and a positive number n, determining an entry of the SmallGroups library, or
• given as an object in the libgap interface
• GroupName (optional string): a name for the group. If the group $$G$$ is given in the Gap interface and if it is not provided with a custom name (using libGap’s SetName) then GroupName must be provided.
• GroupDescr (optional string): a description of the group. This can be any string, and is used when printing the cohomology ring or creating a web-site for it.
• If the group is not of prime power order, the optional parameter prime must be set to a prime number.

Parameters describing the database

• websource: If it is False, it is not attempted to download data from a web repository. If it is a URL (string) or tuple of URLs providing the location(s) of a database in the web, then it is attempted to download the data from there. If websource is not given then first it is tried to look up data in the local file system, and if this fails then it is attempted to download the data from some default location in the web.
• from_scratch (default False): If it is True, this cohomology ring may be taken from the cache or from the workspace, but will not be copied from local or remote sources. Note that this will only take effect on this single ring; cohomology rings of subgroups, occuring during the computation, will still be loaded.

Parameters modifying the algorithm

• useElimination (optional, default None): If True, the elimination method is used for trying to construct the Dickson classes. If False, the linear algebra method is used for that purpose. By default, the linear algebra method is chosen, unless there is a Dickson class in degree greater than 18 (for prime power groups) or 20 (for non prime power groups).
• DicksonExp (optional integer, default = 3): If the elimination method for finding the Dickson classes is used, it is needed to set a bound for the power to which the Dickson classes might be raised: If $$G$$ is a $$p$$-group and $$n$$ is the given DicksonExp, then the Dickson classes of the elementary abelian sub-groups of $$G$$ are raised to the power of $$p^0,p^1,...,p^n$$ before trying to simultaneously lift them to $$G$$. We do not know any example in which the default value would not suffice.
• useFactorization (optional boolean, default True): Try to replace the Dickson classes of $$G$$ by their minimal non-constant factors. This may simplify some computations, but there are rare examples in which the factorisation is a bigger problem than a high degree bound.
• auto (optional integer, default = 2 for abelian groups, and = 4 otherwise): Only applies to the case of prime power groups. A quick but potentially memory consuming method for lifting chain maps will be used in degree at most auto. For prime power groups up to orders around 500, the default value seems to be heuristically best.
• useSlimgb / useStd (optinal boolean): Use Singular’s slimgb (resp. std) for computing the Groebner basis of the relation ideal. If not specified, Singular’s groebner method is chosen, which uses a heuristics to find the best algorithm for the computation of the Groebner basis.

Global options

• options (optional string or list of strings): set/unset global options, or a dictionary that the global options are updated with.

There are various global options—they apply to all cohomology rings. Each option is set by a string, and unset by prepending 'no' to that string.

Available options

• 'warn' [default], 'info', 'debug', logging level
• 'useMTX' [default], use Matrix_gfpn_dense matrices for linear algebra over finite fields, which rely on SharedMeatAxe. Note that the resolutions will always be computed using the SharedMeatAxe. By consequence, if useMTX is turned off, time is wasted for conversions between different matrix types.
• 'save' [default], automatically save ring approximations, which comes in very handy when a long computation needs to be interrupted at some point; that’s why it is the default. Note that many data, including a minimal projective resolution for prime power groups, will always be stored on disk.
• 'sparse' [not default], remove temporarily unneeded data on the resolution from memory. With that option, the computation of very large examples becomes more feasible.

Further options have a numerical value:

• autolift [default=1]: Degree up to which cochains are lifted using the autolift (as opposed to the Urbild Gröbner basis) method. Only applies to groups that are not elementary abelian.
• autoliftElAb [default=0]: The same as autolift, but for elementary abelian groups.
• SingularCutoff [default=70]: This determines how commands for Singular are cut into pieces, in order to reduce the overhead of the pexpect interface.
• NrCandidates [default=1000]: Maximal number of candidates that are considered when trying to find special elements (e.g., parameters) by enumeration.

In experiments with unit_test_64(), the different options had the following effect:

• With options="nouseMTX", the computation time slightly increases.
• With options="sparse", the computation time increases.
• With options="nosave", the computation time decreases.

The options can also be (un)set later, by using the method global_options().

class pGroupCohomology.factory.CohomologyRingFactory

A factory for creating modular cohomology rings of finite p-groups as unique parent structures

Please use CohomologyRing(), which is an instance of this class, and is provided with a documentation of the available options.

TESTS:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H0 = CohomologyRing(8,3)   #indirect doctest
sage: print(H0)
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]

check_arguments(args, minimal_generators=None, GroupId=None)

Return group order and a group in GAP with generating set suitable for the computations

INPUT:

• args: A list, either formed by a group in GAP or by two integers, providing an address in the SmallGroups library.
• minimal_generators: (optional bool) If it is true, it is asserted by the user that an initial segment of the given list of generators of the group froms a minimal generating set.
• GroupId: (optional) Pair of numbers, providing the address of the given group in the SmallGroups library, if this happens to be known to the user.

OUTPUT:

• The group order, and

NOTE:

• It only matters in the case of prime power groups whether or not the given list of generators starts with a minimal generating set.
• If the optional argument GroupId is provided, it is verified whether the group from the SmallGroups library is equivalent to the given group.

EXAMPLE:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.check_arguments([8,3])
(8, <pc group of size 8 with 3 generators>)
sage: CohomologyRing.check_arguments([libgap.eval('DihedralGroup(8)')])
(8, Group([ (1,2)(3,8)(4,6)(5,7), (1,3,4,7)(2,5,6,8) ]))
sage: CohomologyRing.check_arguments([libgap.eval('DihedralGroup(8)')], GroupId=[8,3])
Traceback (most recent call last):
...
ValueError: The given group generators are not canonically isomorphic to SmallGroup(8,3)

create_group_key(G, GroupId=None, GroupDefinition=None)

Return data that allow to determine a given group up to equivalence.

NOTE:

For our package, a group is always supposed to be provided with a fixed list of generators. Two groups are equivalent if there exists a group homomorphism that sends the list of generators of one group to an initial segment of the list of generators of the other group. The ring presentation of a cohomology ring of a group, as computed with this package, only depends on the group’s equivalence class.

This is nothing more than an auxiliary method.

INPUT:

• G - a list, either formed by two integers representing an address in the SmallGroups library, or formed by a group in the libGAP interface.
• GroupId - optional list of two integers, that is supposed to provide the address of a group in the SmallGroups library equivalent to the group given by G.
• GroupDefinition - optional string, that is supposed to be evaluated in the libGAP interface, yielding a group that is equivalent to the group given by G

OUTPUT:

• If GroupDefinition is provided, it is returned.
• If the given group is equivalent to a group in the SmallGroups library whose address is either given or can be determined by GAP, then this address (a pair of integers) is returned.
• Otherwise, if the group is not a permutation group, it is transformed into an equivalent permutation group (using the regular permutation action). Then, a string representation of that permutation group is returned.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing(8,3)
sage: H.group()
Group([ (1,2)(3,8)(4,6)(5,7), (1,3)(2,5)(4,7)(6,8) ])
sage: CohomologyRing.create_group_key([H.group()])
(8, 3)


By consequence, the cohomology rings of SmallGroup(8,3) and the permutation group above are identic:

sage: H is CohomologyRing(libgap.eval('SmallGroup(8,3)'))
True
sage: H is CohomologyRing(H.group())
True


However, defining the dihedral group differently, we obtain a different equivalence class, and thus a different result:

sage: CohomologyRing.create_group_key([libgap.eval('DihedralGroup(8)')])
('Group([(1,2)(3,8)(4,6)(5,7),(1,3,4,7)(2,5,6,8)])',)


So, the given group is transformed into an equivalent permutation group. If we start with a big transformation group, a string representation obtained from its list of generators is returned:

sage: CohomologyRing.create_group_key([libgap.eval('SymmetricGroup(8)')])
('Group([(1,2,3,4,5,6,7,8),(1,2)])',)


It is possible to provide a reasonable string representation or a SmallGroups address. However, it is the user’s responsibility to choose values that match the given group - this is not verified, as can be seen in the final example:

sage: CohomologyRing.create_group_key([libgap.eval('SymmetricGroup(8)')],GroupDefinition='SymmetricGroup(8)')
'SymmetricGroup(8)'
sage: CohomologyRing.create_group_key([libgap.eval('SymmetricGroup(8)')],GroupId=[20,2])
(20, 2)


TEST:

It is important that the group key is not formed by two integers in the libGAP interface. Namely, when storing the resulting ring, it could not easily be unpickled (actually it can be unpickled, but this involves some trickery, and it is certainly better to not rely on trickery). Here, we demonstrate that the given keys are correctly converted:

sage: CohomologyRing.set_workspace(tmp_dir())
sage: X = CohomologyRing(libgap(8),libgap(3), from_scratch=True)
sage: type(X._key[0][0])
<type 'sage.rings.integer.Integer'>

doctest_setup()

Block web access and put the workspace into a temporary directory.

This is essential when doctesting computations that would access web repositories of cohomology data.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.reset()
sage: from pGroupCohomology.cohomology import COHO
sage: COHO.remote_sources
('http://cohomology.uni-jena.de/db/',)
sage: CohomologyRing.doctest_setup()
sage: COHO.remote_sources
()

from_local_sources(*args, **kwds)

Retrieve/create a cohomology ring in the local sources

NOTE:

• The local sources can be chosen using set_local_sources().
• Write permissions to the local sources are required in this method.
• All subsequent computations will modify data in the local sources, until CohomologyRing.set_local_sources(False) is used.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: tmp_priv = tmp_dir()
sage: tmp_publ = tmp_dir()
sage: CohomologyRing.set_workspace(tmp_priv)


We demonstrate how to put data into the local sources:

sage: CohomologyRing.set_local_sources(tmp_publ)
sage: H1 = CohomologyRing(8,3)
sage: H1.root.startswith(os.path.realpath(tmp_publ))
True


After unsetting it, the user’s workspace is used instead:

sage: CohomologyRing.set_local_sources(False)
sage: H2 = CohomologyRing(8,4)
sage: H2.root.startswith(os.path.realpath(tmp_priv))
True


But it is possible to access the local sources directly:

sage: H3 = CohomologyRing.from_local_sources(8,2)
sage: H3.root.startswith(os.path.realpath(tmp_publ))
True

from_remote_sources(GStem, websource=None, prime=None)

Import a cohomology ring from a web source.

NOTE:

Usually this function would not be directly used. It is automatically called by CohomologyRing() if a cohomology ring can not be found in a local folder.

INPUT:

• GStem, a string so that GStem+'.tar.gz' can be found in the web source, if it is a prime power group, or 'H'+GStem+'mod%d.sobj'%prime otherwise.
• websource: If None (default), the currently known URLs of web repositories (those provided by set_remote_sources()) are chosen. If False, no remote source is used. Otherwise, it should be a single URL (string) or tuple of URLs.
• prime: An optional prime, the modulus of the cohomology ring. It must be provided if ond only if the group is not a prime power group.

NOTE:

During doctests, the web access is usually switched off,

TESTS:

We choose a low logging level, so that it is visible what happens behind the scenes.

sage: from pGroupCohomology import CohomologyRing
sage: from sage.env import SAGE_SHARE
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: CohomologyRing.global_options('info')


During package installation, and thus also during its doctests, web access is blocked. Therefore, we simulate a data base using local files that are available during package installation:

sage: H = CohomologyRing.from_remote_sources('8gp3', websource='file://'+os.path.join(os.path.realpath(os.path.curdir),'test_data'))
from_remote_sources:
Accessing web
Press Ctrl-c to interrupt web access.
Resolution of GF(2)[8gp3]:
> rk P_02 =   3
> rk P_03 =   4
H^*(D8; GF(2)):
Import monomials
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]

from_subgroup_tower(*args, **kwds)

Given a tower of subgroups starting with a Sylow subgroup, compute a cohomology ring with stability conditions associated with that subgroup.

INPUT:

• Some nested groups ascendingly sorted starting with a prime power group
• Keyword arguments similar to the ones of :class: ~pGroupCohomology.factory.CohomologyRingFactory.

OUTPUT:

The cohomology of the last of the given subgroups (without computing the ring structure).

EXAMPLES:

Notmally, we compute the mod-$$p$$ cohomology of a finite non-primepower group $$G$$ as a subring of the cohomology ring of $$N_G(Z(Syl_p(G)))$$, which in turn is computed as a subring of the cohomology ring of $$Syl_p(G)$$. If one wants to compute the cohomology of $$G$$ using a different subgroup tower, this method can be used. The computation of the mod-$$2$$ cohomology of the third Conway group, for example, was possible using a tower of four subgroups, which reduced the total number of stability conditions to $$11$$. In the following example, we do the opposite and compute the cohomology ring of the alternating group of rank $$8$$ without an intermediate subgroup.

But first, we compute the cohomology in the default way:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()
sage: A8 = libgap.AlternatingGroup(8)
sage: SylA8 = A8.SylowSubgroup(2).MinimalGeneratingSet().Group()
sage: HA8 = CohomologyRing(A8, prime=2, GroupName="A_8")
sage: HA8.make()


Here is the non-standard way:

sage: HA8_direct = CohomologyRing.from_subgroup_tower(SylA8, A8, GroupName="A8", GroupDescr='AlternatingGroup(8)')
sage: HA8_direct.make()


Apparently, the ring structures thus computed look different:

sage: print(HA8)
Cohomology ring of A_8 with coefficients in GF(2)
<BLANKLINE>
Computation complete
Minimal list of generators:
[b_2_0: 2-Cocycle in H^*(A_8; GF(2)),
c_4_1: 4-Cocycle in H^*(A_8; GF(2)),
b_6_1: 6-Cocycle in H^*(A_8; GF(2)),
b_6_2: 6-Cocycle in H^*(A_8; GF(2)),
b_3_0: 3-Cocycle in H^*(A_8; GF(2)),
b_3_1: 3-Cocycle in H^*(A_8; GF(2)),
b_5_2: 5-Cocycle in H^*(A_8; GF(2)),
b_7_5: 7-Cocycle in H^*(A_8; GF(2)),
b_7_6: 7-Cocycle in H^*(A_8; GF(2))]
Minimal list of algebraic relations:
[b_3_0*b_3_1,
b_3_0*b_5_2,
b_2_0*b_7_5,
b_2_0*b_7_6,
b_6_1*b_3_0,
b_6_2*b_3_0,
b_3_0*b_7_5,
b_3_0*b_7_6,
b_3_1*b_7_5,
b_3_1*b_7_6,
b_5_2^2+b_2_0*b_3_1*b_5_2+b_2_0^2*b_6_2+c_4_1*b_3_1^2,
b_6_1*b_6_2+b_6_1^2+b_2_0^2*b_3_1*b_5_2+b_2_0^3*b_6_2+c_4_1*b_3_1*b_5_2+b_2_0*c_4_1*b_3_1^2+b_2_0*c_4_1*b_6_2,
b_5_2*b_7_5,
b_5_2*b_7_6,
b_6_1*b_7_6+b_6_1*b_7_5,
b_6_2*b_7_5+b_6_1*b_7_5,
b_7_5*b_7_6+b_7_5^2]
sage: print(HA8_direct)
Cohomology ring of AlternatingGroup(8) with coefficients in GF(2)
<BLANKLINE>
Computation complete
Minimal list of generators:
[b_2_0: 2-Cocycle in H^*(A8; GF(2)),
c_4_1: 4-Cocycle in H^*(A8; GF(2)),
b_6_3: 6-Cocycle in H^*(A8; GF(2)),
b_6_5: 6-Cocycle in H^*(A8; GF(2)),
b_3_0: 3-Cocycle in H^*(A8; GF(2)),
b_3_1: 3-Cocycle in H^*(A8; GF(2)),
b_5_1: 5-Cocycle in H^*(A8; GF(2)),
b_7_5: 7-Cocycle in H^*(A8; GF(2)),
b_7_6: 7-Cocycle in H^*(A8; GF(2))]
Minimal list of algebraic relations:
[b_3_0*b_3_1,
b_3_1*b_5_1,
b_2_0*b_7_5,
b_2_0*b_7_6,
b_6_3*b_3_1+b_2_0*c_4_1*b_3_1,
b_6_5*b_3_1,
b_3_0*b_7_5,
b_3_0*b_7_6,
b_3_1*b_7_5,
b_3_1*b_7_6,
b_5_1^2+b_2_0*b_3_0*b_5_1+b_2_0^2*b_6_5+c_4_1*b_3_0^2,
b_3_0^4+b_6_5*b_3_0^2+b_6_3*b_6_5+b_6_3^2+b_2_0^2*b_3_0*b_5_1+b_2_0^3*b_6_5+c_4_1*b_3_0*b_5_1+b_2_0*c_4_1*b_3_0^2+b_2_0^2*c_4_1^2,
b_5_1*b_7_5,
b_5_1*b_7_6,
b_6_3*b_7_6+b_6_3*b_7_5,
b_6_5*b_7_5+b_6_3*b_7_5,
b_7_5*b_7_6+b_7_5^2]


But of course the two rings are isomorphic:

sage: HA8.is_isomorphic(HA8_direct)
('1*b_2_0',
'1*c_4_1',
'1*b_3_0^2+1*b_6_3+1*b_2_0*c_4_1',
'1*b_6_5',
'1*b_3_1',
'1*b_3_0',
'1*b_5_1',
'1*b_7_5',
'1*b_7_6')


The default way of computation is in fact more efficient, since less stability conditions are involved:

sage: len(HA8._PtoPcapCPdirect)
4
sage: len(HA8.subgroup_cohomology()._PtoPcapCPdirect)
1
sage: len(HA8_direct._PtoPcapCPdirect)
18

from_workspace(*args, **kwds)

Retrieve a cohomology ring from the workspace.

NOTE:

By default, the user’s current workspace is hosting the computation anyway. However, it is possible that the data is in fact copied from local sources outside of the workspace. This method temporarily disallows the use of other local or remote sources, so that it is guaranteed that only “fresh” data in the workspace are used.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: H = CohomologyRing.from_workspace(8,3)
sage: print(H)
Cohomology ring of Dihedral group of order 8 with coefficients in GF(2)
<BLANKLINE>
Computed up to degree 0
Minimal list of generators:
[]
Minimal list of algebraic relations:
[]

get_local_sources()

Return the location of the current local sources.

EXAMPLE:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.reset()
sage: try:
....:     from sage.env import SAGE_SHARE
....: except ImportError:
....:     try:
....:         from sage.misc.misc import SAGE_SHARE
....:     except ImportError:
....:         from sage.misc.misc import SAGE_DATA as SAGE_SHARE
sage: CohomologyRing.get_local_sources().startswith(os.path.realpath(SAGE_SHARE))
True
sage: tmp = tmp_dir()
sage: CohomologyRing.set_local_sources(tmp)
sage: CohomologyRing.get_local_sources().startswith(os.path.realpath(tmp))
True

get_workspace()

Return the location of the current workspace.

EXAMPLE:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.reset()
sage: CohomologyRing.get_workspace().startswith(os.path.realpath(DOT_SAGE))
True
sage: tmp = tmp_dir()
sage: CohomologyRing.set_workspace(tmp)
sage: CohomologyRing.get_workspace().startswith(os.path.realpath(tmp))
True

global_options(*args, **kwds)

Set global options for cohomology computations.

INPUT:

• arbitrary strings, as positional arguments.
• optional keyword arguments that provide values to be assigned to an option.

There are the special string values “warn”, “info” and “debug”, that set the logging level accordingly, and moreover “walltime” (the walltime spent since setting this option will be added to the log), “cputime” (the cputime spent since setting this option will be added to the log), “time” (the log will include both walltime and cputime). With “notime”, “nowalltime” and “nocputime”, the corresponding logging option can be switched off.

For any other string that does not start start with $$"no"$$, the option with that name is set to True. If it is of the form "no"+X, then the option with the name X is set to False. If there is no input, a copy of the dictionary of options is returned.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.reset()
sage: sorted(CohomologyRing.global_options().items())
[('NrCandidates', 1000),
('SingularCutoff', 70),
('autolift', 1),
('autoliftElAb', 0),
('save', True),
('sparse', False),
('useMTX', True),
('use_web', True)]
sage: CohomologyRing.global_options('sparse', 'nosave', autolift=4)
sage: sorted(CohomologyRing.global_options().items())
[('NrCandidates', 1000),
('SingularCutoff', 70),
('autolift', 4),
('autoliftElAb', 0),
('save', False),
('sparse', True),
('useMTX', True),
('use_web', True)]
sage: CohomologyRing.reset()

group_name(G, GroupName=None)

Determine a name for the given group.

NOTE:

This is just an auxiliary method and could as well be directly written in the code.

INPUT:

• G – a list, either comprised by two integers that form the address of a group in the SmallGroups library, or by a group in the libGAP interface.
• GroupName – an optional string, a name provided by the user.

If GroupName is provided, it will be used. Otherwise, if the group is given by its SmallGroup address, None is returned. Otherwise, if the group is provided with a custom name in GAP, it will be used. Otherwise, None is returned.

NOTE:

This package has a list of custom names for certain groups in the SmallGroups library. However, this list is only used in the initialisation of COHO.

EXAMPLE:

sage: from pGroupCohomology import CohomologyRing
sage: G = libgap.eval('DihedralGroup(8)')
sage: CohomologyRing.group_name((8,3))
sage: CohomologyRing.group_name((8,3),'D8')
'D8'
sage: CohomologyRing.group_name([G],'D8')
'D8'
sage: CohomologyRing.group_name([G])
sage: G.SetName("DihedralGroup_8")
sage: CohomologyRing.group_name([G])
'DihedralGroup_8'
sage: CohomologyRing.group_name([G],'D8')
'D8'

gstem(G, GStem=None, GroupName=None, GroupId=None)

Return a group identifier that is used to create file names.

INPUT:

• G – A list, either containing a single group in GAP or two integers providing an address in the SmallGroups library.
• GStem – (optional string) if provided, it will be used.
• GroupName – (optional string) if provided, if G contains a single group and no other optional arguments are provided, it is used.
• GroupId – (optional pair of integers) If G contains a single group, GroupId is supposed to be its address in the SmallGroups library.

OUTPUT:

• A normalised version of GStem, if it is provided.
• <q>gp<n>, if the SmallGroups address is provided by either G or GroupId.
• A normalised version of GroupName, if it is provided.
• If G contains a single group that has been given a custom name in GAP, a normalised version of this Name is returned.
• Otherwise, an error is raised.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.gstem([8,3])
'8gp3'
sage: CohomologyRing.gstem([8,3],GStem='DihedralGroup(8)')
'DihedralGroup_8_'
sage: CohomologyRing.gstem([libgap.eval('DihedralGroup(8)')],GroupName='DG(8)')
'DG_8_'
sage: CohomologyRing.gstem([libgap.eval('DihedralGroup(8)')],GroupName='DG(8)',GroupId=[8,3])
'8gp3'
sage: G = libgap.eval('DihedralGroup(8)')
sage: G.SetName("DG_8")
sage: CohomologyRing.gstem([G])
'DG_8'
sage: CohomologyRing.gstem([libgap.eval('DihedralGroup(8)')])
Traceback (most recent call last):
...
ValueError: Cannot infer a short group identifier. Please provide one of the optional arguments GStem or GroupName

reset()

Reset the cohomology ring machinery’s initial state.

We mainly use this to avoid side effects of doctests affecting other doctest.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.reset()
sage: sorted(CohomologyRing.global_options().items())
[('NrCandidates', 1000),
('SingularCutoff', 70),
('autolift', 1),
('autoliftElAb', 0),
('save', True),
('sparse', False),
('useMTX', True),
('use_web', True)]
sage: CohomologyRing.global_options('sparse', 'nosave', autolift=4)
sage: sorted(CohomologyRing.global_options().items())
[('NrCandidates', 1000),
('SingularCutoff', 70),
('autolift', 4),
('autoliftElAb', 0),
('save', False),
('sparse', True),
('useMTX', True),
('use_web', True)]
sage: CohomologyRing.reset()
sage: sorted(CohomologyRing.global_options().items())
[('NrCandidates', 1000),
('SingularCutoff', 70),
('autolift', 1),
('autoliftElAb', 0),
('save', True),
('sparse', False),
('useMTX', True),
('use_web', True)]

set_local_sources(folder=True)

Define which local sources to be used.

INPUT:

folder - (optional, default True) a bool or a string

OUTPUT:

• If folder is a non-empty string, it will be used as the root directory of local sources in subsequent cohomology computations.
• If the user has write permissions in this folder, it is actually used to create rings. Otherwise, it is only used to read existing cohomology data, but all new computations will still be done in the user’s workspace.
• If folder is True then the default location of the local sources is reset; this is a sub-directory of SAGE_SHARE.
• If bool(folder) is False then the user’s workspace will be used to create new data in subsequent computations, even if the user has write permission for the local sources.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: tmp_priv = tmp_dir()
sage: tmp_publ = tmp_dir()
sage: CohomologyRing.set_workspace(tmp_priv)


If the local sources are set by the user to a location for which s/he has write permissions, then it is used for creating a cohomology ring:

sage: CohomologyRing.set_local_sources(tmp_publ)
sage: H1 = CohomologyRing(8,3)
sage: H1.root.startswith(os.path.realpath(tmp_publ))
True


After unsetting it, the workspace is used instead:

sage: CohomologyRing.set_local_sources(False)
sage: H2 = CohomologyRing(8,3)
sage: H2.root.startswith(os.path.realpath(tmp_priv))
True


CohomologyRing.set_local_sources(False) did not reset the default local sources (that by default are read-only); but CohomologyRing.set_local_sources(True) does:

sage: CohomologyRing.set_local_sources(True)
sage: from sage.env import SAGE_SHARE
sage: CohomologyRing.get_local_sources().startswith(os.path.realpath(SAGE_SHARE))
True

set_remote_sources(URLs=None)

Redefine the default locations of web repositories for cohomology rings

INPUT:

URLs, a tuple of strings providing a URLs, or None.

If URLs is a tuple, then cohomology rings will be sought in the repositories denoted by the URLs (in the order given). In particular, if the tuple is empty, no web repositories will be used. If it is None, the locations are reset to some default.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: from sage.env import SAGE_SHARE
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace


During package installation, internet access is impossible. Therefore, we simulate the use of a web repository by accessing local files that are available during package installation:

sage: CohomologyRing.set_remote_sources(('file://'+os.path.join(os.path.realpath(os.path.curdir),'test_data'),))
sage: H = CohomologyRing.from_remote_sources('8gp3')
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]

set_workspace(s=None)

Define the location of the user’s workspace.

INPUT:

s, a string providing a folder name, or None.

OUTPUT:

If s is a string, a cohomology database in the folder s will be activated as the user’s workspace. Write permission for that folder is required. If it is None, a workspacee in a default location will be activated.

NOTE:

If necessary, the folder will be created as soon as data from s are requested.

EXAMPLES:

sage: from pGroupCohomology import CohomologyRing
sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
sage: tmp_root = tmp_dir()
sage: CohomologyRing.set_workspace(tmp_root)
sage: H = CohomologyRing(8,3)
sage: H.root.startswith(os.path.realpath(tmp_root))
True

pGroupCohomology.factory.unit_test_64(**kwds)

Compare computation from scratch with data in the database.

The cohomology rings for all groups of order 64 are computed from sratch and the results are compared with the data that are shipped with this package.

NOTE:

This test is likely to take between 5 and 30 minutes, depending on the computer.

INPUT:

Optional keyword arguments for the creation of cohomology rings.

OUTPUT:

• A list of integers, giving the address of groups of order 64 in the Small Groups library for which a cohomology computation yields (with the given keyword arguments) a Poincare series different from the database. So, this list should be empty.
• A list of three real numbers, giving the total computation time (wall time), the Python CPU-time and the Singular CPU-time, in seconds.

During the computation, there is some information on the progress of the test.

TEST:

sage: from pGroupCohomology.factory import unit_test_64


By default, i.e., without providing an explicit value False for from_scratch, the rings are computed from scratch, using a temporary directory created by the test function (this can be overwritten by providing an explicit value for root). This is a serious test, which should take 5–30 minutes.

Since doctests are supposed to be much shorter, we allow here to retrieve the data from the local sources (from_scratch=False). By consequence, the cohomology rings are simply reloaded and we merely test that pickling works.

sage: L, t = unit_test_64(from_scratch=False)    # long time
#  1: Walltime   ... min
CPU-time   ... min
Singular   ... min
...
#267: Walltime   ... min
CPU-time   ... min
Singular   ... min
sage: L
[]
`