Opened 10 months ago

Last modified 3 months ago

#30164 new enhancement

Add category FreeModules (without distinguished basis)

Reported by: mkoeppe Owned by:
Priority: major Milestone: sage-9.4
Component: linear algebra Keywords:
Cc: tscrim, egourgoulhon, gh-mjungmath Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges

Description

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*)

Change History (15)

comment:1 Changed 10 months ago by tscrim

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.

comment:2 Changed 10 months ago by mkoeppe

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

comment:3 follow-up: Changed 10 months ago by 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. I feel like that might make the code maintenance harder because the two concepts are becoming too blurred together.

comment:4 in reply to: ↑ 3 ; follow-up: Changed 10 months ago by 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.

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.

comment:5 in reply to: ↑ 4 ; follow-ups: Changed 10 months ago by tscrim

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.

comment:6 in reply to: ↑ 5 Changed 10 months ago by mkoeppe

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.

comment:7 in reply to: ↑ 5 ; follow-up: Changed 10 months ago by 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?

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.

comment:8 in reply to: ↑ 7 ; follow-up: Changed 10 months ago by tscrim

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?

comment:9 Changed 10 months ago by mkoeppe

Thanks a lot for your explanations.

comment:10 in reply to: ↑ 8 Changed 10 months ago by mkoeppe

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.

comment:11 follow-up: Changed 10 months ago by mkoeppe

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

comment:12 in reply to: ↑ 11 Changed 10 months ago by mkoeppe

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

comment:13 Changed 10 months ago by tscrim

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.

comment:14 Changed 9 months ago by mkoeppe

  • Milestone changed from sage-9.2 to sage-9.3

comment:15 Changed 3 months ago by mkoeppe

  • Milestone changed from sage-9.3 to sage-9.4

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

Note: See TracTickets for help on using tickets.