#31669 closed enhancement (fixed)

Category of chain complexes: (co)homology functor

Reported by: gh-mjungmath Owned by:
Priority: major Milestone: sage-9.4
Component: categories Keywords: homology
Cc: mkoeppe, tscrim, egourgoulhon, jhpalmieri Merged in:
Authors: Michael Jung Reviewers: Travis Scrimshaw
Report Upstream: N/A Work issues:
Branch: 4bceb9b (Commits, GitHub, GitLab) Commit: 4bceb9b22e889380d36ad78097e82c921aa95309
Dependencies: #31691 Stopgaps:

Status badges

Description (last modified by gh-mjungmath)

In this ticket, we equip the category of chain complexes with a method homology yielding the associated homology. The corresponding homology functor will use this method.

This happens in view of Čech cohomology, Morse homology and de Rham cohomology on manifolds.

Comments and opinions are as always welcome.

Change History (62)

comment:1 Changed 15 months ago by mkoeppe

  • Milestone changed from sage-9.3 to sage-9.4

comment:2 Changed 15 months ago by gh-mjungmath

  • Branch set to u/gh-mjungmath/category_of_chain_complexes___co_homology_functor

comment:3 Changed 15 months ago by gh-mjungmath

  • Commit set to 0393c2594ff80da9b540fee8cb6ed886c2e99a91

First draft. Comments are welcome.


New commits:

bcdee3aTrac #31669: add cochains and (co)homology method
0393c25Trac #31669: (co)homology functor added

comment:4 Changed 15 months ago by git

  • Commit changed from 0393c2594ff80da9b540fee8cb6ed886c2e99a91 to 8bcdfdf0df678e6bd0e1084555e78b8a0e8de5ba

Branch pushed to git repo; I updated commit sha1. New commits:

8bcdfdfTrac #31669: minor typos

comment:5 Changed 15 months ago by gh-mjungmath

  • Authors set to Michael Jung
  • Description modified (diff)
  • Keywords cohomology removed

chain_complex doesn't make a distinction between chain and cochain complexes. Probably because it also allows multigrading.

Should we remove the category of cochain complexes then? I mean, in a broad sense, cochain complexes can be seen as generalized chain complexes, no?

Btw, is it customary to add a mathematical description in the category section?

Last edited 15 months ago by gh-mjungmath (previous) (diff)

comment:6 Changed 15 months ago by git

  • Commit changed from 8bcdfdf0df678e6bd0e1084555e78b8a0e8de5ba to 718d354499400ef4e1686c7f04ea4f2529750e9b

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

6988be0Trac #31669: homology functor
718d354Trac #31669: add category of chain complexes to commutative_dga

comment:7 Changed 15 months ago by gh-mjungmath

Here is a proposal without cochain complexes.


New commits:

6988be0Trac #31669: homology functor
718d354Trac #31669: add category of chain complexes to commutative_dga
Last edited 15 months ago by gh-mjungmath (previous) (diff)

comment:8 Changed 15 months ago by gh-mjungmath

  • Cc jhpalmieri added

comment:9 Changed 15 months ago by tscrim

There is no difference as the degree of the chain map is part of the data of a chain complex. I agree that it is good to *not* have a category of cochain complexes.

You can add a very brief description to the category, but nobody really reads that part IMO.

comment:10 Changed 15 months ago by gh-mjungmath

I have added a differential method to the category since this is a crucial ingredient for chain complexes. For consistency it might also be a good idea to turn differentials of chain_complex into morphisms in the category of modules like it is done in commutative_dga.

Last edited 15 months ago by gh-mjungmath (previous) (diff)

comment:11 Changed 15 months ago by git

  • Commit changed from 718d354499400ef4e1686c7f04ea4f2529750e9b to 98e3ed671206d17e9dbe4377a37fd7648abfc3ce

Branch pushed to git repo; I updated commit sha1. New commits:

98e3ed6Trac #31669: add differentials to category

comment:12 Changed 15 months ago by gh-mjungmath

If there is nothing you'd like to add, that should be it. I added the above task as a TODO comment. Perhaps I even open a ticket.

comment:13 Changed 15 months ago by gh-mjungmath

  • Status changed from new to needs_review

