Python code efficiency - python

This program tests if a matrix is an identity matrix or not.
I have pasted my code beneath, and would like to know ways in which I can optimize the efficiency of this code. Also I am new to python programming, are there some built in functions that can solve the purpose too?
def is_identity_matrix(test):
if (test == []):
return False
i = 0
while (i < len(test)):
if (len(test[i]) == len(test)):
j = 0
while(j < len(test[i])):
if (j != i):
if(test[i][j] != 0):
return False
else:
if(test[i][j] != 1):
return False
if(j == (len(test[i]) - 1)):
break
j += 1
if(i == (len(test) - 1)):
break
i += 1
else:
return False
if(i == j and i == (len(test) - 1)):
return True
# Test Cases:
matrix1 = [[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[0,0,0,1]]
print is_identity_matrix(matrix1)
#>>>True
matrix2 = [[1,0,0],
[0,1,0],
[0,0,0]]
print is_identity_matrix(matrix2)
#>>>False
matrix3 = [[2,0,0],
[0,2,0],
[0,0,2]]
print is_identity_matrix(matrix3)
#>>>False
matrix4 = [[1,0,0,0],
[0,1,1,0],
[0,0,0,1]]
print is_identity_matrix(matrix4)
#>>>False
matrix5 = [[1,0,0,0,0,0,0,0,0]]
print is_identity_matrix(matrix5)
#>>>False
matrix6 = [[1,0,0,0],
[0,1,0,2],
[0,0,1,0],
[0,0,0,1]]
print is_identity_matrix(matrix6)
#>>>False

def is_identity_matrix(listoflist):
return all(val == (x == y)
for y, row in enumerate(listoflist)
for x, val in enumerate(row))
(though, this does not check if the matrix is square, and it returns True for an empty list)
Explanation: Inside all we have a generator expression with nested loops where val loops over each value in the matrix. x == y evaluates to True on the diagonal and False elsewhere. In Python, True == 1 and False == 0, so you can compare val == (x == y). The parentheses are important:
val == x == y would be a chained comparison equivalent to val == x and x == y

I'd use numpy:
(np.array(matrix1) == np.identity(len(matrix1))).all()
Of course, it'd be better if you were storing matrix1 as a numpy array in the first place to avoid the conversion.

Multiply by the all ones vector and check that the result is the same

Check the size of your matrix, make sure it is n x n, then create an actual identity matrix using np.identity(n), then compare your matrix with the new one you created.

def is_identity_matrix(test):
if not test : return False
le = len(test[0])
for i,x in enumerate(test):
if len(x) == le:
if any(y!=1 if j==i else y!=0 for j,y in enumerate(x)):
return False
else:
return False
return True if len(test) == le else False

If speed is important you should probably look at Numpy, but in a situation where you can't use it or perhaps it isn't worth it to have the matrix as a Numpy array you could also use the following:
def is_identity(mat):
for i, row in enumerate(mat):
if any(row[:i]) or row[i]!=1 or any(row[i+1:]):
return False
return True
About 12x faster than the code of the currently accepted answer! For a matrix of 2000x2000 at least...
The above does not check the matrix dimensions, but you can easily add something like:
n = len(matrix)
if not all(len(row) == n for row in matrix):
return False

Related

Symmetric 1D array Python

So I have
A = [1,2,3,4]
I want to check if the array is symmetric. So the output would be False
Another example would be
arr = [1,2,3,3,2,1]
out = fun(arr)
out = True
I have been trying by like
def checksymm(a):
flag = 0
for i in range(0,len(a)/2):
if np.abs(a[i]) == np.abs(a[-i]):
return True
else:
return False
What can I be doing wrong?
Thanks.
Corresponding of a[i] should be a[-1-i], not a[-i].
Besides, why not just reverse the list and compare each elements:
def isSymmetric(arr):
return (arr == arr[::-1]).all()
Probably the most efficient way would be to restrict the comparison to each half of the array:
n = len(arr) // 2
result = np.all(arr[:n] == arr[-1:-n - 1:-1])
With absolute values:
result = (np.abs(arr[:n]) == np.abs(arr[-1:-n - 1:-1])).all()
Both formulations should work directly with either lists or arrays.
When you compare, pay attention to the index, 0 with -1, 1 with -2 etc (not 1 with -1), so it should be i and -i-1 . Also instead of returning True after finding one equality , you should return after all of them are equal ...
arr = [1,2,3,3,2,1]
def checksymm(a):
for i in range(0,len(a)//2):
if a[i] != a[-i-1]: # or np.abs(a[i]) != np.abs(a[-i-1]) as in the original code
return False
return True
out = checksymm(arr)
print(out)
>>> True
And :
arr = [1,2,3,3,5,1]
out = checksymm(arr)
print(out)
>>> False
Edit : I tried to find the problem with your code and fix it, but I would recommand the answer of #songziming it's better.

How can I avoid exceeding maximum recursion depth when generating a Hadamard Matrix?

I am trying to recursively generate Hadamard matrices by Sylvester construction, following this recurrence formula:
H(2) = (1 1)
(1 -1)
H(2**k) = ( H(2**(k-1)) H(2**(k-1)) )
( H(2**(k-1)) -H(2**(k-1)) )
this formula as an image of LaTeX
Or using the notation (x) for Kronecker product:
H(2**k) = H(2) (x) H(2**(k-1))
My code to generate a Hadamard matrix by Sylvester construction is as follows:
def deepMap(f,seq):
if seq == []:
return seq
elif type(seq) != list:
return f(seq)
else:
return [deepMap(f,seq[0])] + deepMap(f,seq[1:])
def Hadamard(n): #n is a power of 2
if n == 1:
return [1]
elif n == 2:
return [[1,1],[1,-1]]
else:
k = 2
array = [Hadamard(k)]
while k < n:
k *= 2
matrix,prev = [],array.pop(0)
for i in range(k):
if i < k//2:
matrix.append(prev[i]+prev[i])
else:
matrix.append(prev[i%(k//2)]+deepMap(lambda x: -x,prev[i%(k//2)]))
array.append(matrix)
#print(f'matrix {k} = {matrix}')
return array[0]
The code works, but is pretty slow, and exceeds maximum depth recursion when n > 1024.
How could I make the code handle larger values of n?
Context: This code was written for a Kattis question https://open.kattis.com/problems/sylvester
Fixing your code: recursion in deepMap
With just a small modification to your deepMap function, it becomes faster and avoids stacking up thousands of recursive calls: replace return [deepMap(f,seq[0])] + deepMap(f,seq[1:]) with return [deepMap(f, x) for x in seq].
def deepMap(f,seq):
if seq == []:
return seq
elif type(seq) != list:
return f(seq)
else:
return [deepMap(f, x) for x in seq]
def Hadamard(n): #n is a power of 2
if n == 1:
return [1]
elif n == 2:
return [[1,1],[1,-1]]
else:
k = 2
array = [Hadamard(k)]
while k < n:
k *= 2
matrix,prev = [],array.pop(0)
for i in range(k):
if i < k//2:
matrix.append(prev[i]+prev[i])
else:
matrix.append(prev[i%(k//2)]+deepMap(lambda x: -x,prev[i%(k//2)]))
array.append(matrix)
#print(f'matrix {k} = {matrix}')
return array[0]
print( Hadamard(2048) ) # should take less than a second
A different version: avoiding .append
Since we already know the size of the matrix, I suggest creating a matrix that already has the correct size, then filling it recursively or iteratively. To fill the matrix, I made a function dup that duplicates a quadrant of the matrix to another quadrant.
def dup(h, k, i0,j0, s=1):
for i in range(k):
for j in range(k):
h[i0+i][j0+j] = s * h[i][j]
def had(n):
'''assume n >= 2 is a power of 2'''
h = [[0 for _ in range(n)] for _ in range(n)]
h[0][0]=1
h[0][1]=1
h[1][0]=1
h[1][1]=-1
k = 2
while k < n:
dup(h, k, 0,k)
dup(h, k, k,0)
dup(h, k, k,k, -1)
k *= 2
return h
print( had(2048) )
Using numpy: everything is easy with concatenate
Using numpy.concatenate, the code becomes much shorter, much much faster, and easier to read:
from numpy import array, concatenate
def hadamard(n):
'''assume n is a power of 2'''
if n == 1:
return array([1])
elif n == 2:
return array([[1,1],[1,-1]])
else:
a = hadamard(n // 2)
return concatenate(
(concatenate((a, a), axis=1),
concatenate((a, -a), axis=1)),
axis=0
)
print( hadamard(2048) )

Having trouble with implementeing the Miller-Rabin compositeness in Python

I'm not sure if this is the right place to post this question so if it isn't let me know! I'm trying to implement the Miller Rabin test in python. The test is to find the first composite number that is a witness to N, an odd number. My code works for numbers that are somewhat smaller in length but stops working when I enter a huge number. (The "challenge" wants to find the witness of N := 14779897919793955962530084256322859998604150108176966387469447864639173396414229372284183833167 in which my code returns that it is prime when it isn't) The first part of the test is to convert N into the form 2^k + q, where q is a prime number.
Is there some limit with python that doesn't allow huge numbers for this?
Here is my code for that portion of the test.
def convertN(n): #this turns n into 2^x * q
placeholder = False
list = []
#this will be x in the equation
count = 1
while placeholder == False:
#x = result of division of 2^count
x = (n / (2**count))
#y tells if we can divide by 2 again or not
y = x%2
#if y != 0, it means that we cannot divide by 2, loop exits
if y != 0:
placeholder = True
list.append(count) #x
list.append(x) #q
else:
count += 1
#makes list to return
#print(list)
return list
The code for the actual test:
def test(N):
#if even return false
if N == 2 | N%2 == 0:
return "even"
#convert number to 2^k+q and put into said variables
n = N - 1
nArray = convertN(n)
k = nArray[0]
q = int(nArray[1])
#this is the upper limit a witness can be
limit = int(math.floor(2 * (math.log(N))**2))
#Checks when 2^q*k = 1 mod N
for a in range(2,limit):
modu = pow(a,q,N)
for i in range(k):
print(a,i,modu)
if i==0:
if modu == 1:
break
elif modu == -1:
break
elif i != 0:
if modu == 1:
#print(i)
return a
#instead of recalculating 2^q*k+1, can square old result and modN that.
modu = pow(modu,2,N)
Any feedback is appreciated!
I don't like unanswered questions so I decided to give a small update.
So as it turns out I was entering the wrong number from the start. Along with that my code should have tested not for when it equaled to 1 but if it equaled -1 from the 2nd part.
The fixed code for the checking
#Checks when 2^q*k = 1 mod N
for a in range(2,limit):
modu = pow(a,q,N)
witness = True #I couldn't think of a better way of doing this so I decided to go with a boolean value. So if any of values of -1 or 1 when i = 0 pop up, we know it's not a witness.
for i in range(k):
print(a,i,modu)
if i==0:
if modu == 1:
witness = False
break
elif modu == -1:
witness = False
break
#instead of recalculating 2^q*k+1, can square old result and modN that.
modu = pow(modu,2,N)
if(witness == True):
return a
Mei, i wrote a Miller Rabin Test in python, the Miller Rabin part is threaded so it's very fast, faster than sympy, for larger numbers:
import math
def strailing(N):
return N>>lars_last_powers_of_two_trailing(N)
def lars_last_powers_of_two_trailing(N):
""" This utilizes a bit trick to find the trailing zeros in a number
Finding the trailing number of zeros is simply a lookup for most
numbers and only in the case of 1 do you have to shift to find the
number of zeros, so there is no need to bit shift in 7 of 8 cases.
In those 7 cases, it's simply a lookup to find the amount of zeros.
"""
p,y=1,2
orign = N
N = N&15
if N == 1:
if ((orign -1) & (orign -2)) == 0: return orign.bit_length()-1
while orign&y == 0:
p+=1
y<<=1
return p
if N in [3, 7, 11, 15]: return 1
if N in [5, 13]: return 2
if N == 9: return 3
return 0
def primes_sieve2(limit):
a = [True] * limit
a[0] = a[1] = False
for (i, isprime) in enumerate(a):
if isprime:
yield i
for n in range(i*i, limit, i):
a[n] = False
def llinear_diophantinex(a, b, divmodx=1, x=1, y=0, offset=0, withstats=False, pow_mod_p2=False):
""" For the case we use here, using a
llinear_diophantinex(num, 1<<num.bit_length()) returns the
same result as a
pow(num, 1<<num.bit_length()-1, 1<<num.bit_length()). This
is 100 to 1000x times faster so we use this instead of a pow.
The extra code is worth it for the time savings.
"""
origa, origb = a, b
r=a
q = a//b
prevq=1
#k = powp2x(a)
if a == 1:
return 1
if withstats == True:
print(f"a = {a}, b = {b}, q = {q}, r = {r}")
while r != 0:
prevr = r
a,r,b = b, b, r
q,r = divmod(a,b)
x, y = y, x - q * y
if withstats == True:
print(f"a = {a}, b = {b}, q = {q}, r = {r}, x = {x}, y = {y}")
y = 1 - origb*x // origa - 1
if withstats == True:
print(f"x = {x}, y = {y}")
x,y=y,x
modx = (-abs(x)*divmodx)%origb
if withstats == True:
print(f"x = {x}, y = {y}, modx = {modx}")
if pow_mod_p2==False:
return (x*divmodx)%origb, y, modx, (origa)%origb
else:
if x < 0: return (modx*divmodx)%origb
else: return (x*divmodx)%origb
def MillerRabin(arglist):
""" This is a standard MillerRabin Test, but refactored so it can be
used with multi threading, so you can run a pool of MillerRabin
tests at the same time.
"""
N = arglist[0]
primetest = arglist[1]
iterx = arglist[2]
powx = arglist[3]
withstats = arglist[4]
primetest = pow(primetest, powx, N)
if withstats == True:
print("first: ",primetest)
if primetest == 1 or primetest == N - 1:
return True
else:
for x in range(0, iterx-1):
primetest = pow(primetest, 2, N)
if withstats == True:
print("else: ", primetest)
if primetest == N - 1: return True
if primetest == 1: return False
return False
# For trial division, we setup this global variable to hold primes
# up to 1,000,000
SFACTORINT_PRIMES=list(primes_sieve2(100000))
# Uses MillerRabin in a unique algorithimically deterministic way and
# also uses multithreading so all MillerRabin Tests are performed at
# the same time, speeding up the isprime test by a factor of 5 or more.
# More k tests can be performed than 5, but in my testing i've found
# that's all you need.
def sfactorint_isprime(N, kn=5, trialdivision=True, withstats=False):
from multiprocessing import Pool
if N == 2:
return True
if N % 2 == 0:
return False
if N < 2:
return False
# Trial Division Factoring
if trialdivision == True:
for xx in SFACTORINT_PRIMES:
if N%xx == 0 and N != xx:
return False
iterx = lars_last_powers_of_two_trailing(N)
""" This k test is a deterministic algorithmic test builder instead of
using random numbers. The offset of k, from -2 to +2 produces pow
tests that fail or pass instead of having to use random numbers
and more iterations. All you need are those 5 numbers from k to
get a primality answer. I've tested this against all numbers in
https://oeis.org/A001262/b001262.txt and all fail, plus other
exhaustive testing comparing to other isprimes to confirm it's
accuracy.
"""
k = llinear_diophantinex(N, 1<<N.bit_length(), pow_mod_p2=True) - 1
t = N >> iterx
tests = []
if kn % 2 == 0: offset = 0
else: offset = 1
for ktest in range(-(kn//2), (kn//2)+offset):
tests.append(k+ktest)
for primetest in range(len(tests)):
if tests[primetest] >= N:
tests[primetest] %= N
arglist = []
for primetest in range(len(tests)):
if tests[primetest] >= 2:
arglist.append([N, tests[primetest], iterx, t, withstats])
with Pool(kn) as p:
s=p.map(MillerRabin, arglist)
if s.count(True) == len(arglist): return True
else: return False
sinn=14779897919793955962530084256322859998604150108176966387469447864639173396414229372284183833167
print(sfactorint_isprime(sinn))

How can I fix my function which is designed to solve determinants?

The function can accurately compute 1x1, 2x2, and 3x3 determinants, but it gives wrong values for higher order determinants. I'm thinking there's a problem with the part in the function where I call the function (recursion) to solve lower order determinants as part of the solution.
I suspect it has something to do with variable locality, but I'm not sure why that would be an issue because I thought locality was automatic.
This is Python 2 by the way.
Code:
def is_Det(matrix):
isdet = True
if not isinstance(matrix,list): # Is this actually a list?
isdet = False
for i in matrix:
if isinstance(i,list): # Things in matrix are lists?
if len(i) == len(matrix): # Square shape?
for j in i: # All numbers?
try:
j = float(j)
except ValueError:
isdet = False
else:
isdet = False
else:
isdet = False
return isdet
def det_Disp(matrix):
if is_Det(matrix):
pass
else:
print "Error: Input not a determinant, cannot display"
def det_Eval(matrix):
print matrix
except StandardError:
print "No such value"
if is_Det(matrix):
if len(matrix) == 1: # 1x1 determinant
print matrix[0][0]
return matrix[0][0]
elif len(matrix) == 2: # 2x2 determinant
print matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
else:
longdet = matrix # Expands higher-order determinant
for row1 in longdet:
for col1 in range(0,len(matrix)-1):
row1.append(row1[col1])
value = 0
for col2 in range(0,len(matrix)): # Recurse determinant value
subdet = []
for row2 in range(1,len(matrix)):
subsubdet = []
for col3 in range(col2+1,col2+len(matrix)):
subsubdet.append(longdet[row2][col3])
'''print "Subsubdet:",
print subsubdet #***************************'''
subdet.append(subsubdet)
'''# print "Subdet",
print "Subdet:",
print subdet #***************************'''
value += longdet[0][col2] * det_Eval(subdet)
##########print value
'''#print longdet[1][col2],
#print det_Eval(subdet),
#print value
# print longdet'''
return value
else:
print "Error: Input not a determinant, cannot evaluate"
#print det_Eval([[2,3],[4,9]])
#print det_Eval([[6,1,8],[9,9,9],[9,7,4]])
print det_Eval([[8,9,2,3],[4,6,1,8],[9,9,9,9],[1,9,7,4]])
In this line dealing with minors:
value += longdet[0][col2] * det_Eval(subdet)
you don't take sign into account - sign depends on parity of index of the first line element (col2)

Python: break out of multiple levels of loop

I have this pseudocode for a Miller-Rabin primality tester:
function isPrime(n, k=5)
if n < 2 then return False
for p in [2,3,5,7,11,13,17,19,23,29]
if n % p == 0 then return n == p
s, d = 0, n-1
while d % 2 == 0
s, d = s+1, d/2
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
if x == n-1 then next i
return False
return True
But translating that to Python is hard because of the next i statement in the inner for loop, which must break two loops. There is no goto in Python. Other questioners who have asked this question on Stack Overflow have been told to use a local function with a return, or a try/except condition, or an additional boolean flag, but those solutions either don't apply here or would greatly uglify this lovely pseudocode.
What is the Pythonic approach to this problem?
I think the pythonic approach would be try/except, readability would prefer a method or a boolean, but I think that this is solvable by adding a single line:
for i in xrange(k):
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1: continue
for r in xrange(1,s):
x = (x * x) % n
if x == 1: return False
if x == n-1: break #*
if x != n-1: #added line
return False
return True
breaking on the line marked with #* is problematic because it returns false, but if we fix that it's just like "next i".
Another solution, suggested by tobias_k, is to use for/else:
for i in xrange(k):
x = powerMod(randint(2, n-1), d, n)
if x == 1 or x == n-1: continue
for r in xrange(1,s):
x = (x * x) % n
if x == 1: return False
if x == n-1: break
else: #added line
return False
return True
return False statement would not be called if the loop was break-ed - only if it was exhausted.
You can use break and continue witn a for: else.
for i from 0 to k
x = powerMod(randint(2, n-1), d, n)
# Use 'continue' to go to next i (skip inner loop).
if x == 1 or x == n-1 then next i
for r from 1 to s
x = (x * x) % n
if x == 1 then return False
# Use 'break' to exit this loop and go to next i
# since this loop is at the end of the i loop.
if x == n-1 then next i
else:
# This is only reached if no `break` occurred
return False
return True

Categories