sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.31k stars 449 forks source link

AffineGroup elements should be hashable #38381

Open wphooper opened 1 month ago

wphooper commented 1 month ago

Problem Description

Currently AffineGroup elements do not implement hash and so can not be used as dictionary keys.

Currently the internal variables of AffineGroupElement are mutable, but the matrix method is cached suggesting that the values are expected to be immutable. This makes it possible to produce (far fetched) bugs where matrix returns something incompatible with the current state of the transformation:

sage: from sage.groups.affine_gps.affine_group import AffineGroup
sage: G = AffineGroup(2, QQ)
sage: G
Affine Group of degree 2 over Rational Field
sage: g = G([[1, 2], [3, 4]], [5,6])
sage: g.matrix()
[1 2|5]
[3 4|6]
[---+-]
[0 0|1]
sage: g.A()[0,0] = 9
sage: g.A()[0,0] = 9
sage: g
      [9 2]     [5]
x |-> [3 4] x + [6]
sage: g.matrix()
[1 2|5]
[3 4|6]
[---+-]
[0 0|1]
sage: hash(g)
TypeError

Proposed Solution

  1. Make affine group elements immutable by calling set_immutable() on the parameters _A and _b in the constructor.
  2. Implement a hash.

Alternatives Considered

If mutability is desired (for some reason I'm not aware of), then the matrix method should not be cached to avoid the bug above. In this case, I would imagine we'd also want to implement something explaining how to change the values.

Additional Information

No response

Is there an existing issue for this?

tscrim commented 1 month ago

+1 on this. The element is meant to be immutable, so the A and b should be immutable. Consequently it should be hashable.