"""
Homology Groups
This module defines a :meth:`HomologyGroup` class which is an abelian
group that prints itself in a way that is suitable for homology
groups.
"""
from sage.modules.free_module import VectorSpace
from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup_fixed_gens
from sage.rings.integer_ring import ZZ
class HomologyGroup_class(AdditiveAbelianGroup_fixed_gens):
"""
Discrete Abelian group on `n` generators. This class inherits from
:class:`~sage.groups.additive_abelian.additive_abelian_group.AdditiveAbelianGroup_fixed_gens`;
see :mod:`sage.groups.additive_abelian.additive_abelian_group` for more
documentation. The main difference between the classes is in the print
representation.
EXAMPLES::
sage: from sage.homology.homology_group import HomologyGroup
sage: G = AbelianGroup(5, [5,5,7,8,9]); G
Multiplicative Abelian group isomorphic to C5 x C5 x C7 x C8 x C9
sage: H = HomologyGroup(5, ZZ, [5,5,7,8,9]); H
C5 x C5 x C7 x C8 x C9
sage: G == loads(dumps(G))
True
sage: AbelianGroup(4)
Multiplicative Abelian group isomorphic to Z x Z x Z x Z
sage: HomologyGroup(4, ZZ)
Z x Z x Z x Z
sage: HomologyGroup(100, ZZ)
Z^100
"""
def __init__(self, n, invfac):
"""
See :func:`HomologyGroup` for full documentation.
EXAMPLES::
sage: from sage.homology.homology_group import HomologyGroup
sage: H = HomologyGroup(5, ZZ, [5,5,7,8,9]); H
C5 x C5 x C7 x C8 x C9
"""
n = len(invfac)
A = ZZ**n
B = A.span([A.gen(i) * invfac[i] for i in xrange(n)])
AdditiveAbelianGroup_fixed_gens.__init__(self, A, B, A.gens())
self._original_invts = invfac
def _repr_(self):
"""
Print representation of ``self``.
EXAMPLES::
sage: from sage.homology.homology_group import HomologyGroup
sage: H = HomologyGroup(7, ZZ, [4,4,4,4,4,7,7])
sage: H._repr_()
'C4^5 x C7 x C7'
sage: HomologyGroup(6, ZZ)
Z^6
"""
eldv = self._original_invts
if len(eldv) == 0:
return "0"
rank = len(filter(lambda x: x == 0, eldv))
torsion = sorted(filter(lambda x: x, eldv))
if rank > 4:
g = ["Z^%s" % rank]
else:
g = ["Z"] * rank
if len(torsion) != 0:
printed = []
for t in torsion:
numfac = torsion.count(t)
too_many = (numfac > 4)
if too_many:
if t not in printed:
g.append("C{}^{}".format(t, numfac))
printed.append(t)
else:
g.append("C%s" % t)
times = " x "
return times.join(g)
def _latex_(self):
"""
LaTeX representation of ``self``.
EXAMPLES::
sage: from sage.homology.homology_group import HomologyGroup
sage: H = HomologyGroup(7, ZZ, [4,4,4,4,4,7,7])
sage: H._latex_()
'C_{4}^{5} \\times C_{7} \\times C_{7}'
sage: latex(HomologyGroup(6, ZZ))
\ZZ^{6}
"""
eldv = self._original_invts
if len(eldv) == 0:
return "0"
rank = len(filter(lambda x: x == 0, eldv))
torsion = sorted(filter(lambda x: x, eldv))
if rank > 4:
g = ["\\ZZ^{{{}}}".format(rank)]
else:
g = ["\\ZZ"] * rank
if len(torsion) != 0:
printed = []
for t in torsion:
numfac = torsion.count(t)
too_many = (numfac > 4)
if too_many:
if t not in printed:
g.append("C_{{{}}}^{{{}}}".format(t, numfac))
printed.append(t)
else:
g.append("C_{{{}}}".format(t))
times = " \\times "
return times.join(g)
def HomologyGroup(n, base_ring, invfac=None):
"""
Abelian group on `n` generators which represents a homology group in a
fixed degree.
INPUT:
- ``n`` -- integer; the number of generators
- ``base_ring`` -- ring; the base ring over which the homology is computed
- ``inv_fac`` -- list of integers; the invariant factors -- ignored
if the base ring is a field
OUTPUT:
A class that can represent the homology group in a fixed
homological degree.
EXAMPLES::
sage: from sage.homology.homology_group import HomologyGroup
sage: G = AbelianGroup(5, [5,5,7,8,9]); G
Multiplicative Abelian group isomorphic to C5 x C5 x C7 x C8 x C9
sage: H = HomologyGroup(5, ZZ, [5,5,7,8,9]); H
C5 x C5 x C7 x C8 x C9
sage: AbelianGroup(4)
Multiplicative Abelian group isomorphic to Z x Z x Z x Z
sage: HomologyGroup(4, ZZ)
Z x Z x Z x Z
sage: HomologyGroup(100, ZZ)
Z^100
"""
if base_ring.is_field():
return VectorSpace(base_ring, n)
if invfac is None:
if isinstance(n, (list, tuple)):
invfac = n
n = len(n)
else:
invfac = []
if len(invfac) < n:
invfac = [0] * (n - len(invfac)) + invfac
elif len(invfac) > n:
raise ValueError("invfac (={}) must have length n (={})".format(invfac, n))
M = HomologyGroup_class(n, invfac)
return M