GitHub

@@ -997,12 +997,6 @@ Here is one solution.

997997

We 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

10071001

A = np.array([[1, 0, 3],

10081002

[0, 2, 0],

@@ -1040,20 +1034,14 @@ print('The real eigenvalue is', np.linalg.eig(A)[0])

10401034

plt.figure(figsize=(10, 6))

10411035

plt.xlabel('iterations')

10421036

plt.ylabel('error')

1037+

plt.title('Power iteration')

10431038

_ = plt.plot(errors)

10441039

```

104510401046-

+++ {"user_expressions": []}

1047-10481041

Then 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

10581046

fig = plt.figure()

10591047

ax = fig.add_subplot(111, projection='3d')

@@ -1081,11 +1069,11 @@ ax.legend(points, ['actual eigenvector',

10811069

r'approximated eigenvector ($b_k$)'])

10821070

ax.set_box_aspect(aspect=None, zoom=0.8)

108310711072+

ax.set_title('Power iteration trajectory')

1073+10841074

plt.show()

10851075

```

108610761087-

+++ {"user_expressions": []}

1088-10891077

```{solution-end}

10901078

```

10911079

@@ -1119,21 +1107,14 @@ print(f'eigenvectors:\n {eigenvectors}')

11191107

plot_series(A, v, n)

11201108

```

112111091122-

+++ {"user_expressions": []}

1123-11241110

The result seems to converge to the eigenvector of $A$ with the largest eigenvalue.

1125111111261112

Let'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

11381119

x, 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',

1165114611661147

plt.xlabel("x")

11671148

plt.ylabel("y")

1149+

plt.title("Convergence towards eigenvectors")

11681150

plt.grid()

11691151

plt.gca().set_aspect('equal', adjustable='box')

11701152

plt.show()

11711153

```

117211541173-

+++ {"user_expressions": []}

1174-11751155

Note 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.

1176115611771157

In 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

12001180

Here 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))

12101185

A = np.array([[sqrt(3) + 1, -2],

12111186

[1, sqrt(3) - 1]])

12121187

A = (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")

12671243

plt.show()

12681244

```

126912451270-

+++ {"user_expressions": []}

1271-12721246

The vector fields explain why we observed the trajectories of the vector $v$ multiplied by $A$ iteratively before.

1273124712741248

The pattern demonstrated here is because we have complex eigenvalues and eigenvectors.

1275124912761250

We 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+12851254

class 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')

13341303

ax.set_zlabel('Im')

13351304

ax.set_box_aspect(aspect=None, zoom=0.8)

133613051306+

plt.title("3D plot of the vector field")

13371307

plt.draw()

13381308

plt.show()

13391309

```

134013101341-

+++ {"user_expressions": []}

1342-13431311

```{solution-end}

13441312

```

Read the original on github.com ↗