I want to improve my code to make it faster and for now, I have a for loop that I don't know how to replace it with numpy functions.
import numpy as np
N = 1000000
d = 2000
p = np.linspace(0,210,211)
alpha = np.linspace(0.00000000000001, np.pi/2, N)
d1 = d*np.cos(alpha)
for i in range(len(p)):
p1 = p[i]*np.cos(alpha)
k = 1/((p[i]+d)*np.tan(alpha))
z = np.exp(p1+d1)**k
First, I tried to vectorize the p1, d1 and k to a matrix with right sizes, but I don't know how to calculate the z without a loop. Furthermore, I think this is not an effective way.
import numpy as np
N = 1000000
d = 2000
p = np.linspace(0,210,211)
alpha = np.linspace(0.00000000000001, np.pi/2, N)
d1 = d*np.cos(alpha)
p1 = np.outer(np.cos(alpha),p)
d1 = np.matrix(d1).T * np.matrix(np.ones(len(p)))
k = 1/(np.outer(np.tan(alpha),p)+np.outer(np.tan(alpha),d))
If you want one row per element in p
, and one column per element in alpha
, you just need to add an axis to p
so it's a column vector. Numpy's broadcasting takes care of the rest:
import numpy as np
N = 100 # modified to run quickly
d = 20
# reshape p to a column vector
p = np.linspace(0,210,211).reshape((-1, 1))
alpha = np.linspace(0.00000000000001, np.pi/2, N)
d1 = d*np.cos(alpha)
p1 = p*np.cos(alpha) # shape (211, 100)
k = 1/((p+d)*np.tan(alpha))
z = np.exp(p1+d1)**k
Note that the power operation overflows to infinity, but that's not related to numpy.
Also note that while this answer does show you how to vectorize your operation, it might not make sense to do so since you're only saving a 211-iteration loop. It makes a lot more sense to vectorize larger loops, such as if p.size
was much greater than alpha.size