Un module Python standard contient-il une fonction pour calculer l'inverse multiplicatif modulaire d'un nombre, c'est-à-dire un nombre y = invmod(x, p)
tel que x*y == 1 (mod p)
? Google ne semble pas donner de bons indices à ce sujet.
Bien sûr, on peut proposer un algorithme euclidien étendu à 10 lignes , mais pourquoi réinventer la roue.
Par exemple, Java's BigInteger
has modInverse
method. Python n'a-t-il pas quelque chose de similaire?
pow
fonction pour cela:y = pow(x, -1, p)
. Voir bugs.python.org/issue36027 . Il n'a fallu que 8,5 ans entre la question posée et l'apparition d'une solution dans la bibliothèque standard!Réponses:
Peut-être que quelqu'un trouvera cela utile (à partir de wikibooks ):
la source
sympy
, alorsx, _, g = sympy.numbers.igcdex(a, m)
fait l'affaire.Si votre module est premier (vous l'appelez
p
), vous pouvez simplement calculer:Ou en Python proprement dit:
Voici quelqu'un qui a implémenté quelques capacités de théorie des nombres en Python: http://www.math.umbc.edu/~campbell/Computers/Python/numbthy.html
Voici un exemple réalisé à l'invite:
la source
Vous pouvez également consulter le module gmpy . C'est une interface entre Python et la bibliothèque multi-précision GMP. gmpy fournit une fonction d'inversion qui fait exactement ce dont vous avez besoin:
Réponse mise à jour
Comme indiqué par @hyh, le
gmpy.invert()
renvoie 0 si l'inverse n'existe pas. Cela correspond au comportement de lampz_invert()
fonction de GMP .gmpy.divm(a, b, m)
fournit une solution générale àa=bx (mod m)
.divm()
retournera une solution quandgcd(b,m) == 1
et lèvera une exception lorsque l'inverse multiplicatif n'existe pas.Clause de non-responsabilité: je suis le mainteneur actuel de la bibliothèque gmpy.
Réponse mise à jour 2
gmpy2 lève désormais correctement une exception lorsque l'inverse n'existe pas:
la source
gmpy.invert(0,5) = mpz(0)
au lieu de soulever une erreur ...gmpy
package? (c'est-à-dire une fonction qui a la même valeur mais qui est plus rapide que(a * b)% p
?)(a * b) % p
dans une fonction n'est pas plus rapide qu'une simple évaluation(a * b) % p
en Python. La surcharge pour un appel de fonction est supérieure au coût d'évaluation de l'expression. Voir code.google.com/p/gmpy/issues/detail?id=61 pour plus de détails.À partir de 3.8 pythons, la fonction pow () peut prendre un module et un entier négatif. Regardez ici . Leur cas pour savoir comment l'utiliser est
la source
Voici un one-liner pour CodeFights ; c'est l'une des solutions les plus courtes:
Il retournera
-1
siA
n'a pas d'inverse multiplicatif dansn
.Usage:
La solution utilise l' algorithme euclidien étendu .
la source
Sympy , un module python pour les mathématiques symboliques, a une fonction inverse modulaire intégrée si vous ne voulez pas implémenter la vôtre (ou si vous utilisez déjà Sympy):
Cela ne semble pas être documenté sur le site Web de Sympy, mais voici la docstring: Sympy mod_inverse docstring sur Github
la source
Voici mon code, il peut être bâclé mais il semble fonctionner pour moi de toute façon.
la source
Le code ci-dessus ne fonctionnera pas en python3 et est moins efficace que les variantes de GCD. Cependant, ce code est très transparent. Cela m'a incité à créer une version plus compacte:
la source
n == 7
. Mais sinon, c'est à peu près l'équivalent de cet "algorithme":for i in range(2, n): if i * a % n == 1: return i
Voici un 1-liner concis qui le fait, sans utiliser de bibliothèques externes.
Notez qu'il ne s'agit en réalité que de egcd, simplifié pour ne renvoyer que le seul coefficient d'intérêt.
la source
Pour comprendre l'inverse multiplicatif modulaire, je recommande d'utiliser l'algorithme euclidien étendu comme ceci:
la source
a = prevX - quotient * X
devrait êtreX = prevX - quotient * X
, et il devrait revenirprevX
. FWIW, cette implémentation est similaire à celle du lien de Qaz dans le commentaire de la réponse de Märt Bakhoff.J'essaie différentes solutions de ce fil et à la fin j'utilise celle-ci:
Modular_inverse en Python
la source
return
dans egcd est indended d'une mauvaise manièreEh bien, je n'ai pas de fonction en python mais j'ai une fonction en C que vous pouvez facilement convertir en python, dans la fonction c ci-dessous, l'algorithme euclidien étendu est utilisé pour calculer le mod inverse.
Fonction Python
La référence à la fonction C ci-dessus est tirée du programme lien C suivant pour trouver l'inverse multiplicatif modulaire de deux nombres relativement premiers
la source
à partir du code source de l' implémentation cpython :
selon le commentaire ci-dessus ce code, il peut renvoyer de petites valeurs négatives, vous pouvez donc potentiellement vérifier si négatif et ajouter n lorsqu'il est négatif avant de renvoyer b.
la source
La plupart des liens ci-dessus sont rompus au 23/01/2017. J'ai trouvé cette implémentation: https://courses.csail.mit.edu/6.857/2016/files/ffield.py
la source