Group, ring, etc. actions on objects - Coercion

Skip to content
Back to top
View this page
Edit this page

# Group, ring, etc. actions on objects

The terminology and notation used is suggestive of groups acting on sets, but this framework can be used for modules, algebras, etc.

A group action \(G \times S \rightarrow S\) is a functor from \(G\) to Sets.

Warning

An `Action` object only keeps a weak reference to the underlying set which is acted upon. This decision was made in Issue #715 in order to allow garbage collection within the coercion framework (this is where actions are mainly used) and avoid memory leaks.

Sage

    sage: from sage.categories.action import Action
    sage: class P: pass
    sage: A = Action(P(),P())
    sage: import gc
    sage: _ = gc.collect()
    sage: A
    <repr(<sage.categories.action.Action at 0x...>) failed:
     RuntimeError: This action acted on a set that became garbage collected>

Python

    >>> from sage.all import *
    >>> from sage.categories.action import Action
    >>> class P: pass
    >>> A = Action(P(),P())
    >>> import gc
    >>> _ = gc.collect()
    >>> A
    <repr(<sage.categories.action.Action at 0x...>) failed:
     RuntimeError: This action acted on a set that became garbage collected>

To avoid garbage collection of the underlying set, it is sufficient to create a strong reference to it before the action is created.

Sage

    sage: _ = gc.collect()
    sage: from sage.categories.action import Action
    sage: class P: pass
    sage: q = P()
    sage: A = Action(P(),q)
    sage: gc.collect()
    0
    sage: A
    Left action by <__main__.P ... at ...> on <__main__.P ... at ...>

[Python]

    >>> from sage.all import *
    >>> _ = gc.collect()
    >>> from sage.categories.action import Action
    >>> class P: pass
    >>> q = P()
    >>> A = Action(P(),q)
    >>> gc.collect()
    0
    >>> A
    Left action by <__main__.P ... at ...> on <__main__.P ... at ...>

AUTHOR:

- Robert Bradshaw: initial version

class sage.categories.action.Action

  Bases: `Functor`

  The action of `G` on `S`.

  INPUT:

  - `G` – a parent or Python type

  - `S` – a parent or Python type

  - `is_left` – boolean (default: `True`); whether elements of `G` are on the left

  - `op` – (default: `None`) operation. This is not used by `Action` itself, but other classes may use it

  G
  act(g, x)

    This is a consistent interface for acting on `x` by `g`, regardless of whether it’s a left or right action.

    If needed, `g` and `x` are converted to the correct parent.

    EXAMPLES:

    Sage

        sage: R.<x> = ZZ []
        sage: from sage.structure.coerce_actions import IntegerMulAction
        sage: A = IntegerMulAction(ZZ, R, True)   # Left action
        sage: A.act(5, x)
        5*x
        sage: A.act(int(5), x)
        5*x
        sage: A = IntegerMulAction(ZZ, R, False)  # Right action
        sage: A.act(5, x)
        5*x
        sage: A.act(int(5), x)
        5*x

    Python

        >>> from sage.all import *
        >>> R = ZZ ['x']; (x,) = R._first_ngens(1)
        >>> from sage.structure.coerce_actions import IntegerMulAction
        >>> A = IntegerMulAction(ZZ, R, True)   # Left action
        >>> A.act(Integer(5), x)
        5*x
        >>> A.act(int(Integer(5)), x)
        5*x
        >>> A = IntegerMulAction(ZZ, R, False)  # Right action
        >>> A.act(Integer(5), x)
        5*x
        >>> A.act(int(Integer(5)), x)
        5*x

  actor()
  codomain()
  domain()
  is_left()
  left_domain()
  op
  operation()
  right_domain()

class sage.categories.action.ActionEndomorphism

  Bases: `Morphism`

  The endomorphism defined by the action of one element.

  EXAMPLES:

  Sage

      sage: A = ZZ['x'].get_action(QQ, self_on_left=False, op=operator.mul)
      sage: A
      Left scalar multiplication by Rational Field
       on Univariate Polynomial Ring in x over Integer Ring
      sage: A(1/2)
      Action of 1/2 on Univariate Polynomial Ring in x over Integer Ring
      under Left scalar multiplication by Rational Field on Univariate
      Polynomial Ring in x over Integer Ring.

  Python

      >>> from sage.all import *
      >>> A = ZZ['x'].get_action(QQ, self_on_left=False, op=operator.mul)
      >>> A
      Left scalar multiplication by Rational Field
       on Univariate Polynomial Ring in x over Integer Ring
      >>> A(Integer(1)/Integer(2))
      Action of 1/2 on Univariate Polynomial Ring in x over Integer Ring
      under Left scalar multiplication by Rational Field on Univariate
      Polynomial Ring in x over Integer Ring.

