I am wanting to produce a meshgrid whose coordinates have been rotated. I have to do the rotation in a double loop and I'm sure there is a better way to vectorize it. The code goes as so:
# Define the range for x and y in the unrotated matrix
xspan = linspace(-2*pi, 2*pi, 101)
yspan = linspace(-2*pi, 2*pi, 101)
# Generate a meshgrid and rotate it by RotRad radians.
def DoRotation(xspan, yspan, RotRad=0):
# Clockwise, 2D rotation matrix
RotMatrix = np.array([ [np.cos(RotRad), np.sin(RotRad)],
[-np.sin(RotRad), np.cos(RotRad)]])
print RotMatrix
# This makes two 2D arrays which are the x and y coordinates for each point.
x, y = meshgrid(xspan,yspan)
# After rotating, I'll have another two 2D arrays with the same shapes.
xrot = zeros(x.shape)
yrot = zeros(y.shape)
# Dot the rotation matrix against each coordinate from the meshgrids.
# I BELIEVE THERE IS A BETTER WAY THAN THIS DOUBLE LOOP!!!
# I BELIEVE THERE IS A BETTER WAY THAN THIS DOUBLE LOOP!!!
# I BELIEVE THERE IS A BETTER WAY THAN THIS DOUBLE LOOP!!!
# I BELIEVE THERE IS A BETTER WAY THAN THIS DOUBLE LOOP!!!
# I BELIEVE THERE IS A BETTER WAY THAN THIS DOUBLE LOOP!!!
# I BELIEVE THERE IS A BETTER WAY THAN THIS DOUBLE LOOP!!!
for i in range(len(xspan)):
for j in range(len(yspan)):
xrot[i,j], yrot[i,j] = dot(RotMatrix, array([x[i,j], y[i,j]]))
# Now the matrix is rotated
return xrot, yrot
# Pick some arbitrary function and plot it (no rotation)
x, y = DoRotation(xspan, yspan, 0)
z = sin(x)+cos(y)
imshow(z)
# And now with 0.3 radian rotation so you can see that it works.
x, y = DoRotation(xspan, yspan, 0.3)
z = sin(x)+cos(y)
figure()
imshow(z)
It seems silly to have to write a double loop over the two meshgrids. Do one of the wizards out there have an idea how to vectorize this?
You can get rid of those two nested loops with some
reshaping
&flattening with np.ravel
and keeping that matrix multiplication withnp.dot
like so -Maybe I misunderstand the question, but I usually just...
~100ms also
Einstein summation (
np.einsum
) is very quick for this sort of thing. I got 97 ms for 1001x1001.