Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add category FreeModules (without distinguished basis) #30164

Open
mkoeppe opened this issue Jul 17, 2020 · 14 comments
Open

Add category FreeModules (without distinguished basis) #30164

mkoeppe opened this issue Jul 17, 2020 · 14 comments

Comments

@mkoeppe
Copy link
Member

mkoeppe commented Jul 17, 2020

From sage.tensor.modules.finite_rank_free_module:

.. TODO::

    - implement submodules
    - create a FreeModules category (cf. the *TODO* statement in the
      documentation of :class:`~sage.categories.modules.Modules`: *Implement
      a ``FreeModules(R)`` category, when so prompted by a concrete use case*)

Also we can define a functor from FreeModules(R) to FreeModulesWithBasis(R), which picks a basis (either arbitrary or optionally a parameter of the functor) for every module. This is a section of the forgetful functor from FreeModulesWithBasis(R) to FreeModules(R).

CC: @tscrim @egourgoulhon @mjungmath

Component: linear algebra

Issue created by migration from https://trac.sagemath.org/ticket/30164

@mkoeppe mkoeppe added this to the sage-9.2 milestone Jul 17, 2020
@tscrim
Copy link
Collaborator

tscrim commented Jul 17, 2020

comment:1

I am not sure I agree with having this category. I don't see the use case why we would need this category as there are basically only one concrete implementation: an n-dimensional free module. It is not until you start selecting and manipulating bases that you start having the possibility for different concrete implementations. At least, I see better ways of doing this rather than a new category that I don't foresee having much room to expand.

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 19, 2020

comment:2

Perhaps, in fact, this category should define (as an abstract method) the method isomorphism_with_fixed_basis proposed in #30094.

@tscrim
Copy link
Collaborator

tscrim commented Jul 24, 2020

comment:3

My thought is that would be better left to the concrete implementation. It almost seems like you are proposing lifting the entire concrete implementation of FiniteRankFreeModule to the category, at which point the category becomes the parent, rather than the abstraction of the properties you want the parent to have. I feel like that might make the code maintenance harder because the two concepts are becoming too blurred together.

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 25, 2020

comment:4

Replying to @tscrim:

My thought is that would be better left to the concrete implementation. It almost seems like you are proposing lifting the entire concrete implementation of FiniteRankFreeModule to the category, at which point the category becomes the parent, rather than the abstraction of the properties you want the parent to have.

There is certainly a subtle line that separates expectations for a category's parent/element methods from those for abstract base classes.

I would think that user-facing methods that expose a mathematical concept/theorem do belong to the category.

Concretely, an implementation detail certainly is how a basis is designated or represented. FiniteRankFreeModule uses a custom class for representing a basis and accepts symbols (strings) as designators for a basis. I agree that it would make maintenance harder if on the category level we tried to define this.

However, we can focus on the theorem that in a free module we can choose a basis and that therefore there exists a free module isomorphism with a free module with the same base ring and rank. And this is exactly what is expressed by the method isomorphism_with_fixed_basis -- without having to expose the concrete concept of a basis on the category level.

I would generalize the method from #30094, isomorphism_with_fixed_basis(self, basis, codomain=None), so that the parameter basis becomes optional - and when not provided uses some basis (such as the default basis if it has been set, or like some_elements does, to set the default basis to something arbitrary).

The category's parent method would use the compatible signature
isomorphism_with_fixed_basis(self, *, codomain=None). It would be an optional abstract method.

@tscrim
Copy link
Collaborator

tscrim commented Jul 25, 2020

comment:5

Replying to @mkoeppe:

Replying to @tscrim:

My thought is that would be better left to the concrete implementation. It almost seems like you are proposing lifting the entire concrete implementation of FiniteRankFreeModule to the category, at which point the category becomes the parent, rather than the abstraction of the properties you want the parent to have.

There is certainly a subtle line that separates expectations for a category's parent/element methods from those for abstract base classes.

I would think that user-facing methods that expose a mathematical concept/theorem do belong to the category.

Concretely, an implementation detail certainly is how a basis is designated or represented. FiniteRankFreeModule uses a custom class for representing a basis and accepts symbols (strings) as designators for a basis. I agree that it would make maintenance harder if on the category level we tried to define this.

The maintenance aspect with categories is something that I worry a bit more about. I have gotten a lot of questions asking how the category framework works with its black magic. Most of the times I point to a concrete implementation and the key methods someone needs to implement.

