Opened 10 months ago

Last modified 5 months ago

#31276 new enhancement

Tensor Product Method for FiniteRankFreeModule

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

Status badges

Description (last modified by gh-mjungmath)

We introduce the methods tensor_product and tensor_power as per #30373.

Furthermore, we introduce a method tensor_productfor elements.

Things that are probably nice to get to work:

sage: M = FiniteRankFreeModule(QQ, 2)
sage: N = FiniteRankFreeModule(QQ, 3)
sage: M.tensor(N)
sage: M.tensor(M)
sage: M.tensor(M.tensor_module(1,2))
sage: N.tensor(M.tensor_module(1,2))
sage: M.tensor_module(1,2).tensor(M)
sage: N.tensor_module(1,2).tensor(M)
sage: M.tensor_module(1,1).tensor(M.tensor_module(1,2))
sage: N.tensor_module(1,1).tensor(M.tensor_module(1,2))
sage: M.tensor_power(3)
sage: M.tensor_module(1,2).tensor_power(3)

and for elements respectively.

Change History (12)

comment:1 follow-up: Changed 10 months ago by gh-mjungmath

  • Cc jhpalmieri mkoeppe added

Turns out that this is not as easy as expected.

  1. FiniteRankFreeModule has no attribute (or method) tensor_type in contrast to TensorFreeModule. If it had, one could just add the tensor types and return the corresponding module. However, I see no point why FiniteRankFreeModule should have such a method/attribute apart from this single purpose.
  2. Trying to wrap the patch over, it turns out that TensorFreeModule inherits from FiniteRankFreeModule and therefore inherits all methods and attributes. So far so good, but as I understand the code, instances of TensorFreeModule are not intended to use most of these methods. FiniteRankFreeModule is intended to be the "control center" that takes care of things. This leads to somewhat strange (and probably unwanted) behavior:
    sage: M = FiniteRankFreeModule(QQ, 3)
    sage: T11 = M.tensor_module(1, 1)
    sage: T11 is M.tensor_module(1, 1)
    True
    sage: T11 is T11.tensor_module(1, 1)
    False
    

and

sage: M = FiniteRankFreeModule(ZZ, 2)
sage: e = M.basis('e')
sage: f = M.basis('f', from_family=(e[0]-e[1], -2*e[0]+3*e[1]))
sage: M.change_of_basis(e, f)
Automorphism of the Rank-2 free module over the Integer Ring
sage: T11 = M.tensor_module(1, 1)
sage: T11.change_of_basis(e, f)
Traceback (most recent call last):
...
TypeError: Basis (e_0,e_1) on the Rank-2 free module over the Integer Ring is not a basis of the Free module of type-(1,1) tensors on the Rank-2 free module over the Integer Ring

The latter might be acceptable because e and f are, strictly speaking, no bases of T11. However, this methods has then no use in TensorFreeModule. Nevertheless, these are just two examples and there is a lot more. Furthermore, TensorFreeModule initializes a bunch of dictionaries, sets and further attributes that are not used anywhere else. I think this should be changed.

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

comment:2 in reply to: ↑ 1 ; follow-up: Changed 10 months ago by egourgoulhon

Replying to gh-mjungmath:

  1. Trying to wrap the patch over, it turns out that TensorFreeModule inherits from FiniteRankFreeModule and therefore inherits all methods and attributes. So far so good, but as I understand the code, instances of TensorFreeModule are not intended to use most of these methods.

Indeed, so maybe a better inheritance structure should be devised.

FiniteRankFreeModule is intended to be the "control center" that takes care of things.

Yes. This avoids information redundancy, in particular regarding the bases.

This leads to somewhat strange (and probably unwanted) behavior:

sage: M = FiniteRankFreeModule(QQ, 3)
sage: T11 = M.tensor_module(1, 1)
sage: T11 is M.tensor_module(1, 1)
True
sage: T11 is T11.tensor_module(1, 1)
False

Why do you call this strange behavior? Both answers, True and False, are mathematically correct.

and

