patternpythonMinor
Lucas sequence implementation
Viewed 0 times
implementationsequencelucas
Problem
Could you suggest any improvements in this Lucas sequence's implementation:
```
from mpmath.libmp import bitcount as _bitlength
def _int_tuple(*i):
return tuple(int(_) for _ in i)
def _lucas_sequence(n, P, Q, k):
"""Return the modular Lucas sequence (U_k, V_k, Q_k).
Given a Lucas sequence defined by P, Q, returns the kth values for
U and V, along with Q^k, all modulo n.
"""
D = PP - 4Q
if n = 2")
if k = 0")
if D == 0:
raise ValueError("D must not be zero")
if k == 0:
return _int_tuple(0, 2, Q)
U = 1
V = P
Qk = Q
b = _bitlength(k)
if Q == 1:
# For strong tests
while b > 1:
U = (U*V) % n
V = (V*V - 2) % n
b -= 1
if (k >> (b - 1)) & 1:
t = U*D
U = U*P + V
if U & 1:
U += n
U >>= 1
V = V*P + t
if V & 1:
V += n
V >>= 1
elif P == 1 and Q == -1:
# For Selfridge parameters
while b > 1:
U = (U*V) % n
if Qk == 1:
V = (V*V - 2) % n
else:
V = (V*V + 2) % n
Qk = 1
b -= 1
if (k >> (b-1)) & 1:
t = U*D
U = U + V
if U & 1:
U += n
U >>= 1
V = V + t
if V & 1:
V += n
V >>= 1
Qk = -1
else:
# The general case with any P and Q
while b > 1:
U = (U*V) % n
V = (VV - 2Qk) % n
Qk *= Qk
b -= 1
if (k >> (b - 1)) & 1:
t = U*D
U = U*P + V
if U & 1:
U += n
U >>= 1
V = V*P + t
if V & 1:
V += n
```
from mpmath.libmp import bitcount as _bitlength
def _int_tuple(*i):
return tuple(int(_) for _ in i)
def _lucas_sequence(n, P, Q, k):
"""Return the modular Lucas sequence (U_k, V_k, Q_k).
Given a Lucas sequence defined by P, Q, returns the kth values for
U and V, along with Q^k, all modulo n.
"""
D = PP - 4Q
if n = 2")
if k = 0")
if D == 0:
raise ValueError("D must not be zero")
if k == 0:
return _int_tuple(0, 2, Q)
U = 1
V = P
Qk = Q
b = _bitlength(k)
if Q == 1:
# For strong tests
while b > 1:
U = (U*V) % n
V = (V*V - 2) % n
b -= 1
if (k >> (b - 1)) & 1:
t = U*D
U = U*P + V
if U & 1:
U += n
U >>= 1
V = V*P + t
if V & 1:
V += n
V >>= 1
elif P == 1 and Q == -1:
# For Selfridge parameters
while b > 1:
U = (U*V) % n
if Qk == 1:
V = (V*V - 2) % n
else:
V = (V*V + 2) % n
Qk = 1
b -= 1
if (k >> (b-1)) & 1:
t = U*D
U = U + V
if U & 1:
U += n
U >>= 1
V = V + t
if V & 1:
V += n
V >>= 1
Qk = -1
else:
# The general case with any P and Q
while b > 1:
U = (U*V) % n
V = (VV - 2Qk) % n
Qk *= Qk
b -= 1
if (k >> (b - 1)) & 1:
t = U*D
U = U*P + V
if U & 1:
U += n
U >>= 1
V = V*P + t
if V & 1:
V += n
Solution
Your
I also can't see any parts of your code which would produce a
So I would get rid of that function and return just a tuple and see what it does.
_int_tuple function does not seem to serve any real purpose. U and V are always integers (you initialize them to 1 and do only arithmetic on them afterwards). And what exactly your program will do with a Q which is e.g. a string is hard to follow, but I think it will run into the else block (Q is neither 1 nor -1) and then try to do Qk = Q, followed by Qk *= Qk which fails for almost everything but number types.I also can't see any parts of your code which would produce a
float (though I might have overlooked one).So I would get rid of that function and return just a tuple and see what it does.
Context
StackExchange Code Review Q#140992, answer score: 2
Revisions (0)
No revisions yet.