comment:14 follow-up: Changed 15 months ago by tscrim

Rather than raise a NotImplementedError, it is better if you mark them as @abstract_method.

_apply_functor_to_morphism is missing doctests.

I would not change the title doc of chain_complex.py. It is possible that non-bounded chain complexes are added to that file eventually.

Should we allow HomologyFunctor to have a default of n=None so it returns the entire homology?

This is a more of a question for John. When I think of cohomology, I think there should be some extra ring structure. If the degree of the differential is negative, can we generally assume there is a ring structure on the homology or is this something special based on the construction?

comment:15 in reply to: ↑ 14 ; follow-up: Changed 15 months ago by gh-mjungmath

Replying to tscrim:

Rather than raise a NotImplementedError, it is better if you mark them as @abstract_method.

_apply_functor_to_morphism is missing doctests.

That is because we don't have any examples to apply here, or do we?

I would not change the title doc of chain_complex.py. It is possible that non-bounded chain complexes are added to that file eventually.

Well, that can be done if that finally happens, no?

Should we allow HomologyFunctor to have a default of n=None so it returns the entire homology?

This is a more of a question for John. When I think of cohomology, I think there should be some extra ring structure. If the degree of the differential is negative, can we generally assume there is a ring structure on the homology or is this something special based on the construction?

I agree, it should, and I will add it accordingly. For the moment however, neither chain_complex nor commutative_dga provide (co)homology in terms of a graded ring.

comment:16 in reply to: ↑ 15 Changed 15 months ago by gh-mjungmath

Replying to gh-mjungmath:

Replying to tscrim:

Rather than raise a NotImplementedError, it is better if you mark them as @abstract_method.

_apply_functor_to_morphism is missing doctests.

That is because we don't have any examples to apply here, or do we?

Perhaps I can add an example together with #31693.

comment:17 follow-up: Changed 15 months ago by gh-mjungmath

As for _apply_functor_to_morphism we could enforce a method homology_raw (cf. commutative_dga) which returns the homology as an actual quotient whose elements admit a lift method. Then the _apply_functor_to_morphism is rather generic:

Lift the homology element, apply the original morphism to it, reduce to the quotient.

At that end one could implement isomorphisms from the already lifted homology groups to the homology groups emerged as quotient.

Not sure whether this is a feasible approach. Travis, what do you think?

I would have wished that the homology already occurs as a quotient in the first place. Is there a reason why this hasn't been done so?

comment:18 Changed 15 months ago by gh-mjungmath

  • Status changed from needs_review to needs_work

comment:19 in reply to: ↑ 17 Changed 15 months ago by jhpalmieri

Replying to gh-mjungmath:

I would have wished that the homology already occurs as a quotient in the first place. Is there a reason why this hasn't been done so?

It is much faster to compute the homology as an abstract group (by computing the Smith normal form of the boundary matrices) than to compute the cycles as a subgroup of the chains and then the homology as a quotient of the cycles.

comment:20 Changed 15 months ago by git

  • Commit changed from 98e3ed671206d17e9dbe4377a37fd7648abfc3ce to 6f00253e5702a38a55a232ddc1538bccf6b28f02

Branch pushed to git repo; I updated commit sha1. New commits:

6f00253Trac 31669: lift and reduce to/from homology

comment:21 Changed 15 months ago by gh-mjungmath

Check out my new commit. This approach is a bit more generic. What do you think?

comment:22 Changed 15 months ago by git

  • Commit changed from 6f00253e5702a38a55a232ddc1538bccf6b28f02 to 78475b65f60b604d28c96327f6a23bfa335a8bb9

Branch pushed to git repo; I updated commit sha1. New commits:

78475b6Trac 31669: docstring improved

comment:23 Changed 15 months ago by git

  • Commit changed from 78475b65f60b604d28c96327f6a23bfa335a8bb9 to 41461f748100803f5951945560f49815c430740a

Branch pushed to git repo; I updated commit sha1. New commits:

41461f7Trac 31669: minor docstring improved

comment:24 follow-up: Changed 15 months ago by tscrim

Even if we have no examples, it still needs a doctest (even if it just showing that it has not been defined).

Yes, we can change the title if that indeed happens, but right now, let's leave it alone.

