Bar Codes¶
AUTHORS:
 Simon King <simon.king@unijena.de>
The two classes provided in this module are used to store and display ‘persistent group cohomology’. Persistent group cohomology was introduced by [EllisKing].
The basic idea is as follows: Any normal series of a group gives rise to a chain of inclusion and quotient maps, which in turn give induced homomorphisms in cohomology. The degree \(d\) bar code associated with the normal series is an upper triangular nonnegative integer matrix, telling how many cocycles of degree \(d\) ‘survive’ how long under the induced maps.
It turns out that these simple collections of integers allow to distinguish between cohomology rings, even if the rings seem fairly similar (same Poincaré series, same number of generators and relations sorted by degree, same depth) and even if the normal series of the two groups are essentially the same.
EXAMPLES:
We work here with groups of order 64, that are part of the cohomology data base shipped with this package.
sage: from pGroupCohomology import CohomologyRing
sage: H158 = CohomologyRing(64,158)
sage: H160 = CohomologyRing(64,160)
The Poincaré series, the \(a\)invariants, the degrees of generators and of relations of the cohomology rings coincide:
sage: H158.poincare_series()
(t^4 + t^3 + t^2 + t + 1)/(t^6  2*t^5 + 3*t^4  4*t^3 + 3*t^2  2*t + 1)
sage: H160.poincare_series()
(t^4 + t^3 + t^2 + t + 1)/(t^6  2*t^5 + 3*t^4  4*t^3 + 3*t^2  2*t + 1)
sage: H158.degvec
[4, 4, 1, 1, 1, 3, 3]
sage: H160.degvec
[4, 4, 1, 1, 1, 3, 3]
sage: H158.set_ring()
sage: [singular('deg(%s)'%r) for r in H158.rels()]
[2, 2, 3, 3, 4, 4, 5, 6, 6, 6]
sage: H160.set_ring()
sage: [singular('deg(%s)'%r) for r in H160.rels()]
[2, 2, 3, 3, 4, 4, 5, 6, 6, 6]
sage: H158.a_invariants()
[Infinity, Infinity, 2]
sage: H160.a_invariants()
[Infinity, Infinity, 2]
We consider here the bar codes associated with the upper central series. It turns out that the nontrivial terms of the upper central series and the resulting factor groups are isomorphic:
sage: G158 = libgap.SmallGroup(64,158)
sage: G160 = libgap.SmallGroup(64,160)
sage: [(G.IdGroup(), (G158/G).IdGroup()) for G in G158.UpperCentralSeries()]
[([ 64, 158 ], [ 1, 1 ]),
([ 16, 2 ], [ 4, 2 ]),
([ 4, 2 ], [ 16, 11 ]),
([ 1, 1 ], [ 64, 158 ])]
sage: [(G.IdGroup(), (G160/G).IdGroup()) for G in G160.UpperCentralSeries()]
[([ 64, 160 ], [ 1, 1 ]),
([ 16, 2 ], [ 4, 2 ]),
([ 4, 2 ], [ 16, 11 ]),
([ 1, 1 ], [ 64, 160 ])]
Nevertheless, the groups can be distinguished using the bar codes associated with the upper central series:
sage: B158 = H158.bar_code('UpperCentralSeries')
sage: B160 = H160.bar_code('UpperCentralSeries')
sage: B158 == B160
False
Indeed, the bar codes differ in degree 3; graphically:
sage: ascii_art(B158[3])
*
*
**
**
*
*
*
*
*
*
**
**
*
*
*
*
*
*
*
*
*
*
sage: ascii_art(B160[3])
*
*
**
*
*
*
*
*
*
*
***
**
*
**
*
*
*
*
*
*
*
These pictures (bar codes) can be interpreted as follows. Let \(G\) be a finite \(p\)group and let \(G=G_0 > G_1 > ... > G_n > 1\) be a normal series; in our example, we have \(n=2\). The first \(n+1\) columns of the bar code correspond to the normal subgroups groups \(G_n, G_{n1},..., G_0\), while the last \(n\) columns correspond to the factor groups \(G/G_n, G/G_{n1},..., G/G_1\). We consider the sequence of group homomorphisms given by inclusions and quotients. The stars in the bar code correspond to basis vectors of the degree \(d\) part of the cohomology rings of the respective groups. Stars are connected by a line (i.e., a hyphen) if the corresponding basis vectors are mapped to each other by the induced maps (which of course go from right to left).
As we have mentioned above, the bar code is determined by an upper triangular ‘persistence matrix’, which is as follows in degree 3:
sage: B158[3].matrix()
[ 4 0 0 0 0]
[ 0 4 0 0 0]
[ 0 0 4 2 0]
[ 0 0 0 10 2]
[ 0 0 0 0 4]
sage: B160[3].matrix()
[ 4 0 0 0 0]
[ 0 4 1 0 0]
[ 0 0 4 2 1]
[ 0 0 0 10 2]
[ 0 0 0 0 4]
As usual, the sequence of integers in increasing degrees gives rise to
a Poincaré series. So, in fact we get an upper triangular persistence
matrix whose coefficients are rational functions. We show how these
look in position (2,4)
:
sage: B158.matrix()[2,4]
2*t^2 + 2*t + 1
sage: B160.matrix()[2,4]
t^3 + 2*t^2 + 2*t + 1

