Opened 15 months ago

Last modified 3 months ago

#30245 new enhancement

FreeModuleAutomorphism should not inherit from FreeModuleTensor

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

Status badges

Description (last modified by mkoeppe)

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 (12)

comment:1 Changed 15 months ago by gh-mjungmath

Do you have an explicit example what goes wrong here?

comment:2 Changed 15 months ago by mkoeppe

  • Description modified (diff)

comment:3 Changed 15 months ago by mkoeppe

  • Description modified (diff)

comment:4 Changed 15 months ago by mkoeppe

  • Authors set to Matthias Koeppe

comment:5 Changed 15 months ago by mkoeppe

  • Description modified (diff)

comment:6 Changed 15 months ago by mkoeppe

  • Description modified (diff)

comment:7 Changed 15 months ago by egourgoulhon

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 15 months ago by mkoeppe

Thanks, that's an important point.

comment:9 Changed 14 months ago by mkoeppe

  • Milestone changed from sage-9.2 to sage-9.3

comment:10 Changed 9 months ago by mkoeppe

  • Authors Matthias Koeppe deleted

comment:11 Changed 8 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 3 months ago by mkoeppe

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