I don't like the idea of enforcing a homology_raw. Implementors should be free to implement what works best for them and their problem at hand as per John's comment. Things at the category level should be kept as generic as possible.

It would be better to have this as a generic implementation in the category by using some assumption on the chain complex and the corresponding morphisms. Of course, it would need a better name and could be the generic implementation, but I am not sure we want to force an option that homology needs to be realized as a quotient.

comment:25 in reply to: ↑ 24 ; follow-up: Changed 14 months ago by gh-mjungmath

Replying to tscrim:

Even if we have no examples, it still needs a doctest (even if it just showing that it has not been defined).

Yes, we can change the title if that indeed happens, but right now, let's leave it alone.

I don't like the idea of enforcing a homology_raw. Implementors should be free to implement what works best for them and their problem at hand as per John's comment. Things at the category level should be kept as generic as possible.

It would be better to have this as a generic implementation in the category by using some assumption on the chain complex and the corresponding morphisms. Of course, it would need a better name and could be the generic implementation, but I am not sure we want to force an option that homology needs to be realized as a quotient.

Have you checked my last commits? I already dropped most things you are referring to.

Instead of homology_raw, I have introduced two methods: lift_from_homology and reduce_to_homology which lifts an homology class to a representative and reduces a cycle to its homology class respectively. These can be overwritten depending on the implementation.

As for renaming: I really don't care. I just think that it is way smoother if the title fits the content. What I meant: you can change it back as soon as the implementation has been generalized, at which point the documentation needs to be refactored anyway.

comment:26 in reply to: ↑ 25 ; follow-up: Changed 14 months ago by tscrim

Replying to gh-mjungmath:

Replying to tscrim:

Even if we have no examples, it still needs a doctest (even if it just showing that it has not been defined).

Yes, we can change the title if that indeed happens, but right now, let's leave it alone.

I don't like the idea of enforcing a homology_raw. Implementors should be free to implement what works best for them and their problem at hand as per John's comment. Things at the category level should be kept as generic as possible.

It would be better to have this as a generic implementation in the category by using some assumption on the chain complex and the corresponding morphisms. Of course, it would need a better name and could be the generic implementation, but I am not sure we want to force an option that homology needs to be realized as a quotient.

Have you checked my last commits? I already dropped most things you are referring to.

Instead of homology_raw, I have introduced two methods: lift_from_homology and reduce_to_homology which lifts an homology class to a representative and reduces a cycle to its homology class respectively. These can be overwritten depending on the implementation.

Okay, I understand what you are trying to do. I didn't realize you were changing your approach with your last commit. It might be a slight abuse to have a functor for all n, but I think it should be fine.

As for renaming: I really don't care. I just think that it is way smoother if the title fits the content. What I meant: you can change it back as soon as the implementation has been generalized, at which point the documentation needs to be refactored anyway.

I am still a -1 on changing the title docstring of chain_complex.py. That file is for chain complexes. Just because we happen to have only bounded ones implemented doesn't mean we need to limit it right now.

comment:27 Changed 14 months ago by git

  • Commit changed from 41461f748100803f5951945560f49815c430740a to 57ee0af5f5f0c52dffe353c281352ccaa0b46649

Branch pushed to git repo; I updated commit sha1. New commits:

57ee0afTrac #31669: correct morphism

comment:28 Changed 14 months ago by git

  • Commit changed from 57ee0af5f5f0c52dffe353c281352ccaa0b46649 to a475f2a79b4444b0e83cdb9f40b709af1d91b5be

Branch pushed to git repo; I updated commit sha1. New commits:

a475f2aTrac #31669: make lift_from_homology entirely abstract

comment:29 Changed 14 months ago by gh-mjungmath

When #31691 has a positive review, I will add some examples for de Rham cohomology here.

comment:30 in reply to: ↑ 26 Changed 14 months ago by jhpalmieri

Replying to tscrim:

Replying to gh-mjungmath:

As for renaming: I really don't care. I just think that it is way smoother if the title fits the content. What I meant: you can change it back as soon as the implementation has been generalized, at which point the documentation needs to be refactored anyway.

