Skip to content

Commit 9b19b60

Browse files
Minor updates
1 parent 1d35cb5 commit 9b19b60

File tree

1 file changed

+63
-55
lines changed

1 file changed

+63
-55
lines changed

lectures/eigen_I.md

Lines changed: 63 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ from mpl_toolkits.mplot3d import proj3d
5959

6060
Let's start by discussing an important concept concerning matrices.
6161

62-
### Mapping vectors into vectors
62+
### Mapping vectors to vectors
6363

6464
One way to think about a matrix is as a rectangular collection of
6565
numbers.
6666

6767
Another way to think about a matrix is as a *map* (i.e., as a function) that
68-
transforms vectors into new vectors.
68+
transforms vectors to new vectors.
6969

7070
To understand the second point of view, suppose we multiply an $n \times m$
7171
matrix $A$ with an $m \times 1$ column vector $x$ to obtain an $n \times 1$
@@ -76,9 +76,9 @@ $$
7676
$$
7777

7878
If we fix $A$ and consider different choices of $x$, we can understand $A$ as
79-
a map transforming $x$ into $Ax$.
79+
a map transforming $x$ to $Ax$.
8080

81-
Because $A$ is $n \times m$, it transforms $m$-vectors into $n$-vectors.
81+
Because $A$ is $n \times m$, it transforms $m$-vectors to $n$-vectors.
8282

8383
We can write this formally as $A \colon \mathbb{R}^m \rightarrow \mathbb{R}^n$.
8484

@@ -89,11 +89,11 @@ $A(x) = y$ rather than $Ax = y$ but the second notation is more conventional.
8989

9090
Let's restrict our discussion to square matrices.
9191

92-
In the above discussion, this means that $m=n$ and $A$ maps $\mathbb R^n$ into
92+
In the above discussion, this means that $m=n$ and $A$ maps $\mathbb R^n$ to
9393
itself.
9494

9595
This means $A$ is an $n \times n$ matrix that maps (or "transforms") a vector
96-
$x$ in $\mathbb{R}^n$ into a new vector $y=Ax$ also in $\mathbb{R}^n$.
96+
$x$ in $\mathbb{R}^n$ to a new vector $y=Ax$ also in $\mathbb{R}^n$.
9797

9898
Here's one example:
9999

@@ -121,7 +121,7 @@ $$
121121
\end{bmatrix}
122122
$$
123123

124-
transforms the vector $x = \begin{bmatrix} 1 \\ 3 \end{bmatrix}$ into the vector
124+
transforms the vector $x = \begin{bmatrix} 1 \\ 3 \end{bmatrix}$ to the vector
125125
$y = \begin{bmatrix} 5 \\ 2 \end{bmatrix}$.
126126

127127
Let's visualize this using Python:
@@ -193,7 +193,7 @@ We consider how a given matrix transforms
193193

194194
To build the transformations we will use two functions, called `grid_transform` and `circle_transform`.
195195

196-
Each of these functions visualizes the action of a given $2 \times 2$ matrix $A$.
196+
Each of these functions visualizes the actions of a given $2 \times 2$ matrix $A$.
197197

