Converting EGCD Equation to Python - python

Attempting to convert this EGCD equation into python.
egcd(a, b) = (1, 0), if b = 0
= (t, s - q * t), otherwise, where
q = a / b (note: integer division)
r = a mod b
(s, t) = egcd(b, r)
The test I used was egcd(5, 37) which should return (15,-2) but is returning (19.5, -5.135135135135135)
My code is:
def egcd(a, b):
if b == 0:
return (1, 0)
else:
q = a / b # Calculate q
r = a % b # Calculate r
(s,t) = egcd(b,r) # Calculate (s, t) by calling egcd(b, r)
return (t,s-q*t) # Return (t, s-q*t)

a / b in Python 3 is "true division" the result is non-truncating floating point division even when both operands are ints.
To fix, either use // instead (which is floor division):
q = a // b
or use divmod to perform both division and remainder as a single computation, replacing both of these lines:
q = a / b
r = a % b
with just:
q, r = divmod(a, b)

Change q = a / b for q = a // b

Related

TypeError float object cannot be interpreted as an integer

I'm trying to get the result in hex format, but I get the error "TypeError: 'float' object cannot be interpreted as an integer!"
39 d = chinese_remainder(a, n)
---> 40 number = hex(d)
41 print(number)
Code:
import functools
# Euclidean extended algorithm
def egcd(a, b):
if a == 0:
return b, 0, 1
else:
d, x, y = egcd(b % a, a)
return d, y - (b // a) * x, x
"""
Functions whcih calculate the CRT (
return x in ' x = a mod n'.
"""
def chinese_remainder(a, n):
modulus = functools.reduce(lambda a, b: a * b, n)
multipliers = []
for N_i in n:
N = modulus / N_i
gcd, inverse, y = egcd(N, N_i)
multipliers.append(inverse * N % modulus)
result = 0
for multi, a_i in zip(multipliers, a):
result = (result + multi * a_i) % modulus
return result
FN = 1184749
FM = 8118474
FL = 5386565
HN = 8686891
HM = 6036033
HK = 6029230
n = [FN, FM, FL]
a = [HN, HM, HK]
d = chinese_remainder(a, n)
number = hex(d)
print(number)
The result should be like this
FAB15A7AE056200F9
But it gives me
3.3981196080447865e + 19
How to fix this so that the result is in hex format ???
Normal division / operator returns float whereas you can use floor division // to get integers.
As others suggested, you have to use floor division to variable N like this N = modulus//N_i

How to make this float precision without using print

I'm working on assignment, it's about numerical method regarding to trapezoidal rule
def trapezoidalRule(F,a,b,n):
h = float(b-a)/n
f_sum = 0
for i in range(1, n, 1):
x = a + i * h
f_sum = f_sum + f(x)
return h * (0.5 * f(a) + f_sum + 0.5 * f(b))
def f(x):
return x**3
a = 2
b = 10
n = 512
print('%.16f' %trapezoidalRule(f, a, b, n))
And the output is
2496.0058593750000000
My question is, how do i get a precission like that.. without using print('%.16f' %trapezoidalRule(f, a, b, n)). I want to append the result to the list, with exact value like that..
I already tried to google it, but i found nothing related to this problem, can somebody tell me the solution if i want to it ?
Change your return statement in trapezoidalRule to be formatted with 16 points of precision, do note that this is going to cause it to become a string as if you cast it back to float you'll lose the trailing 0's.
def trapezoidalRule(F,a,b,n):
h = float(b-a)/n
f_sum = 0
for i in range(1, n, 1):
x = a + i * h
f_sum = f_sum + f(x)
return format((h * (0.5 * f(a) + f_sum + 0.5 * f(b))), '.16f')
def f(x):
return x**3
a = 2
b = 10
n = 512
See the return line in trapezoidalRule so now if I print the exact output of trapezoidalRule like so: print(trapezoidalRule(f, a, b, n)) with no formatting I get:
2496.0058593750000000
To increase precision try using decimal module
import decimal
def trapezoidalRule(F,a,b,n):
h = decimal.Decimal(float(b-a)/n)
f_sum = 0
for i in range(1, n, 1):
x = a + i * h
f_sum = f_sum + f(x)
return h * (decimal.Decimal(0.5) * f(a) + f_sum + decimal.Decimal(0.5) * f(b))
def f(x):
return decimal.Decimal(x**3)

How to find reverse of pow(a,b,c) in python?

pow(a,b,c) operator in python returns (a**b)%c . If I have values of b, c, and the result of this operation (res=pow(a,b,c)), how can I find the value of a?
Despite the statements in the comments this is not the discrete logarithm problem. This more closely resembles the RSA problem in which c is the product of two large primes, b is the encrypt exponent, and a is the unknown plaintext. I always like to make x the unknown variable you want to solve for, so you have y= xb mod c where y, b, and c are known, you want to solve for x. Solving it involves the same basic number theory as in RSA, namely you must compute z=b-1 mod λ(c), and then you can solve for x via x = yz mod c. λ is Carmichael's lambda function, but you can also use Euler's phi (totient) function instead. We have reduced the original problem to computing an inverse mod λ(c). This is easy to do if c is easy to factor or we already know the factorization of c, and hard otherwise. If c is small then brute-force is an acceptable technique and you can ignore all the complicated math.
Here is some code showing these steps:
import functools
import math
def egcd(a, b):
"""Extended gcd of a and b. Returns (d, x, y) such that
d = a*x + b*y where d is the greatest common divisor of a and b."""
x0, x1, y0, y1 = 1, 0, 0, 1
while b != 0:
q, a, b = a // b, b, a % b
x0, x1 = x1, x0 - q * x1
y0, y1 = y1, y0 - q * y1
return a, x0, y0
def inverse(a, n):
"""Returns the inverse x of a mod n, i.e. x*a = 1 mod n. Raises a
ZeroDivisionError if gcd(a,n) != 1."""
d, a_inv, n_inv = egcd(a, n)
if d != 1:
raise ZeroDivisionError('{} is not coprime to {}'.format(a, n))
else:
return a_inv % n
def lcm(*x):
"""
Returns the least common multiple of its arguments. At least two arguments must be
supplied.
:param x:
:return:
"""
if not x or len(x) < 2:
raise ValueError("at least two arguments must be supplied to lcm")
lcm_of_2 = lambda x, y: (x * y) // math.gcd(x, y)
return functools.reduce(lcm_of_2, x)
def carmichael_pp(p, e):
phi = pow(p, e - 1) * (p - 1)
if (p % 2 == 1) or (e >= 2):
return phi
else:
return phi // 2
def carmichael_lambda(pp):
"""
pp is a sequence representing the unique prime-power factorization of the
integer whose Carmichael function is to be computed.
:param pp: the prime-power factorization, a sequence of pairs (p,e) where p is prime and e>=1.
:return: Carmichael's function result
"""
return lcm(*[carmichael_pp(p, e) for p, e in pp])
a = 182989423414314437
b = 112388918933488834121
c = 128391911110189182102909037 * 256
y = pow(a, b, c)
lam = carmichael_lambda([(2,8), (128391911110189182102909037, 1)])
z = inverse(b, lam)
x = pow(y, z, c)
print(x)
The best you can do is something like this:
a = 12
b = 5
c = 125
def is_int(a):
return a - int(a) <= 1e-5
# ============= Without C ========== #
print("Process without c")
rslt = pow(a, b)
print("a**b:", rslt)
print("a:", pow(rslt, (1.0 / b)))
# ============= With C ========== #
print("\nProcess with c")
rslt = pow(a, b, c)
i = 0
while True:
a = pow(rslt + i*c, (1.0 / b))
if is_int(a):
break
else:
i += 1
print("a**b % c:", rslt)
print("a:", a)
You can never be sure that you have found the correct modulo value, it is the first value that is compatible with your settings. The algorithm is based on the fact that a, b and c are integers. If they are not you have no solution a likely combination that was the original one.
Outputs:
Process without c
a**b: 248832
a: 12.000000000000002
Process with c
a**b % c: 82
a: 12.000000000000002

Fast floating point modpow

I am looking to compute a^b mod m where a & b are floating point numbers and m is an non-negative integer. The trivial solution is to do b multiplications which takes O(n) time, however my numbers a & b can be largish (~10 digits before the decimal point) and I would like to do this efficiently. When a,b and m are integers we can compute the modpow quickly in log(n) time via: Exponentiation_by_squaring.
How would I use this method (or another) for floating point numbers? I am using Python to do this computation and the pow function only allows integers. Here is my attempt at doing exponentiation by squaring with Decimal numbers, but the answer is not coming out right:
from decimal import Decimal
EPS = Decimal("0.0001")
# a, b are Decimals and m is an integer
def deci_pow(a, b, m):
if abs(b) < EPS:
return Decimal(1)
tmp = deci_pow(a, b / 2, m) % m # Should this be // ?
if abs(b % 2) < EPS:
return (tmp * tmp) % m
else:
if b > 0:
return (a * tmp * tmp) % m
else:
return ((tmp * tmp)/a) % m
print(deci_pow(Decimal(2.4), Decimal(3.5), 5)) # != 1.416
When a,b,m are all integers this is what the method looks like:
# a, b, m are Integers
def integer_pow(a, b, m):
if b == 0: return 1
tmp = integer_pow(a, b // 2, m) % m
if b % 2 == 0:
return (tmp * tmp) % m
else:
if b > 0:
return (a * tmp * tmp) % m
else:
return ((tmp * tmp) / a) % m
I don't think there is an easy way to do this in general, if a and b can be 10 digits (assuming before the decimal point). The problem is that for floats x and y, you don't necessarily have the property
((x % m) * (y % m)) % m == (x * y) % m
If you tell us your specific context and why you want to do this, there might be other approaches possible.

basic example of elgamal algorithm in python 2.7 [duplicate]

Does some standard Python module contain a function to compute modular multiplicative inverse of a number, i.e. a number y = invmod(x, p) such that x*y == 1 (mod p)? Google doesn't seem to give any good hints on this.
Of course, one can come up with home-brewed 10-liner of extended Euclidean algorithm, but why reinvent the wheel.
For example, Java's BigInteger has modInverse method. Doesn't Python have something similar?
Python 3.8+
y = pow(x, -1, p)
Python 3.7 and earlier
Maybe someone will find this useful (from wikibooks):
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
If your modulus is prime (you call it p) then you may simply compute:
y = x**(p-2) mod p # Pseudocode
Or in Python proper:
y = pow(x, p-2, p)
Here is someone who has implemented some number theory capabilities in Python: http://www.math.umbc.edu/~campbell/Computers/Python/numbthy.html
Here is an example done at the prompt:
m = 1000000007
x = 1234567
y = pow(x,m-2,m)
y
989145189L
x*y
1221166008548163L
x*y % m
1L
You might also want to look at the gmpy module. It is an interface between Python and the GMP multiple-precision library. gmpy provides an invert function that does exactly what you need:
>>> import gmpy
>>> gmpy.invert(1234567, 1000000007)
mpz(989145189)
Updated answer
As noted by #hyh , the gmpy.invert() returns 0 if the inverse does not exist. That matches the behavior of GMP's mpz_invert() function. gmpy.divm(a, b, m) provides a general solution to a=bx (mod m).
>>> gmpy.divm(1, 1234567, 1000000007)
mpz(989145189)
>>> gmpy.divm(1, 0, 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 9)
mpz(7)
divm() will return a solution when gcd(b,m) == 1 and raises an exception when the multiplicative inverse does not exist.
Disclaimer: I'm the current maintainer of the gmpy library.
Updated answer 2
gmpy2 now properly raises an exception when the inverse does not exists:
>>> import gmpy2
>>> gmpy2.invert(0,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: invert() no inverse exists
As of 3.8 pythons pow() function can take a modulus and a negative integer. See here. Their case for how to use it is
>>> pow(38, -1, 97)
23
>>> 23 * 38 % 97 == 1
True
Here is a one-liner for CodeFights; it is one of the shortest solutions:
MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1]
It will return -1 if A has no multiplicative inverse in n.
Usage:
MMI(23, 99) # returns 56
MMI(18, 24) # return -1
The solution uses the Extended Euclidean Algorithm.
Sympy, a python module for symbolic mathematics, has a built-in modular inverse function if you don't want to implement your own (or if you're using Sympy already):
from sympy import mod_inverse
mod_inverse(11, 35) # returns 16
mod_inverse(15, 35) # raises ValueError: 'inverse of 15 (mod 35) does not exist'
This doesn't seem to be documented on the Sympy website, but here's the docstring: Sympy mod_inverse docstring on Github
Here is a concise 1-liner that does it, without using any external libraries.
# Given 0<a<b, returns the unique c such that 0<c<b and a*c == gcd(a,b) (mod b).
# In particular, if a,b are relatively prime, returns the inverse of a modulo b.
def invmod(a,b): return 0 if a==0 else 1 if b%a==0 else b - invmod(b%a,a)*b//a
Note that this is really just egcd, streamlined to return only the single coefficient of interest.
I try different solutions from this thread and in the end I use this one:
def egcd(a, b):
lastremainder, remainder = abs(a), abs(b)
x, lastx, y, lasty = 0, 1, 1, 0
while remainder:
lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
x, lastx = lastx - quotient*x, x
y, lasty = lasty - quotient*y, y
return lastremainder, lastx * (-1 if a < 0 else 1), lasty * (-1 if b < 0 else 1)
def modinv(a, m):
g, x, y = self.egcd(a, m)
if g != 1:
raise ValueError('modinv for {} does not exist'.format(a))
return x % m
Modular_inverse in Python
Here is my code, it might be sloppy but it seems to work for me anyway.
# a is the number you want the inverse for
# b is the modulus
def mod_inverse(a, b):
r = -1
B = b
A = a
eq_set = []
full_set = []
mod_set = []
#euclid's algorithm
while r!=1 and r!=0:
r = b%a
q = b//a
eq_set = [r, b, a, q*-1]
b = a
a = r
full_set.append(eq_set)
for i in range(0, 4):
mod_set.append(full_set[-1][i])
mod_set.insert(2, 1)
counter = 0
#extended euclid's algorithm
for i in range(1, len(full_set)):
if counter%2 == 0:
mod_set[2] = full_set[-1*(i+1)][3]*mod_set[4]+mod_set[2]
mod_set[3] = full_set[-1*(i+1)][1]
elif counter%2 != 0:
mod_set[4] = full_set[-1*(i+1)][3]*mod_set[2]+mod_set[4]
mod_set[1] = full_set[-1*(i+1)][1]
counter += 1
if mod_set[3] == B:
return mod_set[2]%B
return mod_set[4]%B
The code above will not run in python3 and is less efficient compared to the GCD variants. However, this code is very transparent. It triggered me to create a more compact version:
def imod(a, n):
c = 1
while (c % a > 0):
c += n
return c // a
from the cpython implementation source code:
def invmod(a, n):
b, c = 1, 0
while n:
q, r = divmod(a, n)
a, b, c, n = n, c, b - q*c, r
# at this point a is the gcd of the original inputs
if a == 1:
return b
raise ValueError("Not invertible")
according to the comment above this code, it can return small negative values, so you could potentially check if negative and add n when negative before returning b.
To figure out the modular multiplicative inverse I recommend using the Extended Euclidean Algorithm like this:
def multiplicative_inverse(a, b):
origA = a
X = 0
prevX = 1
Y = 1
prevY = 0
while b != 0:
temp = b
quotient = a/b
b = a%b
a = temp
temp = X
a = prevX - quotient * X
prevX = temp
temp = Y
Y = prevY - quotient * Y
prevY = temp
return origA + prevY
Well, here's a function in C which you can easily convert to python. In the below c function extended euclidian algorithm is used to calculate inverse mod.
int imod(int a,int n){
int c,i=1;
while(1){
c = n * i + 1;
if(c%a==0){
c = c/a;
break;
}
i++;
}
return c;}
Translates to Python Function
def imod(a,n):
i=1
while True:
c = n * i + 1;
if(c%a==0):
c = c/a
break;
i = i+1
return c
Reference to the above C function is taken from the following link C program to find Modular Multiplicative Inverse of two Relatively Prime Numbers

Categories