@@ -997,12 +997,6 @@ Here is one solution.
997997We start by looking into the distance between the eigenvector approximation and the true eigenvector.
998998999999```{code-cell} ipython3
1000----
1001-mystnb:
1002- figure:
1003- caption: Power iteration
1004- name: pow-dist
1005----
10061000# Define a matrix A
10071001A = np.array([[1, 0, 3],
10081002 [0, 2, 0],
@@ -1040,20 +1034,14 @@ print('The real eigenvalue is', np.linalg.eig(A)[0])
10401034plt.figure(figsize=(10, 6))
10411035plt.xlabel('iterations')
10421036plt.ylabel('error')
1037+plt.title('Power iteration')
10431038_ = plt.plot(errors)
10441039```
104510401046-+++ {"user_expressions": []}
1047-10481041Then we can look at the trajectory of the eigenvector approximation.
1049104210501043```{code-cell} ipython3
1051----
1052-mystnb:
1053- figure:
1054- caption: Power iteration trajectory
1055- name: pow-trajectory
1056----
1044+10571045# Set up the figure and axis for 3D plot
10581046fig = plt.figure()
10591047ax = fig.add_subplot(111, projection='3d')
@@ -1081,11 +1069,11 @@ ax.legend(points, ['actual eigenvector',
10811069 r'approximated eigenvector ($b_k$)'])
10821070ax.set_box_aspect(aspect=None, zoom=0.8)
108310711072+ax.set_title('Power iteration trajectory')
1073+10841074plt.show()
10851075```
108610761087-+++ {"user_expressions": []}
1088-10891077```{solution-end}
10901078```
10911079@@ -1119,21 +1107,14 @@ print(f'eigenvectors:\n {eigenvectors}')
11191107plot_series(A, v, n)
11201108```
112111091122-+++ {"user_expressions": []}
1123-11241110The result seems to converge to the eigenvector of $A$ with the largest eigenvalue.
1125111111261112Let's use a [vector field](https://en.wikipedia.org/wiki/Vector_field) to visualize the transformation brought by A.
1127111311281114(This is a more advanced topic in linear algebra, please step ahead if you are comfortable with the math.)
1129111511301116```{code-cell} ipython3
1131----
1132-mystnb:
1133- figure:
1134- caption: Convergence towards eigenvectors
1135- name: eigen-conv
1136----
1117+11371118# Create a grid of points
11381119x, y = np.meshgrid(np.linspace(-5, 5, 15),
11391120 np.linspace(-5, 5, 20))
@@ -1165,13 +1146,12 @@ plt.legend(lines, labels, loc='center left',
1165114611661147plt.xlabel("x")
11671148plt.ylabel("y")
1149+plt.title("Convergence towards eigenvectors")
11681150plt.grid()
11691151plt.gca().set_aspect('equal', adjustable='box')
11701152plt.show()
11711153```
117211541173-+++ {"user_expressions": []}
1174-11751155Note that the vector field converges to the eigenvector of $A$ with the largest eigenvalue and diverges from the eigenvector of $A$ with the smallest eigenvalue.
1176115611771157In fact, the eigenvectors are also the directions in which the matrix $A$ stretches or shrinks the space.
@@ -1200,13 +1180,8 @@ Use the visualization in the previous exercise to explain the trajectory of the
12001180Here is one solution
1201118112021182```{code-cell} ipython3
1203----
1204-mystnb:
1205- figure:
1206- caption: Vector fields of the three matrices
1207- name: vector-field
1208----
1209-figure, ax = plt.subplots(1, 3, figsize=(15, 5))
1183+1184+fig, ax = plt.subplots(1, 3, figsize=(15, 5))
12101185A = np.array([[sqrt(3) + 1, -2],
12111186 [1, sqrt(3) - 1]])
12121187A = (1/(2*sqrt(2))) * A
@@ -1264,24 +1239,18 @@ for i, example in enumerate(examples):
12641239 ax[i].grid()
12651240 ax[i].set_aspect('equal', adjustable='box')
126612411242+fig.suptitle("Vector fields of the three matrices")
12671243plt.show()
12681244```
126912451270-+++ {"user_expressions": []}
1271-12721246The vector fields explain why we observed the trajectories of the vector $v$ multiplied by $A$ iteratively before.
1273124712741248The pattern demonstrated here is because we have complex eigenvalues and eigenvectors.
1275124912761250We can plot the complex plane for one of the matrices using `Arrow3D` class retrieved from [stackoverflow](https://stackoverflow.com/questions/22867620/putting-arrowheads-on-vectors-in-a-3d-plot).
1277125112781252```{code-cell} ipython3
1279----
1280-mystnb:
1281- figure:
1282- caption: 3D plot of the vector field
1283- name: 3d-vector-field
1284----
1253+12851254class Arrow3D(FancyArrowPatch):
12861255 def __init__(self, xs, ys, zs, *args, **kwargs):
12871256 super().__init__((0, 0), (0, 0), *args, **kwargs)
@@ -1334,11 +1303,10 @@ ax.set_ylabel('y')
13341303ax.set_zlabel('Im')
13351304ax.set_box_aspect(aspect=None, zoom=0.8)
133613051306+plt.title("3D plot of the vector field")
13371307plt.draw()
13381308plt.show()
13391309```
134013101341-+++ {"user_expressions": []}
1342-13431311```{solution-end}
13441312```