198198
```{code-cell} ipython3
199199
:tags: [hide-input]
@@ -489,7 +489,9 @@ same as first applying $B$ on $x$ and then applying $A$ on the vector $Bx$.
489489

490490
Thus the matrix product $AB$ is the
491491
[composition](https://en.wikipedia.org/wiki/Function_composition) of the
492-
matrix transformations $A$ and $B$, which represents first apply transformation $B$ and then
492+
matrix transformations $A$ and $B$
493+
494+
This means first apply transformation $B$ and then
493495
transformation $A$.
494496

495497
When we matrix multiply an $n \times m$ matrix $A$ with an $m \times k$ matrix
@@ -500,7 +502,7 @@ Thus, if $A$ and $B$ are transformations such that $A \colon \mathbb{R}^m \to
500502
transforms $\mathbb{R}^k$ to $\mathbb{R}^n$.
501503

502504
Viewing matrix multiplication as composition of maps helps us
503-
understand why, under matrix multiplication, $AB$ is not generally equal to $BA$.
505+
understand why, under matrix multiplication, $AB$ is generally not equal to $BA$.
504506

505507
(After all, when we compose functions, the order usually matters.)
506508

@@ -601,57 +603,58 @@ different maps $A$.
601603
(plot_series)=
602604

603605
```{code-cell} ipython3
604-
def plot_series(B, v, n):
605-
606-
A = np.array([[1, -1],
606+
def plot_series(A, v, n):
607+
608+
B = np.array([[1, -1],
607609
[1, 0]])
608-
610+
609611
figure, ax = plt.subplots()
610-
612+
611613
ax.set(xlim=(-4, 4), ylim=(-4, 4))
612614
ax.set_xticks([])
613615
ax.set_yticks([])
614616
for spine in ['left', 'bottom']:
615617
ax.spines[spine].set_position('zero')
616618
for spine in ['right', 'top']:
617619
ax.spines[spine].set_color('none')
618-
619-
θ = np.linspace( 0 , 2 * np.pi , 150)
620+
621+
θ = np.linspace(0, 2 * np.pi, 150)
620622
r = 2.5
621-
x = r * np.cos(θ)
623+
x = r * np.cos(θ)
622624
y = r * np.sin(θ)
623-
x1 = x.reshape(1,-1)
625+
x1 = x.reshape(1, -1)
624626
y1 = y.reshape(1, -1)
625-
xy = np.concatenate((x1,y1), axis=0)
626-
627-
ellipse = A @ xy
628-
ax.plot(ellipse[0,:], ellipse[1,:], color = 'black', linestyle = (0, (5,10)), linewidth = 0.5)
629-
630-
colors = plt.cm.rainbow(np.linspace(0,1,20))# Initialize holder for trajectories
631-
627+
xy = np.concatenate((x1, y1), axis=0)
628+
629+
ellipse = B @ xy
630+
ax.plot(ellipse[0, :], ellipse[1, :], color='black',
631+
linestyle=(0, (5, 10)), linewidth=0.5)
632+
633+
# Initialize holder for trajectories
634+
colors = plt.cm.rainbow(np.linspace(0, 1, 20))
635+
632636
for i in range(n):
633-
iteration = matrix_power(B, i) @ v
637+
iteration = matrix_power(A, i) @ v
634638
v1 = iteration[0]
635639
v2 = iteration[1]
636640
ax.scatter(v1, v2, color=colors[i])
637641
if i == 0:
638642
ax.text(v1+0.25, v2, f'$v$')
639-
if i == 1:
643+
elif i == 1:
640644
ax.text(v1+0.25, v2, f'$Av$')
641-
if 1< i < 4:
645+
elif 1 < i < 4:
642646
ax.text(v1+0.25, v2, f'$A^{i}v$')
643-
644647
plt.show()
645648
```
646649

647650
```{code-cell} ipython3
648-
B = np.array([[sqrt(3) + 1, -2],
651+
A = np.array([[sqrt(3) + 1, -2],
649652
[1, sqrt(3) - 1]])
650-
B = (1/(2*sqrt(2))) * B
653+
A = (1/(2*sqrt(2))) * A
651654
v = (-3, -3)
652655
n = 12
653656
654-
plot_series(B, v, n)
657+
plot_series(A, v, n)
655658
```
656659

657660
+++ {"user_expressions": []}
@@ -816,12 +819,12 @@ plane, although some might be repeated.
816819

817820
Some nice facts about the eigenvalues of a square matrix $A$ are as follows:
818821

819-
1. The determinant of $A$ equals the product of the eigenvalues.
820-
1. The trace of $A$ (the sum of the elements on the principal diagonal) equals the sum of the eigenvalues.
821-
1. If $A$ is symmetric, then all of its eigenvalues are real.
822-
1. If $A$ is invertible and $\lambda_1, \ldots, \lambda_n$ are its eigenvalues, then the eigenvalues of $A^{-1}$ are $1/\lambda_1, \ldots, 1/\lambda_n$.
822+
1. the determinant of $A$ equals the product of the eigenvalues
823+
2. the trace of $A$ (the sum of the elements on the principal diagonal) equals the sum of the eigenvalues
824+
3. if $A$ is symmetric, then all of its eigenvalues are real
825+
4. if $A$ is invertible and $\lambda_1, \ldots, \lambda_n$ are its eigenvalues, then the eigenvalues of $A^{-1}$ are $1/\lambda_1, \ldots, 1/\lambda_n$.
823826

824-
A corollary of the first statement is that a matrix is invertible if and only if all its eigenvalues are nonzero.
827+
A corollary of the last statement is that a matrix is invertible if and only if all its eigenvalues are nonzero.
825828

826829
### Computation
827830

@@ -866,7 +869,7 @@ many applications in economics.
866869

867870
### Scalar series
868871

869-
Here's a fundamental result about series that you surely know:
872+
Here's a fundamental result about series:
870873

871874
If $a$ is a number and $|a| < 1$, then
872875

@@ -971,7 +974,7 @@ result which illustrates the result of the Neumann Series Lemma.
971974
```{exercise}
972975
:label: eig1_ex1
973976
974-
Power iteration is a method for finding the largest absolute eigenvalue of a diagonalizable matrix.
977+
Power iteration is a method for finding the greatest absolute eigenvalue of a diagonalizable matrix.
975978
976979
The method starts with a random vector $b_0$ and repeatedly applies the matrix $A$ to it
977980
@@ -981,7 +984,7 @@ $$
981984
982985
A thorough discussion of the method can be found [here](https://pythonnumericalmethods.berkeley.edu/notebooks/chapter15.02-The-Power-Method.html).
983986
984-
In this exercise, first implement the power iteration method and use it to find the largest eigenvalue and its corresponding eigenvector.
987+
In this exercise, first implement the power iteration method and use it to find the greatest absolute eigenvalue and its corresponding eigenvector.
985988
986989
Then visualize the convergence.
987990
```
@@ -1014,7 +1017,7 @@ b = np.random.rand(A.shape[1])
10141017
# Get the leading eigenvector of matrix A
10151018
eigenvector = np.linalg.eig(A)[1][:, 0]
10161019
1017-
norm_ls = []
1020+
errors = []
10181021
res = []
10191022
10201023
# Power iteration loop
@@ -1025,24 +1028,25 @@ for i in range(num_iters):
10251028
b = b / np.linalg.norm(b)
10261029
# Append b to the list of eigenvector approximations
10271030
res.append(b)
1028-
norm = np.linalg.norm(np.array(b)
1031+
err = np.linalg.norm(np.array(b)
10291032
- eigenvector)
1030-
norm_ls.append(norm)
1033+
errors.append(err)
10311034
1032-
dominant_eigenvalue = np.dot(A @ b, b) / np.dot(b, b)
1033-
print(f'The approximated dominant eigenvalue is {dominant_eigenvalue:.2f}')
1035+
greatest_eigenvalue = np.dot(A @ b, b) / np.dot(b, b)
1036+
print(f'The approximated greatest absolute eigenvalue is \
1037+
{greatest_eigenvalue:.2f}')
10341038
print('The real eigenvalue is', np.linalg.eig(A)[0])
10351039
10361040
# Plot the eigenvector approximations for each iteration
1037-
plt.figure(figsize=(10, 6))
1041+
fig, ax = plt.subplots(figsize=(10, 6))
1042+
ax.plot(errors)
10381043
plt.xlabel('iterations')
1039-
plt.ylabel('Norm')
1040-
_ = plt.plot(norm_ls)
1044+
plt.ylabel('error')
10411045
```
10421046

10431047
+++ {"user_expressions": []}
10441048

1045-
Then we can look at the trajectory of the eigenvector approximation
1049+
Then we can look at the trajectory of the eigenvector approximation.
10461050

10471051
```{code-cell} ipython3
10481052
---
@@ -1078,7 +1082,6 @@ ax.legend(points, ['actual eigenvector',
10781082
r'approximated eigenvector ($b_k$)'])
10791083
ax.set_box_aspect(aspect=None, zoom=0.8)
10801084
1081-
# Show the plot
10821085
plt.show()
10831086
```
10841087

@@ -1121,7 +1124,9 @@ plot_series(A, v, n)
11211124

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

1124-
Let's use a vector field to visualize the transformation brought by A.
1127+
Let's use a [vector field](https://en.wikipedia.org/wiki/Vector_field) to visualize the transformation brought by A.
1128+
1129+
(This is a more advanced topic in linear algebra, please step ahead if you are comfortable with the math.)
11251130

11261131
```{code-cell} ipython3
11271132
---
@@ -1156,7 +1161,8 @@ plt.quiver(*origin, - eigenvectors[0],
11561161
colors = ['b', 'g']
11571162
lines = [Line2D([0], [0], color=c, linewidth=3) for c in colors]
11581163
labels = ["2.4 eigenspace", "0.4 eigenspace"]
1159-
plt.legend(lines, labels,loc='center left', bbox_to_anchor=(1, 0.5))
1164+
plt.legend(lines, labels, loc='center left',\
1165+
bbox_to_anchor=(1, 0.5))
11601166
11611167
plt.xlabel("x")
11621168
plt.ylabel("y")
@@ -1284,8 +1290,10 @@ class Arrow3D(FancyArrowPatch):
12841290
12851291
def do_3d_projection(self, renderer=None):
12861292
xs3d, ys3d, zs3d = self._verts3d
1287-
xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, self.axes.M)
1288-
self.set_positions((0.1*xs[0],0.1*ys[0]),(0.1*xs[1],0.1*ys[1]))
1293+
xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d,\
1294+
self.axes.M)
1295+
self.set_positions((0.1*xs[0],0.1*ys[0]), \
1296+
(0.1*xs[1],0.1*ys[1]))
12891297
12901298
return np.min(zs)
12911299

0 commit comments

Comments
 (0)