Notebook 13 – Math 2121, Fall 2020
In this notebook we will explore how to draw complex numbers and then discuss a visual proof of the fundamental theorem of algebra.
The way we can visualize complex numbers is very similar to how we draw vectors in
xxxxxxxxxx
using Plots
xxxxxxxxxx
using PlutoUI
xxxxxxxxxx
using LinearAlgebra
In lecture, we defined the complex number
A very useful way of visualizing the number
which is the first column of the matrix above.
This first column determines the second column, so there is no loss of information.
plot_vector (generic function with 2 methods)
plot_sum (generic function with 2 methods)
complex_product (generic function with 1 method)
plot_multiple (generic function with 2 methods)
We draw such vectors as arrows in the
-2
2
xxxxxxxxxx
u = [-2;2]
This represents the complex number
4
2
xxxxxxxxxx
v = [4; 2]
This represents the complex number
The sum of these complex numbers is
In terms of arrows, the sum
There is also a simple of way of visualizing the product of two complex numbers.
The length or norm of
This is also how we define the length of the vector
The angle of the vector
The angle of
The complex number
If these are
and , respectively, then .
Here is a method to compute the angle of
angle (generic function with 1 method)
xxxxxxxxxx
function angle(z)
# returns angle between 0.0 and 2 * pi
u1, u2 = z[1], z[2]
if u1 == 0
return u2 > 0 ? pi/2 : 3 * pi/2
end
if u2 == 0
return u1 > 0 ? 0 : pi
end
a = atan(abs(u2) / abs(u1))
if u1 > 0 && u2 > 0
return a
elseif u1 > 0 && u1 > 0
return 2 * pi - a
elseif u1 < 0 && u2 > 0
return pi - a
else
return pi + a
end
end
Here is how to interpret the product of two complex numbers
The vector in
representing is the vector whose angle is the sum of the angles of and , and whose length is the product of the lengths of and .
Recall that u = -2 + 2i and v = 4 + 2i.
2.82843
2.35619
xxxxxxxxxx
norm(u), angle(u)
4.47214
0.463648
xxxxxxxxxx
norm(v), angle(v)
-12
4
xxxxxxxxxx
uv = complex_product(u, v)
2×2 Array{Float64,2}:
12.6491 2.81984
12.6491 2.81984
xxxxxxxxxx
[norm(uv) angle(uv); norm(u) * norm(v) angle(u) + angle(v)]
Some more examples of products of complex numbers:
1×2 Array{Float64,2}:
1.414 1.414
1×2 Array{Float64,2}:
-0.3535 0.3535
xxxxxxxxxx
z = [-0.707 0.707] / 2
These vectors represent y = 1.414 + 1.414i and z = -0.3535 + 0.3535i
These numbers have length
The angle of
1.9997
0.499924
0.999698
0.999698
xxxxxxxxxx
norm(y), norm(z), norm(y) * norm(z), norm(complex_product(y, z))
0.785398
2.35619
3.14159
π
xxxxxxxxxx
angle(y), angle(z), angle(y) + angle(z), angle(complex_product(y, z))
Multiplying by
These pictures give us some visual intution about adding, multiplying, and taking powers
Using these abilities together lets us imagine the output of a polynomial function
where
We can encode such a function in Julia as a
random_real_polynomial (generic function with 1 method)
xxxxxxxxxx
function random_real_polynomial(degree)
return rand(-10:10, 1, degree + 1)
end
random_complex_polynomial (generic function with 1 method)
xxxxxxxxxx
function random_complex_polynomial(degree)
return rand(-10:10, 2, degree + 1)
end
monomial (generic function with 1 method)
xxxxxxxxxx
function monomial(degree)
ans = zeros(1, degree + 1)
ans[1, end] = 1
return ans
end
Here is a very simple method to print a 2-row matrix as a polynomial in the usual way.
print_polynomial (generic function with 1 method)
1×6 Array{Int64,2}:
6 -2 -8 4 6 -9
xxxxxxxxxx
f = random_real_polynomial(5)
(6) + (-2) * x + (-8) * x^2 + (4) * x^3 + (6) * x^4 + (-9) * x^5
xxxxxxxxxx
Text(print_polynomial(f))
2×5 Array{Int64,2}:
-5 -3 10 0 -2
-7 0 -4 -10 1
xxxxxxxxxx
g = random_complex_polynomial(4)
(-5 + -7i) + (-3 + 0i) * x + (10 + -4i) * x^2 + (0 + -10i) * x^3 + (-2 + 1i) * x^4
xxxxxxxxxx
Text(print_polynomial(g))
1×8 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
xxxxxxxxxx
h = monomial(7)
(1.0) * x^7
xxxxxxxxxx
Text(print_polynomial(h))
The following method evaluates our polynomial
evaluate_polynomial (generic function with 1 method)
xxxxxxxxxx
function evaluate_polynomial(f, z)
ans = zeros(2, 2)
# convert z back to 2-by-2 matrix
z = [z[1] -z[2]; z[2] z[1]]
m, n = size(f)
degree = n - 1
for i=0:degree
a = f[1, i + 1]
b = m == 1 ? 0 : f[2, i + 1]
# convert coefficient of f back to 2-by-2 matrix
coefficient = [a -b; b a]
# multiply together and add
ans += coefficient * z^i
end
# return just first columne of 2-by-2 matrix
return ans[:, 1]
end
-3.0
0.0
-3
xxxxxxxxxx
# evaluates f(x) at x = 1 = 1 + 0i
evaluate_polynomial(f, [1, 0]), sum(f)
20.0
-15.0
20
-15
xxxxxxxxxx
# evalutes f(x) at x = i = 0 + i
evaluate_polynomial(f, [0, 1]), [f[1] - f[3] + f[5], f[2] - f[4] + f[6]]
To visualize a set of complex numbers
Below is a picture of the set
circle_path (generic function with 2 methods)
xxxxxxxxxx
function circle_path(r, N=1000)
path = zeros(2, N)
for n = 0:N - 1
path[1, n + 1] = r * cos(2 * pi / N * n)
path[2, n + 1] = r * sin(2 * pi / N * n)
end
return path
end
plot_path (generic function with 2 methods)
xxxxxxxxxx
function plot_path(path, title="")
plot(path[1,:], path[2,:], aspect_ratio=:equal, title=title, legend=false)
scatter!([0], [0])
end
Below are the analogous pictures
compute_path (generic function with 1 method)
xxxxxxxxxx
function compute_path(f, domain)
# evaluates polynomial f at all columns in domain
_, N = size(domain)
path = zeros(2, N)
for n = 1:N
path[:, n] = evaluate_polynomial(f, domain[:, n])
end
return path
end
The picture of
This makes sense because
(Can you explain this using our visual interpretation of complex multiplication?)
Fundamental theorem of algebra
The fundamental theorem of algebra result says that if
with
for some complex numbers
We can sketch a visual proof of this fact, extending the discussion above.
Enter cell code...
xxxxxxxxxx
Some preliminaries:
Fact. If
Proof: This is obvious since
Fact. If
Proof: If
But then
Conclusion. To prove the fundamental theorem of algebra, it suffices to show that if
for some complex number
A proof of this last property is what we will outline below.
Enter cell code...
xxxxxxxxxx
Our proof involves the notion of the winding number of a curve in
Consider a circle
Passing the points on the circle in order as inputs to
winding_number (generic function with 1 method)
xxxxxxxxxx
function winding_number(p, r)
# computes winding number of curve tracing { p(z) : |z| = r }
# here is the simple idea to compute this:
#
# * take two successive points z_0, z_1 on the circle
# * compute the small change in angles between these points
# * add up these angle changes over the whole circle, then divide by 2 pi
#
# "adding" in this context is secretly some kind of integration
domain = circle_path(r)
path = compute_path(p, domain)
_, N = size(path)
ans = zeros(1, N)
for i=1:N - 1
z_0 = path[:, i]
z_1 = path[:, i + 1]
angle_0 = angle(z_0)
angle_1 = angle(z_1)
dtheta = angle_1 - angle_0
# we have to adjust dtheta in the case when our angle function returns
# something close to 0 for z_0 and close to 2 pi for z_1 (or vice versa)
if dtheta > pi
dtheta -= 2 * pi
elseif dtheta < -pi
dtheta += 2 * pi
end
ans[i + 1] = ans[i] + dtheta / 2 / pi
end
return ans
end
plot_winding (generic function with 1 method)
xxxxxxxxxx
function plot_winding(f, r)
deg = size(f)[2] - 1
domain = circle_path(r)
path = compute_path(f, domain)
winding = winding_number(f, r)
p1 = plot_path(domain, "{ z: |z| = $(r) }")
p2 = plot_path(path, "{ p(z): |z| = $(r) }")
p3 = plot(transpose(winding), legend=false, ylimit=(-1, deg + 1), title="winding")
plot(p1, p2, p3, layout=(1,3))
end
For example,
However, for
Whereas for
xxxxxxxxxx
plot_winding([-1 1 1; 0 0 0], 0.5)
Keys facts:
If
and is very small, the winding number will be zero.If
then the winding number will always be , for any .If
has degree and is very large, then has the same winding number as .
2×8 Array{Int64,2}:
-9 -1 -1 10 -5 7 -3 -5
-9 -9 9 -10 8 0 -5 -8
xxxxxxxxxx
p = random_complex_polynomial(7)
"(-9 + -9i) + (-1 + -9i) * x + (-1 + 9i) * x^2 + (10 + -10i) * x^3 + (-5 + 8i) * x^4 + (7 + 0i) * x^5 + (-3 + -5i) * x^6 + (-5 + -8i) * x^7"
xxxxxxxxxx
print_polynomial(p)
parameter
=
1.87265
7
xxxxxxxxxx
plot_winding(p, r)
Why does this prove the fundamental theorem of algebra?
Winding number can only change as we vary
if passes through the origin.This must happen if
has degree and .(Since the winding number is zero if
is small and the winding number is if is large.)But this means for some real
there is an with and .