class
pGroupCohomology.barcode.
BarCode
(L, **MetaData)¶ Bar codes (persistent group cohomology).
A bar code in a fixed degree is encoded by an upper triangular matrix of integers and can be depicted by arrangement of bars of different length. The full bar code combines the information for all degrees, by means of Poincaré series.
EXAMPLES:
This class was designed for use in persistent group cohomology. So, we take an example from this context. See
bar_code()
for the theoretical background.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: B = H.bar_code('UpperCentralSeries') # indirect doctest sage: B Persistence data for H^*(D8; GF(2)) associated with UpperCentralSeries
The persistence data are encoded in an upper triangular matrix whose entries are Poincaré series:
sage: B.matrix() [ 1/(t + 1) 1/(t^2  1) 1] [ 0 1/(t^2  2*t + 1) (t  1)/(t  1)] [ 0 0 1/(t^2  2*t + 1)]
The bar code in each degree can be extracted from the Poincaré series:
sage: B[1] Barcode of degree 1 for H^*(D8; GF(2)) associated with UpperCentralSeries sage: ascii_art(B[2]) * ** ** ** sage: B[2].matrix() [1 1 0] [0 3 2] [0 0 3] sage: B[15].matrix() [ 1 0 0] [ 0 16 2] [ 0 0 16]

data
()¶ Return the defining data of self as a sorted list.
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: B = H.bar_code('UpperCentralSeries') sage: B Persistence data for H^*(D8; GF(2)) associated with UpperCentralSeries sage: B.data() [((1, 1), 1/(t + 1)), ((1, 0), 1/(t^2  1)), ((1, 1), 1), ((0, 0), 1/(t^2  2*t + 1)), ((0, 1), (t  1)/(t  1)), ((1, 1), 1/(t^2  2*t + 1))]

matrix
()¶ Return the persistence matrix 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: B = H.bar_code('UpperCentralSeries') sage: B.matrix() [ 1/(t + 1) 1/(t^2  1) 1] [ 0 1/(t^2  2*t + 1) (t  1)/(t  1)] [ 0 0 1/(t^2  2*t + 1)]

show
(*args, **kwds)¶ Show a 3D picture of self.
INPUT:
dmin
(default = 1): optional nonnegative integer, the lowest shown degreedmax
(default = 10): optional nonnegative integer, the highest shown degree
The resulting picture combines the planar bar codes for each degree between
dmin
anddmax
to a 3dimensional arrangement of bars.TESTS:
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: B = H.bar_code('LowerCentralSeries') sage: show(B,dmin=3,dmax=15) <html><script type="math/tex">\newcommand{\Bold}[1]{\mathbf{#1}}\verbPersistence\phantom{\verb!x!}\verbdata\phantom{\verb!x!}\verbfor\phantom{\verb!x!}\verbH^*(SmallGroup(16,3);\phantom{\verb!x!}\verbGF(2))\phantom{\verb!x!}\verbassociated\phantom{\verb!x!}\verbwith\phantom{\verb!x!}\verbLowerCentralSeries</script></html>
For seeing a nice picture, you should instead do
B.show(dmin=3, dmax=15)
.


class
pGroupCohomology.barcode.
BarCode2d
(L, **MetaData)¶ Integer valued bar codes (bar code in a single degree).
A bar code in a fixed degree is encoded by an upper triangular matrix of integers and can be depicted by arrangement of bars of different length.
EXAMPLES:
This class was designed for use in persistent group cohomology. So, we take an example from this context. See
bar_code()
for the theoretical background.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: B = H.bar_code('UpperCentralSeries') # indirect doctest sage: B Persistence data for H^*(D8; GF(2)) associated with UpperCentralSeries sage: B[3] Barcode of degree 3 for H^*(D8; GF(2)) associated with UpperCentralSeries sage: ascii_art(B[3]) * * ** ** * * * sage: B[3].matrix() [1 0 0] [0 4 2] [0 0 4]

add_metadata
(key, datum)¶ Add further information on the bar code.
NOTE:
Currently, only the meta data
degree
,ring
andcommand
are used. But further meta data are, in principle, possible.EXAMPLES:
sage: from pGroupCohomology.barcode import BarCode2d sage: B = BarCode2d([((0,0),1)]) sage: B Barcode sage: B.add_metadata('degree',5) sage: B Barcode of degree 5 sage: B.add_metadata('ring','some fancy ring') sage: B Barcode of degree 5 for some fancy ring sage: B.add_metadata('command','some normal series') sage: B Barcode of degree 5 for some fancy ring associated with some normal series

data
()¶ Return the defining data of self as a sorted list.
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: B = H.bar_code('UpperCentralSeries',degree=3) sage: B Barcode of degree 3 for H^*(D8; GF(2)) associated with UpperCentralSeries sage: B.data() [((1, 1), 1), ((1, 0), 0), ((1, 1), 0), ((0, 0), 4), ((0, 1), 2), ((1, 1), 4)]

matrix
()¶ Return the persistence matrix 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: B = H.bar_code('UpperCentralSeries',degree=3) sage: B.matrix() [1 0 0] [0 4 2] [0 0 4]

plot
(*args, **kwds)¶ Produce a picture of the bar code.
TESTS:
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: B = H.bar_code('UpperCentralSeries',degree=3) sage: plot(B) # render Graphics object consisting of 7 graphics primitives