sage: M = FiniteRankFreeModule(ZZ, 2)
sage: e = M.basis('e')
sage: f = M.basis('f', from_family=(e[0]-e[1], -2*e[0]+3*e[1]))
sage: M.change_of_basis(e, f)
Automorphism of the Rank-2 free module over the Integer Ring
sage: T11 = M.tensor_module(1, 1)
sage: T11.change_of_basis(e, f)
Traceback (most recent call last):
...
TypeError: Basis (e_0,e_1) on the Rank-2 free module over the Integer Ring is not a basis of the Free module of type-(1,1) tensors on the Rank-2 free module over the Integer Ring

The latter might be acceptable because e and f are, strictly speaking, no bases of T11.

Yes, the TypeError sounds correct here.

However, this methods has then no use in TensorFreeModule. Nevertheless, these are just two examples and there is a lot more. Furthermore, TensorFreeModule initializes a bunch of dictionaries, sets and further attributes that are not used anywhere else.

You mean those attributes inherited from FiniteRankFreeModule?

comment:3 in reply to: ↑ 2 ; follow-up: Changed 10 months ago by gh-mjungmath

Replying to egourgoulhon:

Why do you call this strange behavior? Both answers, True and False, are mathematically correct.

Of course, right, it's the tensor module of the tensor module. But we also have:

sage: T22 = T11.tensor_module(1, 1)
sage: T22 is M.tensor_module(1, 1)
False

But one could argue here that these objects are different mathematical entities which are just isomorphic. On the other hand, they behave exactly the same as instances of TensorFreeModule.

You mean those attributes inherited from FiniteRankFreeModule?

Indeed. At least those that are not needed in TensorFreeModule.

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

comment:4 in reply to: ↑ 3 ; follow-up: Changed 10 months ago by egourgoulhon

Replying to gh-mjungmath:

Replying to egourgoulhon:

Why do you call this strange behavior? Both answers, True and False, are mathematically correct.

Of course, right, it's the tensor module of the tensor module. But we also have:

sage: T22 = T11.tensor_module(1, 1)
sage: T22 is M.tensor_module(1, 1)
False

I guess you mean

sage: T22 = T11.tensor_module(1, 1)
sage: T22 is M.tensor_module(2, 2)
False

What would be the purpose to implement such an identification? Do you have a use case in mind?

comment:5 in reply to: ↑ 4 ; follow-up: Changed 10 months ago by gh-mjungmath

Replying to egourgoulhon:

I guess you mean

sage: T22 = T11.tensor_module(1, 1)
sage: T22 is M.tensor_module(2, 2)
False

Yes, indeed...it was late yesterday..

What would be the purpose to implement such an identification? Do you have a use case in mind?

Alright, it should be fine. I totally missed the tensor module inception going on here. Then, it would be nice to have at least the canonical isomorphism from T11.tensor_module(1, 1) to M.tensor_module(2, 2) implemented, in particular make the following work:

sage: t = T11.tensor((1,1))
sage: M.tensor_module(2,2)(t)
Traceback (most recent call last):
...
StopIteration:

and the other way around.

Nevertheless, what do we do about my first point in comment:1? An instanceof check for each object coming in?

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

Replying to gh-mjungmath:

Replying to egourgoulhon:

Nevertheless, what do we do about my first point in comment:1? An instanceof check for each object coming in?

I see no reason why FiniteRankFreeModule should not have a tensor_type() method (returning (1? 0)), as TensorFreeModule.

Version 0, edited 10 months ago by egourgoulhon (next)

comment:7 Changed 10 months ago by gh-mjungmath

Alright, then let's do this. This method would also be beneficial to introduce the above coercion.

comment:8 Changed 10 months ago by gh-mjungmath

  • Description modified (diff)

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

comment:10 in reply to: ↑ 9 Changed 10 months ago by egourgoulhon

Replying to mkoeppe:

Relevant previous discussions: #30241, https://trac.sagemath.org/ticket/30229#comment:6

Thanks for pointing out this! Especially the comment:2 in the second ticket provides details for the "Yes. This avoids information redundancy, in particular regarding the bases" in comment:2 of the current ticket.

comment:11 Changed 10 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.

comment:12 Changed 5 months ago by mkoeppe

  • Milestone changed from sage-9.4 to sage-9.5
Note: See TracTickets for help on using tickets.