Skip to content

Commit

Permalink
sagemathgh-37872: sage.{topology,homology}: Remove deprecated chomp i…
Browse files Browse the repository at this point in the history
…nterface

    
<!-- ^ Please provide a concise and informative title. -->
<!-- ^ Don't put issue numbers in the title, do this in the PR
description below. -->
<!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method
to calculate 1 + 2". -->
<!-- v Describe your changes below in detail. -->
<!-- v Why is this change required? What problem does it solve? -->
<!-- v If this PR resolves an open issue, please link to it here. For
example, "Fixes sagemath#12345". -->

- Deprecated in sagemath#33777 (2022).

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->

- [x] The title is concise and informative.
- [ ] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation and checked the documentation
preview.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on. For example,
-->
<!-- - sagemath#12345: short description why this is a dependency -->
<!-- - sagemath#34567: ... -->
    
URL: sagemath#37872
Reported by: Matthias Köppe
Reviewer(s):
  • Loading branch information
Release Manager committed May 1, 2024
2 parents 75c86c8 + 3993ba7 commit 31cf6d3
Show file tree
Hide file tree
Showing 7 changed files with 5 additions and 1,217 deletions.
6 changes: 3 additions & 3 deletions src/doc/en/developer/coding_basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1303,11 +1303,11 @@ framework. Here is a comprehensive list:
that is, commas, hyphens, semicolons, ..., after the
first word ends the list of packages. Hyphens or colons between the
word ``optional`` and the first package name are allowed. Therefore,
you should not write ``# optional - depends on package CHomP`` but simply
``# optional - CHomP``.
you should not write ``# optional - depends on package bliss`` but simply
``# optional - bliss``.

- Optional tags are case-insensitive, so you could also write ``# optional -
chOMP``.
Bliss``.

If ``# optional`` or ``# needs`` is placed right after the ``sage:`` prompt,
it is a block-scoped tag, which applies to all doctest lines until
Expand Down
1 change: 0 additions & 1 deletion src/doc/en/reference/homology/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ computing homology groups.
sage/homology/algebraic_topological_model
sage/homology/homology_morphism
sage/homology/matrix_utils
sage/interfaces/chomp

.. include:: ../footer.txt
133 changes: 1 addition & 132 deletions src/sage/homology/chain_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1141,58 +1141,6 @@ def __ne__(self, other):
"""
return not self == other

def _homology_chomp(self, deg, base_ring, verbose, generators):
"""
Helper function for :meth:`homology`.
This function is deprecated.
INPUT:
- ``deg`` -- integer (one specific homology group) or ``None``
(all of those that can be non-zero)
- ``base_ring`` -- the base ring (must be the integers
or a prime field)
- ``verbose`` -- boolean, whether to print some messages
- ``generators`` -- boolean, whether to also return generators
for homology
EXAMPLES::
sage: C = ChainComplex({0: matrix(ZZ, 2, 3, [3, 0, 0, 0, 0, 0])}, base_ring=GF(2))
sage: C._homology_chomp(None, GF(2), False, False) # optional - chomp, needs sage.rings.finite_rings
doctest:...: DeprecationWarning: the CHomP interface is deprecated; hence so is this function
See https://github.com/sagemath/sage/issues/33777 for details.
{0: Vector space of dimension 2 over Finite Field of size 2, 1: Vector space of dimension 1 over Finite Field of size 2}
sage: D = ChainComplex({0: matrix(ZZ,1,0,[]), 1: matrix(ZZ,1,1,[0]),
....: 2: matrix(ZZ,0,1,[])})
sage: D._homology_chomp(None, GF(2), False, False) # optional - chomp, needs sage.rings.finite_rings
{1: Vector space of dimension 1 over Finite Field of size 2,
2: Vector space of dimension 1 over Finite Field of size 2}
"""
deprecation(33777, "the CHomP interface is deprecated; hence so is this function")
from sage.interfaces.chomp import homchain
H = homchain(self, base_ring=base_ring, verbose=verbose,
generators=generators)
if H is None:
raise RuntimeError('ran CHomP, but no output')
if deg is None:
# all the homology groups that could be non-zero
# one has to complete the answer of chomp
result = H
for idx in self.nonzero_degrees():
if idx not in H:
result[idx] = HomologyGroup(0, base_ring)
return result
if deg in H:
return H[deg]
else:
return HomologyGroup(0, base_ring)

def homology(self, deg=None, base_ring=None, generators=False,
verbose=False, algorithm='pari'):
r"""
Expand Down Expand Up @@ -1223,7 +1171,6 @@ def homology(self, deg=None, base_ring=None, generators=False,
* ``'auto'``
* ``'dhsw'``
* ``'pari'``
* ``'chomp'`` (this option is deprecated)
See below for descriptions.
Expand Down Expand Up @@ -1254,12 +1201,6 @@ def homology(self, deg=None, base_ring=None, generators=False,
forces the named algorithm to be used regardless of the size
of the matrices.
Finally, if ``algorithm`` is set to ``'chomp'``, then use
CHomP. CHomP is available at the web page
http://chomp.rutgers.edu/, although the software has not been
tested recently in Sage. The use of this option is deprecated;
see :issue:`33777`.
As of this writing, ``'pari'`` is the fastest standard option.
.. WARNING::
Expand Down Expand Up @@ -1319,10 +1260,8 @@ def homology(self, deg=None, base_ring=None, generators=False,
if not (base_ring.is_field() or base_ring is ZZ):
raise NotImplementedError('can only compute homology if the base ring is the integers or a field')

if algorithm not in ['dhsw', 'pari', 'auto', 'no_chomp', 'chomp']:
if algorithm not in ['dhsw', 'pari', 'auto', 'no_chomp']:
raise NotImplementedError('algorithm not recognized')
if algorithm == 'chomp':
return self._homology_chomp(deg, base_ring, verbose, generators)

if deg is None:
deg = self.nonzero_degrees()
Expand Down Expand Up @@ -1686,76 +1625,6 @@ def shift(self, n=1):
return ChainComplex({k-shift: sgn * self._diff[k] for k in self._diff},
degree_of_differential=deg)

def _chomp_repr_(self):
r"""
String representation of ``self`` suitable for use by the CHomP
program.
This function is deprecated.
Since CHomP can only handle chain complexes, not cochain
complexes, and since it likes its complexes to start in degree
0, flip the complex over if necessary, and shift it to start
in degree 0. Note also that CHomP only works over the
integers or a finite prime field.
EXAMPLES::
sage: C = ChainComplex({-2: matrix(ZZ, 1, 3, [3, 0, 0])}, degree=-1)
sage: C._chomp_repr_()
doctest:...: DeprecationWarning: the CHomP interface is deprecated; hence so is this function
See https://github.com/sagemath/sage/issues/33777 for details.
'chain complex\n\nmax dimension = 1\n\ndimension 0\n boundary a1 = 0\n\ndimension 1\n boundary a1 = + 3 * a1 \n boundary a2 = 0\n boundary a3 = 0\n\n'
sage: C = ChainComplex({-2: matrix(ZZ, 1, 3, [3, 0, 0])}, degree=1)
sage: C._chomp_repr_()
'chain complex\n\nmax dimension = 1\n\ndimension 0\n boundary a1 = 0\n\ndimension 1\n boundary a1 = + 3 * a1 \n boundary a2 = 0\n boundary a3 = 0\n\n'
"""
deprecation(33777, "the CHomP interface is deprecated; hence so is this function")
deg = self.degree_of_differential()
if (self.grading_group() != ZZ or
(deg != 1 and deg != -1)):
raise ValueError('CHomP only works on Z-graded chain complexes with '
'differential of degree 1 or -1')
base_ring = self.base_ring()
if (base_ring == QQ) or (base_ring != ZZ and not (base_ring.is_prime_field())):
raise ValueError('CHomP doesn\'t compute over the rationals, only over Z or F_p')
if deg == -1:
diffs = self.differential()
else:
diffs = self._flip_().differential()

if len(diffs) == 0:
diffs = {0: matrix(ZZ, 0, 0)}

maxdim = max(diffs)
mindim = min(diffs)
# will shift chain complex by subtracting mindim from
# dimensions, so its bottom dimension is zero.
s = "chain complex\n\nmax dimension = %s\n\n" % (maxdim - mindim - 1,)

for i in range(0, maxdim - mindim):
s += "dimension %s\n" % i
mat = diffs.get(i + mindim, matrix(base_ring, 0, 0))
for idx in range(mat.ncols()):
s += " boundary a%s = " % (idx + 1)
# construct list of bdries
col = mat.column(idx)
nonzero_pos = col.nonzero_positions()
if nonzero_pos:
for j in nonzero_pos:
entry = col[j]
if entry > 0:
sgn = "+"
else:
sgn = "-"
entry = -entry
s += "%s %s * a%s " % (sgn, entry, j+1)
else:
s += "0"
s += "\n"
s += "\n"
return s

def _repr_(self):
"""
Print representation.
Expand Down
99 changes: 1 addition & 98 deletions src/sage/homology/tests.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,10 @@
# sage.doctest: needs sage.modules
"""
Tests for chain complexes, simplicial complexes, etc.
These test whether CHomP gives the same answers as Sage's built-in
homology calculator.
Since the CHomP interface has been deprecated --- see :issue:`33777`
--- so are many of the functions in is this module.
TESTS::
sage: from sage.homology.tests import test_random_chain_complex
sage: test_random_chain_complex(trials=20) # optional - CHomP
doctest:...: DeprecationWarning: the CHomP interface is deprecated; hence so is this function
See https://github.com/sagemath/sage/issues/33777 for details.
sage: test_random_chain_complex(level=2, trials=20) # optional - CHomP
sage: test_random_chain_complex(level=3, trials=20) # long time # optional - CHomP
sage: from sage.homology.tests import test_random_simplicial_complex
sage: test_random_simplicial_complex(level=1, trials=20) # optional - CHomP
doctest:...: DeprecationWarning: the CHomP interface is deprecated; hence so is this function
See https://github.com/sagemath/sage/issues/33777 for details.
sage: test_random_simplicial_complex(level=2, trials=20) # optional - CHomP
sage: test_random_simplicial_complex(level=5/2, trials=10) # long time # optional - CHomP
"""

from sage.misc.random_testing import random_testing
from sage.misc.prandom import randint
from sage.misc.superseded import deprecation
from sage.matrix.constructor import random_matrix
from sage.homology.chain_complex import ChainComplex
from sage.rings.integer_ring import ZZ
Expand Down Expand Up @@ -66,43 +43,6 @@ def random_chain_complex(level=1):
return ChainComplex({dim: mat}, degree=deg)


@random_testing
def test_random_chain_complex(level=1, trials=1, verbose=False):
"""
Compute the homology of a random chain complex with and without
CHomP, and compare the results. If they are not the same, raise
an error.
This function is deprecated: see :issue:`33777`.
:param level: measure of complexity of the chain complex -- see
:func:`random_chain_complex`
:type level: positive integer; optional, default 1
:param trials: number of trials to conduct
:type trials: positive integer; optional, default 1
:param verbose: if ``True``, print verbose messages
:type verbose: boolean; optional, default ``False``
EXAMPLES::
sage: from sage.homology.tests import test_random_chain_complex
sage: test_random_chain_complex(trials=2) # optional - CHomP
doctest:...: DeprecationWarning: the CHomP interface is deprecated; hence so is this function
See https://github.com/sagemath/sage/issues/33777 for details.
"""
deprecation(33777, 'the CHomP interface is deprecated; hence so is this function')
for i in range(trials):
C = random_chain_complex(level=level)
for d in C.differential():
chomp = C.homology(d, verbose=verbose)
no_chomp = C.homology(d, algorithm='no_chomp', verbose=verbose)
if chomp != no_chomp:
print("Homology in dimension %s according to CHomP: %s" % (d, chomp))
print("Homology in dimension %s according to Sage: %s" % (d, no_chomp))
print("Chain complex: %s" % C.differential())
raise ValueError


def random_simplicial_complex(level=1, p=0.5):
"""
Return a random simplicial complex.
Expand All @@ -118,48 +58,11 @@ def random_simplicial_complex(level=1, p=0.5):
sage: from sage.homology.tests import random_simplicial_complex
sage: X = random_simplicial_complex()
sage: X # random
sage: X # random
Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6, 7) and 31 facets
sage: X.dimension() < 11
True
"""
n = randint(2, 4 * level)
dim = randint(1, n)
return RandomComplex(n, dim, p)


@random_testing
def test_random_simplicial_complex(level=1, trials=1, verbose=False):
"""
Compute the homology of a random simplicial complex with and
without CHomP, and compare the results. If they are not the same,
raise an error.
:param level: measure of complexity of the simplicial complex --
see :func:`random_simplicial_complex`
:type level: positive integer; optional, default 1
:param trials: number of trials to conduct
:type trials: positive integer; optional, default 1
:param verbose: if ``True``, print verbose messages
:type verbose: boolean; optional, default ``False``
This gets pretty slow if ``level`` is more than 3.
EXAMPLES::
sage: from sage.homology.tests import test_random_simplicial_complex
sage: test_random_simplicial_complex(trials=2) # optional - CHomP
doctest:...: DeprecationWarning: the CHomP interface is deprecated; hence so is this function
See https://github.com/sagemath/sage/issues/33777 for details.
"""
deprecation(33777, 'the CHomP interface is deprecated; hence so is this function')
for i in range(trials):
X = random_simplicial_complex(level=level)
chomp = X.homology(verbose=verbose)
no_chomp = X.homology(algorithm='no_chomp', verbose=verbose)
if chomp != no_chomp:
print("Homology according to CHomP: %s" % chomp)
print("Homology according to Sage: %s" % no_chomp)
print("Simplicial complex: %s" % X)
print("Its chain complex: %s" % X.chain_complex())
raise ValueError
Loading

0 comments on commit 31cf6d3

Please sign in to comment.