You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Trac #17965: Uniformize the API to compute the inverse of an element
Some classes in Sage implement the inverse of an element through the
inverse method:
{{{
mistral-/opt/sage/src/sage>grep "def inverse(" **/*.py
algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.
py: def inverse(self):
algebras/iwahori_hecke_algebra.py: def inverse(self):
categories/coxeter_groups.py: def inverse(self):
combinat/affine_permutation.py: def inverse(self):
combinat/permutation.py: def inverse(self):
combinat/tableau_tuple.py: def inverse(self,k):
crypto/classical_cipher.py: def inverse(self):
crypto/classical_cipher.py: def inverse(self):
crypto/classical_cipher.py: def inverse(self):
crypto/classical_cipher.py: def inverse(self):
dynamics/interval_exchanges/iet.py: def inverse(self):
groups/abelian_gps/element_base.py: def inverse(self):
groups/abelian_gps/values.py: def inverse(self):
groups/affine_gps/group_element.py: def inverse(self):
modules/matrix_morphism.py: def inverse(self):
rings/number_field/class_group.py: def inverse(self):
rings/universal_cyclotomic_field/universal_cyclotomic_field.py:
def inverse(self):
schemes/elliptic_curves/formal_group.py: def inverse(self, prec=20):
schemes/elliptic_curves/weierstrass_transform.py: def inverse(self):
}}}
Some other through the `__invert__` method:
{{{
mistral-/opt/sage/src/sage>grep "def __invert__(" **/*.py
categories/algebras_with_basis.py: def __invert__(self):
categories/magmas.py: def __invert__(self):
categories/modules_with_basis.py: def __invert__(self):
categories/modules_with_basis.py: def __invert__(self):
combinat/combinatorial_algebra.py: def __invert__(self):
combinat/sf/dual.py: def __invert__(self):
combinat/species/generating_series.py: def __invert__(self):
groups/indexed_free_group.py: def __invert__(self):
groups/indexed_free_group.py: def __invert__(self):
groups/matrix_gps/group_element.py: def __invert__(self):
groups/raag.py: def __invert__(self):
libs/coxeter3/coxeter_group.py: def __invert__(self):
logic/boolformula.py: def __invert__(self):
misc/sage_input.py: def __invert__(self):
modular/dirichlet.py: def __invert__(self):
modular/local_comp/smoothchar.py: def __invert__(self):
modules/matrix_morphism.py: def __invert__(self):
rings/continued_fraction.py: def __invert__(self):
rings/finite_rings/element_ext_pari.py: def __invert__(self):
rings/function_field/function_field_ideal.py: def __invert__(self):
rings/infinity.py: def __invert__(self):
rings/multi_power_series_ring_element.py: def __invert__(self):
rings/number_field/morphism.py: def __invert__(self):
rings/number_field/number_field_ideal.py: def __invert__(self):
rings/number_field/number_field_ideal_rel.py: def __invert__(self):
rings/pari_ring.py: def __invert__(self):
rings/polynomial/polynomial_quotient_ring_element.py: def
__invert__(self):
rings/qqbar.py: def __invert__(self):
rings/quotient_ring_element.py: def __invert__(self):
rings/universal_cyclotomic_field/universal_cyclotomic_field.py:
def __invert__(self):
sandpiles/sandpile.py: def __invert__(self):
schemes/elliptic_curves/heegner.py: def __invert__(self):
schemes/elliptic_curves/height.py: def __invert__(self):
schemes/elliptic_curves/weierstrass_morphism.py: def
__invert__(self):
schemes/elliptic_curves/weierstrass_morphism.py: def
__invert__(self):
schemes/hyperelliptic_curves/monsky_washnitzer.py: def
__invert__(self):
structure/factorization.py: def __invert__(self):
}}}
Usually they provide a crosslink so that `__invert__` and
`inverse` are equivalent, but this is done on a case by case bases,
so of course such links are missing here and there:
{{{
sage: ~AA(sqrt(~2))
1.414213562373095?
sage: AA(sqrt(~2)).inverse()
...
AttributeError: 'AlgebraicReal' object has no attribute 'inverse'
}}}
{{{
sage: R.<u,v,w> = QQ[]
sage: f = EllipticCurve_from_cubic(u^3 + v^3 + w^3, [1,-1,0],
morphism=True)
sage: f.inverse()
Scheme morphism:
...
sage: ~f
...
TypeError: bad operand type for unary ~:
'WeierstrassTransformationWithInverse_class'
}}}
Shall we change the code to systematically implement `__invert__` as
per Python's convention, and then implement the cross link `inverse`
-> `__invert__` once for all high up in the class hierarchy,
typically in `Magmas.ElementMethods`?
Caveat: this won't cover all cases since we have invertible elements
that don't belong to a magma; e.g. a isomorphisms between two
different parents; so it will still be necessary to handle a couple
special cases by hand.
See also comment about `__inverse__` in
sage.categories.coxeter_groups.py around line 699.
Note: the default implementation ~f = 1/f provided by Element should
probably be implemented in `Monoids.ElementMethods`; see also #17692.
Note: the qqbar classes also implement an `invert` method, but that's
for a slightly different use case. So we may, or not, want to make
this uniform too. `invert` does not fit Sage's usual verb/noun
convention since it's a verb while it is not inplace.
URL: https://trac.sagemath.org/17965
Reported by: nthiery
Ticket author(s): Frédéric Chapoton
Reviewer(s): Travis Scrimshaw
0 commit comments