I am still a -1 on changing the title docstring of chain_complex.py. That file is for chain complexes. Just because we happen to have only bounded ones implemented doesn't mean we need to limit it right now.

Regarding this, I don't know much about kenzo, but it is conceivable that it handles unbounded chain complexes, and I think we should leave the title of Sage's chain complex module as is, in case the Sage-kenzo interface develops further and we can directly access its chain complexes. (Kenzo certainly handles topological spaces which have nonzero homology in infinitely many dimensions, but I don't know the details of how it handles the associated chain complexes.)

comment:31 Changed 14 months ago by git

  • Commit changed from a475f2a79b4444b0e83cdb9f40b709af1d91b5be to 4cd7c037637491dbfb18b1b3c2dca39b2700221e

Branch pushed to git repo; I updated commit sha1. New commits:

4746ddbTrac #31691: turn mixed form algebra into de rham complex
fb8331aTrac #31691: fix doctest in manifold.py
566176aTrac #31691: new file + improved doc + cup product delegates to *
b2e40f9Trac #31669: Merge branch 't/31691/public/31691_de_rham_complex' into t/31669/category_of_chain_complexes___co_homology_functor
c66dd12Merge branch 'u/gh-mjungmath/category_of_chain_complexes___co_homology_functor' of trac.sagemath.org:sage into t/31669/category_of_chain_complexes___co_homology_functor
4cd7c03Trac #31669: add examples

comment:32 Changed 14 months ago by gh-mjungmath

  • Status changed from needs_work to needs_review

comment:33 Changed 14 months ago by gh-mjungmath

Ready for review.

comment:34 Changed 14 months ago by git

  • Commit changed from 4cd7c037637491dbfb18b1b3c2dca39b2700221e to 030873618ef95119bdc4eaedf71b3171bced826f

Branch pushed to git repo; I updated commit sha1. New commits:

0308736Trac #31669: minor doctest improvements

comment:35 Changed 14 months ago by jhpalmieri

Is #31691 a dependency of this ticket?

comment:36 follow-ups: Changed 14 months ago by tscrim

  • Dependencies set to #31691

Yes, I think it is.

Some comments:

Doctest failure:

sage -t --long --random-seed=0 src/sage/homology/hochschild_complex.py  # 1 doctest failed

I would use _n instead of __n as we don't need the name mangling.

A useful construction is Cat.or_subcategory(input_cat), which automatically returns Cat when input_cat=None.

comment:37 in reply to: ↑ 36 Changed 14 months ago by gh-mjungmath

Replying to tscrim:

Yes, I think it is.

Indeed. My mistake.

Some comments:

Doctest failure:

sage -t --long --random-seed=0 src/sage/homology/hochschild_complex.py  # 1 doctest failed

Saw it. I hope the Hochschild complex implementation provides a boundary map...

I would use _n instead of __n as we don't need the name mangling.

Check.

A useful construction is Cat.or_subcategory(input_cat), which automatically returns Cat when input_cat=None.

What do you propose?

comment:38 in reply to: ↑ 36 Changed 14 months ago by gh-mjungmath

Replying to tscrim:

A useful construction is Cat.or_subcategory(input_cat), which automatically returns Cat when input_cat=None.

Ah, you are probably referring to GCAlgebra. This or_subcategory seems also useful to improve the code for manifolds since this is similarly implemented as I did here.

comment:39 follow-up: Changed 14 months ago by gh-mjungmath

But it seems like this is done all over Sage:

def __init__(..., category=None):
    ...
    if category is None:
        category = SomeCategory()

comment:40 Changed 14 months ago by git

  • Commit changed from 030873618ef95119bdc4eaedf71b3171bced826f to 969d9e3c5ed31e86e423b218ea077f4307d632b1

Branch pushed to git repo; I updated commit sha1. New commits:

969d9e3Trac #31669: __n -> _n + differential alias for hochschild homology

comment:41 Changed 14 months ago by gh-mjungmath

Looks to me like morally green...?

comment:42 Changed 14 months ago by git

  • Commit changed from 969d9e3c5ed31e86e423b218ea077f4307d632b1 to ffc848a52c53756495bb9011c68079b443e886ea

Branch pushed to git repo; I updated commit sha1. New commits:

ffc848aTrac #31669: small documentation fix of #31691

comment:43 Changed 14 months ago by gh-mjungmath

Ready for review. Patchbot is 'green'.

comment:44 in reply to: ↑ 39 Changed 14 months ago by tscrim

Replying to gh-mjungmath:

But it seems like this is done all over Sage:

def __init__(..., category=None):
    ...
    if category is None:
        category = SomeCategory()

Yes, that is what I was referring too. However, just because it is used many places elsewhere doesn't mean you shouldn't use it. That is typically older code and is a weaker test. Someone could pass a weaker category than the code actually needs, which would be a problem.

comment:45 Changed 14 months ago by gh-mjungmath

I don't know whether is_subcategory is the state of the art here. Sometimes, categories are not compatible with each other. Or a subcategory (in the mathematical sense) is not recognized as such. I have a bad feeling that this can lead to undesired results.

comment:46 Changed 14 months ago by tscrim

This is what we want to use. Please make the change to use it. If categories are incompatible, then there is a bigger issue that this will alert you to.

comment:47 Changed 14 months ago by gh-mjungmath

I still don't think this is what we should use. For example, assume that the class represents an object in the category of groups. Now I want to inherit from this class and turn it into a ring. Passing Rings() to the initialization would then cause an error:

sage: Groups().or_subcategory(Rings())
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-38547a21b34f> in <module>
----> 1 Groups().or_subcategory(Rings())

/ext/sage/sage-9.2/local/lib/python3.8/site-packages/sage/categories/category.py in or_subcategory(self, category, join)
   1876         else:
   1877             if not category.is_subcategory(self):
-> 1878                 raise ValueError("Subcategory of `{}` required; got `{}`".format(self, category))
   1879             return category
   1880 
ValueError: Subcategory of `Category of groups` required; got `Category of rings

Even with join=True we get an undesired result:

sage: Groups().or_subcategory(Rings(), join=True)
Category of inverse rings

What we really want to do is overwrite the category in that case.

comment:48 Changed 14 months ago by tscrim

  • Reviewers set to Travis Scrimshaw
  • Status changed from needs_review to needs_work

That error is telling you that you are doing something mathematically nonsensical. A ring is not a (multiplicative) group because it doesn't have inverses. Thus, your example gives even more reason you want to use it.

comment:49 follow-up: Changed 14 months ago by gh-mjungmath

Right, Sage distinguishes between multiplicative and additive groups. Probably a bad example. The same error would occur for additive groups though, except that join=True gives what we want. But I am not sure whether we always want to join categories and never make it possible to overwrite them for inheritance purposes.

I am sure you can somehow construct another example that leads to something undesirable. Besides, there must be a reason why or_subcategory is literally never used for that purpose.

I'd appreciate an additional opinion here. Matthias?

comment:50 Changed 14 months ago by jhpalmieri

I don't have an opinion about this particular situation, but in my experience, Travis knows the category code well, and I try to follow his advice.

comment:51 in reply to: ↑ 49 ; follow-ups: Changed 14 months ago by tscrim

Replying to gh-mjungmath:

Right, Sage distinguishes between multiplicative and additive groups. Probably a bad example. The same error would occur for additive groups though, except that join=True gives what we want.

It does not result in an error:

sage: from sage.categories.additive_groups import AdditiveGroups
sage: AdditiveGroups().or_subcategory(Rings())
Category of rings

But I am not sure whether we always want to join categories and never make it possible to overwrite them for inheritance purposes.

I don't understand. Join categories are used all over the place in Sage. When creating a new category, we often (maybe even typically) build it as a join or a subcategory thereof.

I am sure you can somehow construct another example that leads to something undesirable.

If you do, then you are exposing a bug in the category hierarchy.

Besides, there must be a reason why or_subcategory is literally never used for that purpose.

This is used in many places in Sage:

uqtscrim@SMP-36PQ8T2:~/sage/src/sage$ grep -R -l "or_subcategory" *
algebras/lie_algebras/quotient.py
algebras/lie_algebras/nilpotent_lie_algebra.py
algebras/lie_algebras/structure_coefficients.py
algebras/lie_algebras/lie_algebra.py
algebras/lie_algebras/subalgebra.py
algebras/lie_algebras/abelian.py
algebras/tensor_algebra.py
algebras/lie_conformal_algebras/lie_conformal_algebra_with_basis.py
algebras/lie_conformal_algebras/graded_lie_conformal_algebra.py
algebras/lie_conformal_algebras/finitely_freely_generated_lca.py
algebras/lie_conformal_algebras/lie_conformal_algebra_with_structure_coefs.py
algebras/clifford_algebra.py
algebras/associated_graded.py
algebras/finite_dimensional_algebras/finite_dimensional_algebra.py
categories/examples/semigroups.py
categories/coxeter_groups.py
categories/category.py
combinat/free_module.py
combinat/diagram_algebras.py
combinat/posets/posets.py
combinat/crystals/subcrystal.py
combinat/crystals/virtual_crystal.py
combinat/combinat.py
groups/lie_gps/nilpotent_lie_group.py
groups/perm_gps/permgroup.py
groups/indexed_free_group.py
homology/simplicial_complex.py
homology/homology_vector_space_with_basis.py
manifolds/manifold.py
modules/with_basis/subquotient.py
modules/with_basis/morphism.py
monoids/indexed_free_monoid.py
rings/function_field/order.py
rings/function_field/valuation_ring.py
rings/function_field/differential.py
rings/function_field/function_field.py
rings/lazy_laurent_series_ring.py
rings/polynomial/ore_polynomial_ring.py
rings/polynomial/ore_function_field.py
rings/polynomial/polynomial_quotient_ring.py
rings/asymptotic/asymptotics_multivariate_generating_functions.py
sets/finite_set_maps.py
sets/recursively_enumerated_set.pyx
sets/non_negative_integers.py
tensor/modules/finite_rank_free_module.py

One of the most notable is in combinat/free_module.py, which is the base class of many algebras in Sage.

comment:52 in reply to: ↑ 51 Changed 14 months ago by gh-mjungmath

Replying to tscrim:

Replying to gh-mjungmath:

Right, Sage distinguishes between multiplicative and additive groups. Probably a bad example. The same error would occur for additive groups though, except that join=True gives what we want.

It does not result in an error:

sage: from sage.categories.additive_groups import AdditiveGroups
sage: AdditiveGroups().or_subcategory(Rings())
Category of rings

Mh, you are right, it works. But according to the documentation this input should be invalid, too:

or_subcategory(category=None, join=False)
Return category or self if category is None.

INPUT:

    category – a sub category of self, tuple/list thereof, or None

    join – a boolean (default: False)

In that case, the documentation should be revised.

Last edited 14 months ago by gh-mjungmath (previous) (diff)

comment:53 in reply to: ↑ 51 Changed 14 months ago by gh-mjungmath

Last edited 14 months ago by gh-mjungmath (previous) (diff)

comment:54 Changed 14 months ago by gh-mjungmath

Last edited 14 months ago by gh-mjungmath (previous) (diff)

comment:55 Changed 14 months ago by gh-mjungmath

I think the documentation of or_subcategory should be modified accordingly, at least the INPUT part.

Last edited 14 months ago by gh-mjungmath (previous) (diff)

comment:56 Changed 14 months ago by gh-mjungmath

I apologize for my stubbornness. :D

comment:57 Changed 14 months ago by git

  • Commit changed from ffc848a52c53756495bb9011c68079b443e886ea to 4bceb9b22e889380d36ad78097e82c921aa95309

Branch pushed to git repo; I updated commit sha1. New commits:

4bceb9bTrac #31669: use or_subcategory

comment:58 Changed 14 months ago by gh-mjungmath

Here we go, and thank you for your patience, Travis!

comment:59 Changed 14 months ago by gh-mjungmath

  • Status changed from needs_work to needs_review

comment:60 Changed 13 months ago by tscrim

  • Status changed from needs_review to positive_review

LGTM. Thank you.

comment:61 Changed 13 months ago by gh-mjungmath

Thank you for the review! :)

comment:62 Changed 13 months ago by vbraun

  • Branch changed from u/gh-mjungmath/category_of_chain_complexes___co_homology_functor to 4bceb9b22e889380d36ad78097e82c921aa95309
  • Resolution set to fixed
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.