Additionally, abstracting free modules will not lead to a combinatorial explosion of classes involving different combinations of axioms (which is the main reason why we have this framework). We see this with CombinatorialFreeModule; many implementations of different objects use that implementation for the underlying module rather than the abstraction in ModulesWithBasis.

However, we can focus on the theorem that in a free module we can choose a basis and that therefore there exists a free module isomorphism with a free module with the same base ring and rank. And this is exactly what is expressed by the method isomorphism_with_fixed_basis -- without having to expose the concrete concept of a basis on the category level.

I would generalize the method from #30094, isomorphism_with_fixed_basis(self, basis, codomain=None), so that the parameter basis becomes optional - and when not provided uses some basis (such as the default basis if it has been set, or like some_elements does, to set the default basis to something arbitrary).

The difference with some_elements would be that those elements are not a defining property of the set. Having a default basis sounds like a concrete implementation detail, and we don't want to impose a fixed semantic for basis(). This would lead to a conflict between FiniteRankFreeModule and anything in ModulesWithBasis (which would naturally be a subcategory of FreeModules).

The category's parent method would use the compatible signature
isomorphism_with_fixed_basis(self, *, codomain=None). It would be an optional abstract method.

This feels more like code bloat to me right now. At least, I cannot think of a definitive use-case for this over having a common ABC.

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 25, 2020

comment:6

Replying to @tscrim:

I would generalize the method from #30094, isomorphism_with_fixed_basis(self, basis, codomain=None), so that the parameter basis becomes optional - and when not provided uses some basis (such as the default basis if it has been set, or like some_elements does, to set the default basis to something arbitrary).

The difference with some_elements would be that those elements are not a defining property of the set. Having a default basis sounds like a concrete implementation detail, and we don't want to impose a fixed semantic for basis(). This would lead to a conflict between FiniteRankFreeModule and anything in ModulesWithBasis (which would naturally be a subcategory of FreeModules).

In case it did not become clear, in my proposal I do NOT define a semantic for basis() at all.

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 25, 2020

comment:7

Replying to @tscrim:

The maintenance aspect with categories is something that I worry a bit more about. I have gotten a lot of questions asking how the category framework works with its black magic. Most of the times I point to a concrete implementation and the key methods someone needs to implement.

Could you elaborate on the maintenance aspect? This sounds to me just like a documentation problem. Would it not just suffice to add some comments to an implementation class what methods are already provided by the required category?

Additionally, abstracting free modules will not lead to a combinatorial explosion of classes involving different combinations of axioms (which is the main reason why we have this framework). We see this with CombinatorialFreeModule; many implementations of different objects use that implementation for the underlying module rather than the abstraction in ModulesWithBasis.

I have noticed that, but the problem is that we have multiple incomplete and incompatible implementations of linear algebra. CombinatorialFreeModule does not know about linear forms, FiniteRankFreeModule does not know about triangular morphisms, ...

However, we can focus on the theorem that in a free module we can choose a basis and that therefore there exists a free module isomorphism with a free module with the same base ring and rank. And this is exactly what is expressed by the method isomorphism_with_fixed_basis -- without having to expose the concrete concept of a basis on the category level.

I would generalize the method from #30094, isomorphism_with_fixed_basis(self, basis, codomain=None), so that the parameter basis becomes optional - and when not provided uses some basis (such as the default basis if it has been set, or like some_elements does, to set the default basis to something arbitrary).

The difference with some_elements would be that those elements are not a defining property of the set. Having a default basis sounds like a concrete implementation detail, and we don't want to impose a fixed semantic for basis(). This would lead to a conflict between FiniteRankFreeModule and anything in ModulesWithBasis (which would naturally be a subcategory of FreeModules).

The category's parent method would use the compatible signature
isomorphism_with_fixed_basis(self, *, codomain=None). It would be an optional abstract method.

This feels more like code bloat to me right now. At least, I cannot think of a definitive use-case for this over having a common ABC.

My immediate application is #30198.

@tscrim
Copy link
Collaborator

tscrim commented Jul 26, 2020

comment:8

Replying to @mkoeppe:

Replying to @tscrim:

The maintenance aspect with categories is something that I worry a bit more about. I have gotten a lot of questions asking how the category framework works with its black magic. Most of the times I point to a concrete implementation and the key methods someone needs to implement.

Could you elaborate on the maintenance aspect? This sounds to me just like a documentation problem. Would it not just suffice to add some comments to an implementation class what methods are already provided by the required category?

