def inverse_modulo(representative, modulus): """ Return an element @c n such that @c n * representative has remainder one if divided by @p modulus. In residue class rings, this is the multiplicative inverse. @exception ValueError if @p representative and @p modulus are not relatively prime. """ inverse, ignore, gcd = extended_euclidean_algorithm( representative, modulus ) try: relatively_prime = ( gcd == representative.__class__.one() ) except Exception: relatively_prime = ( gcd == 1 ) if relatively_prime: return inverse else: raise ValueError( "representative and modulus must be relatively prime" )
def multiplicative_inverse(self): """ Return an residue class (QuotientRing element) @c n such that @c n * self is one(). @exception ZeroDivisionError if @p self is not a unit, that is, has no multiplicative inverse. """ if not self.__remainder: raise ZeroDivisionError inverse, ignore, gcd = \ extended_euclidean_algorithm(self.__remainder, self._modulus) if gcd == self._ring.one(): return self.__class__(inverse) else: message = "element has no inverse: representative and modulus " \ "are not relatively prime" raise ZeroDivisionError(message)
def multiplicative_inverse(self): """ Return an residue class (QuotientRing element) @c n such that @c n * self is one(). @exception ZeroDivisionError if @p self is not a unit, that is, has no multiplicative inverse. """ if not self.__remainder: raise ZeroDivisionError inverse, ignore, gcd = \ extended_euclidean_algorithm( self.__remainder, self._modulus ) if gcd == self._ring.one(): return self.__class__( inverse ) else: message = "element has no inverse: representative and modulus " \ "are not relatively prime" raise ZeroDivisionError( message )