Let's assume we have a 2D array that looks like this
array = [[1,2,3],
[4,5,6]]
As you can see, it's not a square 2D array, and we have a function that sums all the values in it.
def sum_values(array):
total = 0
for i in array:
for j in i:
total += j
return total
So the question is, is the time complexity still O(n^2)? or something like O(ab) or something else?
you can define n as the size of the input matrix and say the algorithm is O(n) or you can define n as the number of rows and m as the number of columns in the input and say the algorithm is O(n*m)
Related
I am trying to generate all possible 2D arrays (of size n*n) of 0 and 1. Since there are two choices for each entry of the 2D array, there are 2^{n^2} such arrays that need to be generated.
I have a code that generates all possible 1D arrays (of size n) of 0 and 1. It is:
def generateAllSpinConfigs(n,arr,l,i):
if i == n:
l.append(arr[:])
return
arr[i] = 0
generateAllSpinConfigs(n,arr,l,i+1)
arr[i] = 1
generateAllSpinConfigs(n,arr,l,i+1)
return l
arr=[None]*n
l=[]
answer=generateAllSpinConfigs(n,arr,l,0)
I understand how that works. In this recursive code, the lowest function call returns an array of all 0 first, then an array with all 0 with a 1 in the last location and so on.
Can we extend this logic to generate all 2D arrays or is there a Python function that does the job that I'm not aware of?
You can use itertools.product. First to generate 1-dimensional lists, and then again to use that as a basis to increase the dimension:
from itertools import product
def get_bin_rows(size):
return product(range(2), repeat=size)
def get_bin_matrices(size):
return product(get_bin_rows(size), repeat=size)
Example use for n=2:
for matrix in get_bin_matrices(2):
# print matrix row by row
for row in matrix:
print(*row)
print() # separate matrix outputs
I have a numpy.ndarray variable A of size MxN. I wish to take each row and multiply with it's conjugate transposed. For the first row we will get:
np.matmul(np.expand_dims(A[0,:],axis=1),np.expand_dims(A[0,:].conj(),axis=0))
we get an NxN sized result. I want the final result for the total operation to be of size MxNxN.
I can fo this with a simple loop which iterates over the rows of A and concatenates the results. I wish to avoid a for loop for a faster run time with SIMD operations. Is there a way to do this in a single code line with broadcasting?
Otherwise, can I do something else and somehow reshape the results into my requierment?
The next code does what the same as your code snippet but without for-loop. On the other hand, it uses np.repeat twice, so you will need to benchmark both versions and compare them to test their memory/time performance.
import numpy as np
m, n = A.shape
x, y = A.conj().repeat(n, axis=0), A.reshape([-1, 1]).repeat(n, axis=1)
B = (x * y).reshape([m, n, n])
How it works
Basically x holds the conjugate values of the array A in a single column and then is repeated n times on the column axis (it has a shape m*n by n).
y repeats each row in the conjugate matrix of A, n consecutive times (its final shape is m*n by n also)
x and y are multiplied element-wise and the result is unwrapped to a matrix of shape m by n by n stored in B
A list comprehension comprehension could do the trick:
result = np.array([np.matmul(np.expand_dims(A[i,:],axis=1), np.expand_dims(A[i,:].conj(),axis=0)) for i in range(A.shape[0])])
Pardon me for a basic question(I am new to Theano)!
I want to get the difference of 2 matrices for only those positions that satisfy a condition. So, suppose we have 2 matrices A and B, this(python equivalent code) is what I want to calculate:
sum = 0
n,m = A.shape
for i in xrange(n):
for j in xrange(m):
if(A[i][j] != 3.5): #some random condition!
sum += A[i][j] - B[i][j]
I want a Theano equivalent code to calculate the sum.
I know there is Theano.scan that can be used to scan an ndarray, but I could not get any example that has an if condition.
Thank you in advance :)
I currently have the following double loop in my Python code:
for i in range(a):
for j in range(b):
A[:,i]*=B[j][:,C[i,j]]
(A is a float matrix. B is a list of float matrices. C is a matrix of integers. By matrices I mean m x n np.arrays.
To be precise, the sizes are: A: mxa B: b matrices of size mxl (with l different for each matrix) C: axb. Here m is very large, a is very large, b is small, the l's are even smaller than b
)
I tried to speed it up by doing
for j in range(b):
A[:,:]*=B[j][:,C[:,j]]
but surprisingly to me this performed worse.
More precisely, this did improve performance for small values of m and a (the "large" numbers), but from m=7000,a=700 onwards the first appraoch is roughly twice as fast.
Is there anything else I can do?
Maybe I could parallelize? But I don't really know how.
(I am not committed to either Python 2 or 3)
Here's a vectorized approach assuming B as a list of arrays that are of the same shape -
# Convert B to a 3D array
B_arr = np.asarray(B)
# Use advanced indexing to index into the last axis of B array with C
# and then do product-reduction along the second axis.
# Finally, we perform elementwise multiplication with A
A *= B_arr[np.arange(B_arr.shape[0]),:,C].prod(1).T
For cases with smaller a, we could run a loop that iterates through the length of a instead. Also, for more performance, it might be a better idea to store those elements into a separate 2D array instead and perform the elementwise multiplication only once after we get out of the loop.
Thus, we would have an alternative implementation like so -
range_arr = np.arange(B_arr.shape[0])
out = np.empty_like(A)
for i in range(a):
out[:,i] = B_arr[range_arr,:,C[i,:]].prod(0)
A *= out
Given the number of rows (or columns) , n, of a square matrix, I am trying to get the index pairs of the lower triangular matrix in a 1 dimensional list. So far I thought of the following solution:
def getLowerTriangularIndices(n):
inds=[];
for i in range(1,n):
for j in range(i):
inds.append((i,j))
return inds;
Considering the two for loops, it would be far better to have a more efficient way of calculating this maybe using numpy. Does anyone have a suggestion?
Numpy has a method for that...
import numpy as np
# create your matrix. If it's not yet a numpy array, make it one
ar = np.array(matrix)
indices = np.tril_indices_from(ar)
This returns a tuple of two arrays. If you want to have them as lists, you could do
indices = [list(x) for x in np.tril_indices_from(ar)]
You actually do not need to have an array to get the indices, there is also np.tril_indices, which takes the shape as arguments.
So your function would read:
def getLowerTriangularIndices(n):
return [list(x) for x in np.tril_indices(n)]
or if you want a list of tuples instead:
def getLowerTriangularIndices(n):
return zip(*np.tril_indices(n)]