@@ -1608,6 +1608,27 @@ cdef class Polynomial(CommutativePolynomial):
16081608 AUTHORS:
16091609
16101610 - Robert Bradshaw (2007-05-31)
1611+
1612+ TESTS:
1613+
1614+ At the time of writing :meth:`inverse_mod` is not implemented in general for the following ring,
1615+ but it should fallback to :meth:`inverse_of_unit` when possible::
1616+
1617+ sage: R.<u,v> = ZZ[]
1618+ sage: S = R.localization(u)
1619+ sage: T.<x> = S[]
1620+ sage: T
1621+ Univariate Polynomial Ring in x over Multivariate Polynomial Ring in u, v over Integer Ring localized at (u,)
1622+ sage: T(u).is_unit()
1623+ True
1624+ sage: T(u).inverse_of_unit()
1625+ 1/u
1626+ sage: T(u).inverse_mod(T(v))
1627+ 1/u
1628+ sage: T(v).inverse_mod(T(v^2-1))
1629+ Traceback (most recent call last):
1630+ ...
1631+ NotImplementedError: Multivariate Polynomial Ring in u, v over Integer Ring localized at (u,) does not provide...
16111632 """
16121633 from sage.rings.ideal import Ideal_generic
16131634 if isinstance (m, Ideal_generic):
@@ -1625,13 +1646,21 @@ cdef class Polynomial(CommutativePolynomial):
16251646 return a.parent()(~ u)
16261647 if a.parent().is_exact():
16271648 # use xgcd
1628- g, s, _ = a.xgcd(m)
1629- if g == 1 :
1630- return s
1631- elif g.is_unit():
1632- return g.inverse_of_unit() * s
1633- else :
1634- raise ValueError (" Impossible inverse modulo" )
1649+ try :
1650+ g, s, _ = a.xgcd(m)
1651+ if g == 1 :
1652+ return s
1653+ elif g.is_unit():
1654+ return g.inverse_of_unit() * s
1655+ else :
1656+ raise ValueError (" Impossible inverse modulo" )
1657+ except NotImplementedError :
1658+ # attempt fallback, return inverse_of_unit() if this is already an unit
1659+ try :
1660+ return a.inverse_of_unit()
1661+ except (ArithmeticError , ValueError , NotImplementedError , ZeroDivisionError ):
1662+ pass
1663+ raise
16351664 else :
16361665 # xgcd may not converge for inexact rings.
16371666 # Instead solve for the coefficients of
0 commit comments