Bar Codes — "p_group_cohomology" 3.3.2 documentation

# Bar Codes

AUTHORS:

- Simon King <simon.king@uni-jena.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 non-negative 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 non-trivial 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_{n-1},..., G_0\), while the last \(n\) columns correspond to the factor groups \(G/G_n, G/G_{n-1},..., 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 non-negative integer, the lowest shown degree

    - `dmax` (default = 10): optional non-negative integer, the highest shown degree

    The resulting picture combines the planar bar codes for each degree between `dmin` and `dmax` to a 3-dimensional 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}}\verb|Persistence|\phantom{\verb!x!}\verb|data|\phantom{\verb!x!}\verb|for|\phantom{\verb!x!}\verb|H^*(SmallGroup(16,3);|\phantom{\verb!x!}\verb|GF(2))|\phantom{\verb!x!}\verb|associated|\phantom{\verb!x!}\verb|with|\phantom{\verb!x!}\verb|LowerCentralSeries|</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` and `command` 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