Python meets linear algebra
Statistics and linear algebra seem like a pair that should always be married to each other. This is hardly the case however. If you are like me and you fancy remembering the equation for say the correlation between two variables without memorizing the formula, then you should probably pick a linear algebra text by Gilbert Strang or head over to his MIT vidoes on youtube which can be found here. Trust me this will be very illuminating.
I will give some examples in case you are still not convinced. We have two variables
Pardon my lack of creativity but these two vectors will do. If you wanted to calculate the correlation between these two vectors(variables), from statistics we would need to do
I think the most interesting of these objects is the regression of y on x. Linear algebra tells us that if y is not in the column space of x then there is no way to arrive at a solution however, we can arrive at an approximation by projecting y orthogonally on x. This is a pretty neat discovery as one can easily imagine two lines x and y, going in different directions, then from the shadow y makes on x, we can create a new vector
I have always liked to make images move around on my screen, however, until I understood better transition matrices and change of basis I never had a good grasp of how things worked under the hood. Do you feel anxious about transition matrices and change of basis? Don't worry they are just fancy names of what happens when you multiply matrices. The matrix multiplication
I want to explain how to generate a transition matrix, that flips a vector in
Lets try to extend this result with a little bit of trigonometry. We know that
x
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
# The angles we want to test with
thetas = [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360]
plt.ioff()
for theta in thetas:
# The transition matrix generalized with sines and cosines
matrix = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
ax.set_xlim(-100, 100)
ax.set_ylim(-100, 100)
# Using numpy to multiply the matrix and the vector to get new cordinates
vec1 = np.matmul(matrix, np.array([-25, -25]))
vec2 = np.matmul(matrix, np.array([-25, 25]))
vec3 = np.matmul(matrix, np.array([25, 25]))
vec4 = np.matmul(matrix, np.array([25, -25]))
vec5 = np.matmul(matrix, np.array([-10,24]))
vec6 = np.matmul(matrix, np.array([-10,40]))
vec7 = np.matmul(matrix, np.array([10,40]))
vec8 = np.matmul(matrix, np.array([10,24]))
x = [vec1[0], vec2[0], vec3[0], vec4[0]]
y = [vec1[1], vec2[1], vec3[1], vec4[1]]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=True))
x = [vec5[0], vec6[0], vec7[0], vec8[0]]
y = [vec5[1], vec6[1], vec7[1], vec8[1]]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=True))
plt.draw()
plt.pause(0.4)
plt.clf()
If you run the above code you will get two rectangles that look like a head and a body moving around by the angle specified by theta.
This was pretty tidy, however what happens when we want to say for example reflect about the line
Since we humans haven't yet developed the sense of understanding this new cordinate system, if you wanted to show your new results to your friends, you will need to make some adjustments. Linear algebra comes to the rescue as we can switch from this new cordinate system to a more traditional one. There is a pretty neat technique for doing this called diagonilazation of a matrix. The formula is given by
x
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
theta = 0
matrix = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]])
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
ax.set_xlim(-100, 100)
ax.set_ylim(-100, 100)
vec1 = np.matmul(matrix, np.array([-25, -25]))
vec2 = np.matmul(matrix, np.array([-25, 25]))
vec3 = np.matmul(matrix, np.array([25, 25]))
vec4 = np.matmul(matrix, np.array([25, -25]))
vec5 = np.matmul(matrix, np.array([-10,24]))
vec6 = np.matmul(matrix, np.array([-10,40]))
vec7 = np.matmul(matrix, np.array([10,40]))
vec8 = np.matmul(matrix, np.array([10,24]))
x = [vec1[0], vec2[0], vec3[0], vec4[0]]
y = [vec1[1], vec2[1], vec3[1], vec4[1]]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=True))
x = [vec5[0], vec6[0], vec7[0], vec8[0]]
y = [vec5[1], vec6[1], vec7[1], vec8[1]]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=True))
# Set the line x = [1, 2]
x = [-100, 100]
y = [-200, 200]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=False))
plt.show()
matrix = np.array([[-3/5, 4/5], [4/5, 3/5]])
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
ax.set_xlim(-100, 100)
ax.set_ylim(-100, 100)
vec1 = np.matmul(matrix, np.array([-25, -25]))
vec2 = np.matmul(matrix, np.array([-25, 25]))
vec3 = np.matmul(matrix, np.array([25, 25]))
vec4 = np.matmul(matrix, np.array([25, -25]))
vec5 = np.matmul(matrix, np.array([-10,24]))
vec6 = np.matmul(matrix, np.array([-10,40]))
vec7 = np.matmul(matrix, np.array([10,40]))
vec8 = np.matmul(matrix, np.array([10,24]))
x = [vec1[0], vec2[0], vec3[0], vec4[0]]
y = [vec1[1], vec2[1], vec3[1], vec4[1]]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=True))
x = [vec5[0], vec6[0], vec7[0], vec8[0]]
y = [vec5[1], vec6[1], vec7[1], vec8[1]]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=True))
# Set the line x = [1, 2]
x = [-100, 100]
y = [-200, 200]
ax.add_patch(patches.Polygon(xy=list(zip(x,y)), fill=False))
plt.show()
The results can be extended into 3 dimensions with a little more work.
Thanks.
I read the above article and I got some different kind of information from your article about a mattress. It is a helpful article to enhance our knowledge for us. Thankful to you for sharing an article like this.Abacus For Kids
ReplyDeleteBest amazing blog i like it Technology Blog
ReplyDelete