Содержит ли какой-либо стандартный модуль Python функцию для вычисления модульного мультипликативного обратного числа, то есть числа, y = invmod(x, p)
такого чтоx*y == 1 (mod p)
? Google, похоже, не дает на это никаких хороших намеков.
Конечно, можно придумать самодельный 10-строчный расширенный алгоритм Евклида. , но зачем изобретать велосипед.
Например, в Java BigInteger
есть modInverse
метод. Разве у Python нет чего-то подобного?
pow
функции для этого:y = pow(x, -1, p)
. См. Bugs.python.org/issue36027 . Прошло всего 8,5 лет от вопроса до того, как решение появилось в стандартной библиотеке!Ответы:
Может быть, кому-то это пригодится (из викиучебников ):
источник
sympy
, тоx, _, g = sympy.numbers.igcdex(a, m)
поможет.Если ваш модуль простой (вы его называете
p
), вы можете просто вычислить:Или в самом Python:
Вот кто-то, кто реализовал в Python некоторые возможности теории чисел: http://www.math.umbc.edu/~campbell/Computers/Python/numbthy.html
Вот пример, сделанный в командной строке:
источник
Вы также можете посмотреть модуль gmpy . Это интерфейс между Python и библиотекой множественной точности GMP. gmpy предоставляет функцию инвертирования, которая делает именно то, что вам нужно:
Обновленный ответ
Как отмечает @hyh,
gmpy.invert()
возвращается 0, если обратного не существует. Это соответствует поведению функции GMPmpz_invert()
.gmpy.divm(a, b, m)
обеспечивает общее решение проблемыa=bx (mod m)
.divm()
вернет решение, когдаgcd(b,m) == 1
и вызовет исключение, когда мультипликативная обратная функция не существует.Отказ от ответственности: я в настоящее время поддерживаю библиотеку gmpy.
Обновленный ответ 2
gmpy2 теперь корректно вызывает исключение, если обратное не существует:
источник
gmpy.invert(0,5) = mpz(0)
вместо того, чтобыgmpy
пакете модульное умножение ? (т.е. некоторая функция, которая имеет то же значение, но работает быстрее, чем(a * b)% p
?)(a * b) % p
в функции - не быстрее, чем просто вычисление(a * b) % p
в Python. Накладные расходы на вызов функции больше, чем затраты на оценку выражения. См. Code.google.com/p/gmpy/issues/detail?id=61 для получения дополнительных сведений.Начиная с версии 3.8 pythons, функция pow () может принимать модуль и отрицательное целое число. Смотрите здесь . Их аргументы в пользу того, как его использовать,
источник
Вот однострочный текст для CodeFights ; это одно из самых коротких решений:
Он вернется,
-1
еслиA
не имеет обратного мультипликативного значенияn
.Использование:
Решение использует расширенный алгоритм Евклида .
источник
Sympy , модуль Python для символьной математики, имеет встроенную модульную обратную функцию, если вы не хотите реализовывать свою собственную (или если вы уже используете Sympy):
Кажется, это не задокументировано на веб-сайте Sympy, но вот строка документации: Sympy mod_inverse docstring на Github
источник
Вот мой код, он может быть небрежным, но, похоже, он все равно работает для меня.
источник
Приведенный выше код не будет работать в python3 и менее эффективен по сравнению с вариантами GCD. Однако этот код очень прозрачен. Это побудило меня создать более компактную версию:
источник
n == 7
. Но в остальном речь идет об эквиваленте этого «алгоритма»:for i in range(2, n): if i * a % n == 1: return i
Вот краткий однострочный файл, который делает это без использования каких-либо внешних библиотек.
Обратите внимание, что это действительно просто egcd, оптимизированная для возврата только одного интересующего коэффициента.
источник
Чтобы выяснить модульное мультипликативное обратное, я рекомендую использовать расширенный алгоритм Евклида следующим образом:
источник
a = prevX - quotient * X
должна бытьX = prevX - quotient * X
и должна вернутьсяprevX
. FWIW, эта реализация аналогична той, что указана в ссылке Qaz в комментарии к ответу Мярта Бахоффа.Я пробую разные решения из этой ветки и в итоге использую вот это:
Modular_inverse в Python
источник
return
в egcd неправильныйНу, у меня нет функции в python, но у меня есть функция на C, которую вы можете легко преобразовать в python, в приведенной ниже функции c расширенный алгоритм евклида используется для вычисления обратного мода.
Функция Python
Ссылка на приведенную выше функцию C взята из следующей ссылки программы C, чтобы найти модульное мультипликативное обратное значение двух относительно простых чисел
источник
из исходного кода реализации cpython :
согласно комментарию над этим кодом, он может возвращать небольшие отрицательные значения, поэтому вы потенциально можете проверить, является ли оно отрицательным, и добавить n, если оно отрицательное, прежде чем возвращать b.
источник
По состоянию на 23.01.2017 многие из приведенных выше ссылок не работают. Я нашел эту реализацию: https://courses.csail.mit.edu/6.857/2016/files/ffield.py
источник