For someone who doesn't know the code, if you look at an object X, how do you find the methods? The problem is that most of the classes in its MRO are dynamically created, so they don't exist as actual code. You also cannot easily point to specific points where to look. Generic answers are not very helpful, and there is documentation (including a number of tutorials), but it is a lot to process in one go. Now more often than not, the benefits of having the generic code outweigh the extra disassociation between the implementation and the use, but I don't see that here.

Additionally, abstracting free modules will not lead to a combinatorial explosion of classes involving different combinations of axioms (which is the main reason why we have this framework). We see this with CombinatorialFreeModule; many implementations of different objects use that implementation for the underlying module rather than the abstraction in ModulesWithBasis.

I have noticed that, but the problem is that we have multiple incomplete and incompatible implementations of linear algebra. CombinatorialFreeModule does not know about linear forms, FiniteRankFreeModule does not know about triangular morphisms, ...

Not all of the features should necessarily be compatible because they are designed for different purposes. Sometimes these unaoidaby require specific implementation details. That being said, there are definitely missing features that could be lifted to an ABC, which can easily handle the generality you want.

Categories are heavier objects than ABCs, which are still effective at modeling the mathematics. There are more assumptions and a bigger ecosystem to worry about. For instance, you have to make sure that you cannot have a category for FreeModulesWithBasis as an object in ModulesWithBasis is free by definition. You have to make sure there are no possible convention conflicts (cf. metric).

The category's parent method would use the compatible signature
isomorphism_with_fixed_basis(self, *, codomain=None). It would be an optional abstract method.

I feel like this method needs to handle a basis parameter. If you use a default_basis(), then you need a method that should be named basis() to create a basis. Also, something with a set default_basis() is in ModulesWithBasis essentially as the default basis is a distinguished basis. Not quite, but close. You have to also be a little more careful about what can happen when the default basis changes.

This feels more like code bloat to me right now. At least, I cannot think of a definitive use-case for this over having a common ABC.

My immediate application is #30198.

Why would you want a category over an ABC?

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 26, 2020

comment:9

Thanks a lot for your explanations.

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 26, 2020

comment:10

Replying to @tscrim:

Replying to @mkoeppe:

The category's parent method would use the compatible signature
isomorphism_with_fixed_basis(self, *, codomain=None). It would be an optional abstract method.

I feel like this method needs to handle a basis parameter. If you use a default_basis(), then you need a method that should be named basis() to create a basis. Also, something with a set default_basis() is in ModulesWithBasis essentially as the default basis is a distinguished basis. Not quite, but close. You have to also be a little more careful about what can happen when the default basis changes.

I think you're missing that I want the category (or, if you will, ABC) to provide the abstract method so that the protocol is specified, but not provide an implementation. Thus no methods basis() or default_basis() are assumed.

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 27, 2020

comment:11

In a slightly different direction: I think it should also be clarified what exactly the category Modules(R).FiniteDimensional() is.

@mkoeppe
Copy link
Member Author

mkoeppe commented Jul 28, 2020

comment:12

Replying to @mkoeppe:

In a slightly different direction: I think it should also be clarified what exactly the category Modules(R).FiniteDimensional() is.

Continuing with this question on #30233

@tscrim
Copy link
Collaborator

tscrim commented Jul 29, 2020

comment:13

Your proposed method isomorphism_with_fixed_basis would require the target object to be specified, which means a specific implementation. The other option I see would be that it just requires the image to have some fixed basis, but I don't see how that would be different than a basis implementation of the generic free module. Basically, this feels like it requires a concrete implementation.

@mkoeppe mkoeppe modified the milestones: sage-9.2, sage-9.3 Aug 13, 2020
@mkoeppe
Copy link
Member Author

mkoeppe commented Feb 13, 2021

comment:15

Setting new milestone based on a cursory review of ticket status, priority, and last modification date.

@mkoeppe mkoeppe modified the milestones: sage-9.3, sage-9.4 Feb 13, 2021
@mkoeppe mkoeppe modified the milestones: sage-9.4, sage-9.5 Jul 19, 2021
@mkoeppe mkoeppe modified the milestones: sage-9.5, sage-9.6 Dec 14, 2021
@mkoeppe mkoeppe modified the milestones: sage-9.6, sage-9.7 Mar 5, 2022
@mkoeppe mkoeppe modified the milestones: sage-9.7, sage-9.8 Aug 31, 2022
@mkoeppe mkoeppe modified the milestones: sage-9.8, sage-9.9 Jan 7, 2023
@mkoeppe mkoeppe removed this from the sage-10.0 milestone Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants