Opened 2 years ago

Last modified 3 months ago

#30245 new enhancement

FreeModuleAutomorphism should not inherit from FreeModuleTensor

Reported by: Matthias Köppe Owned by:
Priority: major Milestone: sage-9.8
Component: linear algebra Keywords:
Cc: Eric Gourgoulhon, Travis Scrimshaw, Michael Jung Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges

Description (last modified by Matthias Köppe)

It inherits _add_ and _sub_ methods that make no sense in the coercion system. These methods are guaranteed by the coercion system to get elements of the parent, and are supposed to give elements as well:

sage: M = FiniteRankFreeModule(ZZ, 2, name='M')
sage: G = M.general_linear_group()
sage: T11 = M.tensor_module(1, 1)
sage: from sage.structure.coerce import CoercionModel
sage: cm = CoercionModel()
sage: cm.explain(G, G, operator.add)
Identical parents, arithmetic performed immediately.
Result lives in General linear group of the Rank-2 free module M over the Integer Ring
General linear group of the Rank-2 free module M over the Integer Ring

Also other operations inherited from the module are problematic because they are not type-stable. The result of operations is supposed to depend only on the parents of the operands, but:

sage: cm.explain(ZZ, G, operator.mul)
Action discovered.
    Left Integer Multiplication by Integer Ring on General linear group of the Rank-2 free module M over the Integer Ring
Result lives in General linear group of the Rank-2 free module M over the Integer Ring
General linear group of the Rank-2 free module M over the Integer Ring
sage: a = G.an_element()
sage: 2 * a
Type-(1,1) tensor on the Rank-2 free module M over the Integer Ring
sage: -a
Automorphism of the Rank-2 free module M over the Integer Ring
sage: (-1)*a
Automorphism of the Rank-2 free module M over the Integer Ring
sage: 0 *a
Automorphism of the Rank-2 free module M over the Integer Ring

(Note in particular the scary last one...)

There is already a coercion map from FreeModuleLinearGroup, sending a FreeModuleAutomorphism to the underlying tensor:

sage: M = FiniteRankFreeModule(ZZ, 2, name='M')
sage: G = M.general_linear_group()
sage: T11 = M.tensor_module(1, 1)
sage: T11.coerce_map_from(G)
Coercion map:
  From: General linear group of the Rank-2 free module M over the Integer Ring
  To:   Free module of type-(1,1) tensors on the Rank-2 free module M over the Integer Ring
sage: _.category()
Category of elements of Set of Morphisms from General linear group of the Rank-2 free module M over the Integer Ring to Free module of type-(1,1) tensors on the Rank-2 free module M over the Integer Ring in Category of sets

This coercion can handle all of the module operations if we let it.

In this ticket, we change the relationship of FreeModuleAutomorphism and FreeModuleTensor from "is-a" to "has-a".

Making this change will also allow us to simplify FreeModuleTensor._add_ and _sub_: Currently they go through self._fmodule.tensor_from_comp() when they really should use self._new_instance.

Change History (15)

comment:1 Changed 2 years ago by Michael Jung

Do you have an explicit example what goes wrong here?

comment:2 Changed 2 years ago by Matthias Köppe

Description: modified (diff)

comment:3 Changed 2 years ago by Matthias Köppe

Description: modified (diff)

comment:4 Changed 2 years ago by Matthias Köppe

Authors: Matthias Koeppe

comment:5 Changed 2 years ago by Matthias Köppe

Description: modified (diff)

comment:6 Changed 2 years ago by Matthias Köppe

Description: modified (diff)

comment:7 Changed 2 years ago by Eric Gourgoulhon

I agree with most of the ticket description, except for

Making this change will also allow us to simplify FreeModuleTensor._add_ and _sub_: Currently they go through self._fmodule.tensor_from_comp() when they really should use self._new_instance.

Indeed, at this stage, self._fmodule.tensor_from_comp() is still required in FreeModuleTensor._add_() because it deals properly with the tensor (anti)symmetries, via the code of CompWithSym.__add__(). For instance, if t1 is a (4,0)-tensor with that is fully symmetric, and t2 is a (4,0)-tensor that is symmetric on the first two indices and antisymmetric on the last two ones, t1 + t2 is symmetric only on the first two indices, i.e. its (anti)symmetries are different from those of t1 or t2. They thus cannot be generated by self._new_instance (in the current stage).

comment:8 Changed 2 years ago by Matthias Köppe

Thanks, that's an important point.

comment:9 Changed 2 years ago by Matthias Köppe

Milestone: sage-9.2sage-9.3

comment:10 Changed 23 months ago by Matthias Köppe

Authors: Matthias Koeppe

comment:11 Changed 22 months ago by Matthias Köppe

Milestone: sage-9.3sage-9.4

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

comment:12 Changed 17 months ago by Matthias Köppe

Milestone: sage-9.4sage-9.5

comment:13 Changed 12 months ago by Matthias Köppe

Milestone: sage-9.5sage-9.6

comment:14 Changed 9 months ago by Matthias Köppe

Milestone: sage-9.6sage-9.7

comment:15 Changed 3 months ago by Matthias Köppe

Milestone: sage-9.7sage-9.8
Note: See TracTickets for help on using tickets.