@@ -842,6 +842,7 @@ The eigenvectors and eigenvalues of a map $A$ determine how a vector $v$ is tran
842842
843843This is discussed further later.
844844
845+ ## Exercises
845846
846847``` {exercise}
847848:label: eig1_ex1
@@ -865,6 +866,10 @@ Visualize your results by plotting the eigenvalue as a function of the number of
865866:class: dropdown
866867```
867868
869+ Here is one solution.
870+
871+ We start by looking into the distance between the eigenvector approximation and the true eigenvector.
872+
868873``` {code-cell} ipython3
869874# Define a matrix A
870875A = np.array([[1, 0, 3],
@@ -878,6 +883,7 @@ num_iters = 20
878883b = np.random.rand(A.shape[1])
879884
880885# Initialize a list to store the eigenvector approximations
886+ norm_ls = []
881887res = []
882888
883889# Power iteration loop
@@ -887,53 +893,29 @@ for i in range(num_iters):
887893 # Normalize b
888894 b = b / np.linalg.norm(b)
889895 # Append b to the list of eigenvector approximations
890- dis = np.linalg.norm(np.array(b) - np.linalg.eig(A)[1][:, 0])
891- res.append(dis)
896+ res.append(b)
897+ norm = np.linalg.norm(np.array(b) - np.linalg.eig(A)[1][:, 0])
898+ norm_ls.append(norm)
892899
893900# Plot the eigenvector approximations for each iteration
894901plt.figure(figsize=(10, 6))
895902plt.xlabel('Iterations')
896903plt.ylabel('L2 Norm')
897- plt.title('Power Iteration and Eigenvector Approximations ')
898- _ = plt.plot(res )
904+ plt.title('Distance between the Approximation and the True Eigenvector ')
905+ _ = plt.plot(norm_ls )
899906```
900907
901- ``` {code-cell} ipython3
902- import numpy as np
903- import matplotlib.pyplot as plt
904- from mpl_toolkits.mplot3d import Axes3D
905-
906- # Define a matrix A
907- A = np.array([[1, 0, 3],
908- [0, 2, 0],
909- [3, 0, 1]])
910-
911- # Define a number of iterations
912- num_iters = 20
913-
914- # Define a random starting vector b
915- b = np.array([0.5, 1, 0.5])
916-
917- # Initialize a list to store the eigenvector approximations
918- res = [b]
908+ Then we can look at the trajectory of the eigenvector approximation
919909
920- # Power iteration loop
921- for i in range(num_iters):
922- # Multiply b by A
923- b = A @ b
924- # Normalize b
925- b = b / np.linalg.norm(b)
926- # Append b to the list of eigenvector approximations
927- res.append(b)
928-
929- # Get the actual eigenvectors of matrix A
910+ ``` {code-cell} ipython3
911+ # Get the eigenvectors of matrix A
930912eigenvector = np.linalg.eig(A)[1][:, 0]
913+
931914# Set up the figure and axis for 3D plot
932915fig = plt.figure()
933916ax = fig.add_subplot(111, projection='3d')
934917
935- # Plot the actual eigenvectors
936-
918+ # Plot the eigenvectors
937919ax.scatter(eigenvector[0], eigenvector[1], eigenvector[2], color='r', s = 80)
938920
939921# Plot the approximated eigenvectors (b) at each iteration
@@ -943,7 +925,7 @@ for i, vec in enumerate(res):
943925ax.set_xlabel('X')
944926ax.set_ylabel('Y')
945927ax.set_zlabel('Z')
946- ax.set_title('Power iteration eigenvector approximations ')
928+ ax.set_title('Power Iteration and Eigenvector Approximations ')
947929points = [plt.Line2D([0], [0], linestyle='none', c=i, marker='o') for i in ['r', 'b']]
948930ax.legend(points, ['Actual eigenvectors', 'Approximated eigenvectors (b)'], numpoints=1)
949931ax.set_box_aspect(aspect=None, zoom=0.8)
@@ -1006,8 +988,10 @@ c.arrows.set_alpha(0.5)
1006988
1007989# Plot the eigenvectors as long blue and green arrows
1008990origin = np.zeros((2, len(eigenvectors)))
1009- plt.quiver(*origin, eigenvectors[0], eigenvectors[1], color=['b', 'g'], angles='xy', scale_units='xy', scale=0.1, width=0.01)
1010- plt.quiver(*origin, - eigenvectors[0], - eigenvectors[1], color=['b', 'g'], angles='xy', scale_units='xy', scale=0.1, width=0.01)
991+ parameters = {'color':['b', 'g'], 'angles':'xy',
992+ 'scale_units':'xy', 'scale':0.1, 'width':0.01}
993+ plt.quiver(*origin, eigenvectors[0], eigenvectors[1], **parameters)
994+ plt.quiver(*origin, - eigenvectors[0], - eigenvectors[1], **parameters)
1011995
1012996colors = ['b', 'g']
1013997lines = [Line2D([0], [0], color=c, linewidth=3) for c in colors]
@@ -1094,7 +1078,8 @@ for i, example in enumerate(examples):
10941078 c.arrows.set_alpha(0.5)
10951079
10961080 # Plot the eigenvectors as long blue and green arrows
1097- parameters = {'color':['b', 'g'], 'angles':'xy', 'scale_units':'xy', 'scale':1, 'width':0.01, 'alpha':0.5}
1081+ parameters = {'color':['b', 'g'], 'angles':'xy',
1082+ 'scale_units':'xy', 'scale':1, 'width':0.01, 'alpha':0.5}
10981083 origin = np.zeros((2, len(eigenvectors)))
10991084 ax[i].quiver(*origin, eigenvectors_real[0], eigenvectors_real[1], **parameters)
11001085 ax[i].quiver(*origin, - eigenvectors_real[0], - eigenvectors_real[1], **parameters)
@@ -1107,6 +1092,8 @@ for i, example in enumerate(examples):
11071092plt.show()
11081093```
11091094
1095+ The vector fields explains why we observed the trajectories of the vector $v$ multiplied by $A$ iteratively before.
1096+
11101097The pattern demonstrated here is because we have complex eigenvalues and eigenvectors.
11111098
11121099It is important to acknowledge that there is a complex plane.
@@ -1129,18 +1116,11 @@ class Arrow3D(FancyArrowPatch):
11291116 self.set_positions((0.1*xs[0],0.1*ys[0]),(0.1*xs[1],0.1*ys[1]))
11301117
11311118 return np.min(zs)
1132-
1133-
1134- # Define matrix A with complex eigenvalues
1135- A = np.array([[sqrt(3) + 1, -2],
1136- [1, sqrt(3) - 1]])
1137- A = (1/(2*sqrt(2))) * A
11381119
1139- # Find eigenvalues and eigenvectors
11401120eigenvalues, eigenvectors = np.linalg.eig(A)
11411121
11421122# Create meshgrid for vector field
1143- x, y = np.meshgrid(np.linspace(-2, 2, 10 ), np.linspace(-2, 2, 10 ))
1123+ x, y = np.meshgrid(np.linspace(-2, 2, 15 ), np.linspace(-2, 2, 15 ))
11441124
11451125# Calculate vector field (real and imaginary parts)
11461126u_real = A[0][0] * x + A[0][1] * y
@@ -1154,7 +1134,7 @@ ax = fig.add_subplot(111, projection='3d')
11541134vlength = np.linalg.norm(eigenvectors)
11551135ax.quiver(x, y, u_imag, u_real-x, v_real-y, v_imag-u_imag, colors = 'b', alpha=0.3, length = .2, arrow_length_ratio = 0.01)
11561136
1157- arrow_prop_dict = dict(mutation_scale=2 , arrowstyle='-|>', shrinkA=0, shrinkB=0)
1137+ arrow_prop_dict = dict(mutation_scale=5 , arrowstyle='-|>', shrinkA=0, shrinkB=0)
11581138
11591139# Plot 3D eigenvectors
11601140for c, i in zip(['b', 'g'], [0, 1]):
0 commit comments