class sage.categories.action.InverseAction

  Bases: `Action`

  An action that acts as the inverse of the given action.

  EXAMPLES:

  Sage

      sage: V = QQ^3                                                                  # needs sage.modules
      sage: v = V((1, 2, 3))                                                          # needs sage.modules
      sage: cm = get_coercion_model()

      sage: # needs sage.modules
      sage: a = cm.get_action(V, QQ, operator.mul)
      sage: a
      Right scalar multiplication by Rational Field
       on Vector space of dimension 3 over Rational Field
      sage: ~a
      Right inverse action by Rational Field
       on Vector space of dimension 3 over Rational Field
      sage: (~a)(v, 1/3)
      (3, 6, 9)

      sage: # needs sage.modules
      sage: b = cm.get_action(QQ, V, operator.mul)
      sage: b
      Left scalar multiplication by Rational Field
       on Vector space of dimension 3 over Rational Field
      sage: ~b
      Left inverse action by Rational Field
       on Vector space of dimension 3 over Rational Field
      sage: (~b)(1/3, v)
      (3, 6, 9)

      sage: c = cm.get_action(ZZ, list, operator.mul)
      sage: c
      Left action by Integer Ring on <... 'list'>
      sage: ~c
      Traceback (most recent call last):
      ...
      TypeError: no inverse defined for Left action by Integer Ring on <... 'list'>

  Python

      >>> from sage.all import *
      >>> V = QQ**Integer(3)                                                                  # needs sage.modules
      >>> v = V((Integer(1), Integer(2), Integer(3)))                                                          # needs sage.modules
      >>> cm = get_coercion_model()

      >>> # needs sage.modules
      >>> a = cm.get_action(V, QQ, operator.mul)
      >>> a
      Right scalar multiplication by Rational Field
       on Vector space of dimension 3 over Rational Field
      >>> ~a
      Right inverse action by Rational Field
       on Vector space of dimension 3 over Rational Field
      >>> (~a)(v, Integer(1)/Integer(3))
      (3, 6, 9)

      >>> # needs sage.modules
      >>> b = cm.get_action(QQ, V, operator.mul)
      >>> b
      Left scalar multiplication by Rational Field
       on Vector space of dimension 3 over Rational Field
      >>> ~b
      Left inverse action by Rational Field
       on Vector space of dimension 3 over Rational Field
      >>> (~b)(Integer(1)/Integer(3), v)
      (3, 6, 9)

      >>> c = cm.get_action(ZZ, list, operator.mul)
      >>> c
      Left action by Integer Ring on <... 'list'>
      >>> ~c
      Traceback (most recent call last):
      ...
      TypeError: no inverse defined for Left action by Integer Ring on <... 'list'>

  codomain()

class sage.categories.action.PrecomposedAction

  Bases: `Action`

  A precomposed action first applies given maps, and then applying an action to the return values of the maps.

  EXAMPLES:

  We demonstrate that an example discussed on Issue #14711 did not become a problem:

  Sage

      sage: # needs sage.libs.flint sage.modular
      sage: E = ModularSymbols(11).2
      sage: s = E.modular_symbol_rep()
      sage: del E,s
      sage: import gc
      sage: _ = gc.collect()
      sage: E = ModularSymbols(11).2
      sage: v = E.manin_symbol_rep()
      sage: c,x = v[0]
      sage: y = x.modular_symbol_rep()
      sage: coercion_model.get_action(QQ, parent(y), op=operator.mul)
      Left scalar multiplication by Rational Field
       on Abelian Group of all Formal Finite Sums over Rational Field
       with precomposition on right by Coercion map:
        From: Abelian Group of all Formal Finite Sums over Integer Ring
        To:   Abelian Group of all Formal Finite Sums over Rational Field

  Python

      >>> from sage.all import *
      >>> # needs sage.libs.flint sage.modular
      >>> E = ModularSymbols(Integer(11)).gen(2)
      >>> s = E.modular_symbol_rep()
      >>> del E,s
      >>> import gc
      >>> _ = gc.collect()
      >>> E = ModularSymbols(Integer(11)).gen(2)
      >>> v = E.manin_symbol_rep()
      >>> c,x = v[Integer(0)]
      >>> y = x.modular_symbol_rep()
      >>> coercion_model.get_action(QQ, parent(y), op=operator.mul)
      Left scalar multiplication by Rational Field
       on Abelian Group of all Formal Finite Sums over Rational Field
       with precomposition on right by Coercion map:
        From: Abelian Group of all Formal Finite Sums over Integer Ring
        To:   Abelian Group of all Formal Finite Sums over Rational Field

  codomain()
  domain()
  left_precomposition

    The left map to precompose with, or `None` if there is no left precomposition map.

  right_precomposition

    The right map to precompose with, or `None` if there is no right precomposition map.