Description
In this problem we will consider a very special symmetric matrix. Recall that the second-order finite difference scheme for a function ๐(๐ฅ) is given by
๐๐โณ = ๐๐+1 โ 2โ๐2๐ + ๐๐โ1
where ๐๐ = ๐(๐ฅ0 + ๐โ) and โ = ๐ฅ๐๐โ๐ฅ0 .
Define the vector f such that f๐ = ๐๐. Then the corresponding derivative vector using finite differences can be written as fโณ = ๐ทf. Some care must be taken about the boundary conditions; for simplicity we will assume that ๐0 = ๐๐ = 0. Under these assumptions the matrix ๐ท is a tridiagonal matrix:
๐1โฒ โ2 1 ๐1
โก ๐2โฒ โค โก 1 โ2 1 โค โก ๐2 โค
โข ๐3โฒ โฅ = โขโข 1 โ2โฑ โฑ1 โฑ โฅโฅ โขโข ๐โฎ3 โฅโฅ
โข โฎ โฅ
โข๐๐โ2โฒ โฅ โข 1 โ2 1 โฅ โข๐๐โ2โฅ
โฃ๐๐โ1โฒ โฆ โโโโโโโโโโโโโโฃ 1 โ2โฆ โฃ๐๐โ1โฆ
๐ท๐
You can construct the matrix ๐ท in Julia using the diagm function. For simplicity keep everything dense in this problem, although there clearly a lot of structure that could be exploited.
1. Consider the matrix ๐ท. Using the ansatz (i.e. hypothesis) v๐ = sin(๐๐๐/๐), where 1 โค ๐ โค ๐ โ 1, show that v is an eigenvector of ๐ท๐. What is the corresponding eigenvalue? Remember that the eigenvalues should be real!
2. In class we discussed several ways to find eigenvalues of matrices. The simplest algorithm for finding eigenvalues is the power method. Supppse that a symmetric matrix ๐ด has the eigendecomposition ๐ด =
๐ฮ๐โ1. Recall that for a symmetric matrix the eigenvectors associated with distinct eigenvalues are orthogonal. Starting with a random intitial vector x which can be written as a sum over the eigenvectors,
x = โ ๐๐v๐
๐
show that
๐ด๐x = โ ๐๐๐๐๐v๐
๐
where we order the eigenvalues by their magnitude, |๐1| > |๐2| > โฏ > |๐๐| and hence
๐ด๐x = ๐1๐๐1 (v1 + ๐ช (๐๐๐1๐2v2)) .
This shows why the power method converges to the leading eigenvector.
3. The power method gives an approximation for the leading eigenvector v1ฬ .
Since it is only an approximation it is not necessarily true that ๐ด ฬv1 =
๐1v1ฬ exactly.
Instead we will say that the best approximation to ๐1 is given by the ๐
that satifies
2 ๐1 = min ||๐ด ฬv1 โ ๐ผ ฬv1||2 = โ (โ ๐ด๐๐(v1ฬ )๐ โ ๐ผ( ฬv1)๐) .
๐ผ
๐ ๐
By differentiating this expression with respect to ๐ผ, show that
ฬ โ
(๐ด ฬv ) ฬ
๐1 ฬ โ
ฬ ฬ ฬ .
This is called the Rayleigh quotient.
4. Implement the power method power_method(A, N, x) for a symmetric matrix ๐ด which iterates for a fixed number of iterations ๐ on the intial vector x and returns v1ฬ and ๐1 approximated by the Rayleigh quotient above.
5. Run this on the matrix ๐ท10 which is of size (9 ร 9). Use the true largest magnitude vector from part 1. Plot the relative error between your result and the true value as a function of ๐ to get a smooth plot; use the same initial vector each time.
Remember to normalize the vector at each iteration to avoid overflow!
This initial random vector should be complex. (Extra credit: show that the relationship is what you would expect analytically!)
6. A more advanced method that we discussed to find all the eigenvalues was the QR algorithm. We define ๐ด(0) = ๐ด and then
๐(๐)๐
(๐) = ๐ด(๐)
๐ด(๐+1) = ๐
(๐)๐(๐)
This will normally converge to an upper-triangular matrix. How does this work? We call two matrices ๐ด and ๐ต similar if ๐ต = ๐๐ด๐โค where ๐ is orthogonal. Show that if ๐ด has eigenvalue pairs (๐๐, v๐) then ๐ต has eigenpairs (๐๐, ๐v๐).
7. Show that in the QR algorithm ๐ด(๐+1) is similar to ๐ด(๐) and hence ๐ด. Therefore if the algorithm converges to an upper-triangular matrix we can read off the eigenvalues from the diagonal and the eigenvectors will be given by the columns of ๐(1)๐(2)๐(3) โฏ ๐(๐).
8. Implement the QR algorithm in a function qr_algorithm(A, N) for a matrix ๐ด with ๐ iterations. It should return the resulting matrix ๐ด(๐) and the eigenvector matrix. Run the algorithm on a random symmetric matrix of size 10 ร 10 for 100 iterations. How close to upper-triangular is the resulting matrix?
9. Run the QR algorithm on the matrix ๐ท10 of size (9 ร 9) for a suitable number of iterations to get convergence. Compare the results to the theoretical one. Can you find all the eigenvalues and eigenvectors?
10. Using the fact that the eigendecomposition of a symmetric matrix gives orthogonal matrices (which are easy to invert) propose a method to solve the linear system
๐ทx = b
11. Solve the system for b = 0.01^2*sin.(2ฯ*(0.01:0.01:0.99)) and ๐ท as a 99 ร 99 matrix. Plot the resulting vector x. Plot on the same axis sin.(2ฯ*(0.01:0.01:0.99))/4ฯ^2. Is it similar to x? We have just solved the boundary value problem ๐โณ = sin(2๐๐ฅ) with ๐(0) = ๐(2๐) = 0. In the next problem set we will see how to do this even quicker using Fourier analysis.
Exercise 2: Low-rank approximation
In this problem we will use the SVD to produce low-rank approximations for matrices. We will then use this to compress images and write fast multiplication algorithms.
In the last problem set we saw that we could exploit structural zeros to speed up algorithms. A matrix is of rank ๐ if we can write it in the form
๐
๐ด = โ ๐๐u๐vโค๐
๐=1
where the u๐ and v๐ are vectors of length ๐, So u๐vโค๐ is a matrix of size (๐ ร ๐), of rank 1.
The SVD of a square ๐ ร ๐ matrix ๐ด exactly writes ๐ด in this form:
|
๐ด = ๐ฮฃ๐ โค = [u1 |
u2 โฏ | ๐1
โก u๐] โข ๐2 โฑ โโ
โค โกโโ
โฅ โขโข vโค1
โค โโ
โโโคโฅโฅ = โ๐ ๐๐u๐vโค๐
| | | โฃ ๐๐โฆ โฃ โฆ ๐=1
Truncating the summation after the largest ๐ singular values results in a rank๐ approximation of the matrix ๐ด. In fact the EckhartโMirskyโYoung theorem shows this is the best rank ๐ approximation to ๐ด.
Define the rank ๐ approximation of ๐ด
๐
๐ด๐ โถ= โ ๐๐u๐vโค๐
๐=1
where u๐ and v๐ are the singular vectors of ๐ด and ๐๐ are the singular values of the matrix.
2. Make a square matrix M of size (20 ร 20) that is all zero, except for an axis-aligned cross centred in the centre. Each arm should be of total width 2 and extend a distance 5 out from the centre in each direction parallel to the axes. The cross should consist of 1s.
3. Remembering that the rank is the column rank, i.e. the number of linearlyindependent columns, how much should the rank be? Use the SVD of M to confirm this. What does the rank-1 approximation of M look like?
4. Now add small random gaussian noise using the randn function, of intensity 0.1. Plot the new matrix (using heatmap). How should this affect the (column) rank of the matrix?
5. Plot the singular values ๐๐ as a function of ๐. What do they tell us? What is a suitable rank-๐ approximation to take? What does it look like?
img = testimage(“mandrill”)
imgmat = Array(channelview(Float64.(Gray.(img))))
heatmap(imgmat, c=ColorGradient(:grays), showaxis=false, clims=(0,1), yflip=true)
Here imgmat is a standard Julia matrix that contains greyscale pixel values.
7. Plot the rank-50 approximation to imgmat (using heatmap). How does it compare to the original?
8. Plot the singular values as a function of ๐. You should see an โelbowโ shape. Approximately where does it occur?
9. Create an interactive visualization that shows the low-rank approximation for different values of ๐. What do you observe? After which ๐ are you happy with the quality of the image. Is it related to where the elbow is?
Exercise 3: Dynamic mode decomposition
In this problem we will use the SVD to predict the future! Suppose that we have some data that satisfies an ODE,
xฬ = f(x)
We can solve the ODE and take time snapshots of the result which we can stack into a matrix as follows:
| | |
๐๐,๐ โถ= [x(๐ก๐) x(๐ก๐+1) โฏ x(๐ก๐)]
| | |
We will assume that the dynamics is linear. This means that we expect that two consecutive snapshots should satisfy
x๐+1 = ๐ดx๐
for some matrix ๐ด.
If we have ๐ snapshots then we can write this as a matrix equation,
๐2,๐ = ๐ด๐1,(๐โ1)
1. Suppose that we have an eigen-decomposition for ๐ด, i.e. ๐ด = ๐ฮ๐โ1, and that we can write the initial time snapshot as a sum over the eigenbasis of ๐ด,
x0 = โ ๐๐w๐
๐
where w๐ is the ๐th eigenvector of ๐ด. Show that future time snapshots can be written as
x๐ = โ ๐๐๐๐๐ w๐
๐
where ๐๐ is the ๐th eigenvalue of ๐ด.
2. We are now going to try and find the eigendecomposition of ๐ด without ever constructing it! Start by calculating the SVD of ๐1,(๐โ1) = ๐ฮฃ๐ โค. Find an expression for ๐โค๐ด๐ in terms of ๐2,๐, ฮฃ, ๐ , ๐. We can then calculate the eigenspectrum of A by taking the eigenvalue decomposition of ๐โค๐ด๐ since they are similar and using use the result in [1.5].
3. Write a function that calculates the eigenspectrum of ๐ด given ๐1,๐. Instead of using the full SVD, use a truncated SVD keeping only the first ๐ singular values and singular vectors; i.e. use the matrices Vr = V[:,
1:r], Ur = U[:, 1:r] and ฮฃr = ฮฃ[1:r, 1:r] in the expression above for ๐ , ๐, ฮฃ. Your function should be of the form aspectrum(X, r). The reason for truncating is in case A is not full rank, in which case some terms in ฮฃ might be nearly 0 and dividing by them would be a bad idea. 4. Test your function on a random 10 ร 10 matrix ๐ด generating some data for ๐ of size (10ร11) from it starting from a random ๐ฅ0. Compare the results of eigen(A) with aspectrum(X, 10). Remember that eigenvectors are the same upto a multiplicative constant.
5. We are now going to apply this to some dynamical data. Use the ODE integrator code below to generate some data for ๐ coupled oscillators with ๐ฅ1(0) = 0.5 and all the others ๐ฅ๐(0) = 0 for N = 10 from ๐ก = 0 to ๐ก = 10. The coupled system can be written as
๐ฅฬ1 โ2 1 ๐ฅ1
โก๐ฅฬ2 โค โก 1 โ2 1 โค โก๐ฅ2 โค
โข๐ฅฬ3 โฅ = โข 1 โ2 1 โฅ โข๐ฅ3 โฅ
โข โฎ โฅ โข โฑ โฑ โฑ โฅ โข โฎ โฅ
โฃ๐ฅฬ๐โฆ โฃ 1 โ2โฆ โฃ๐ฅ๐โฆ
or as a system of first order equations,
๐ฅฬ1 0 1 ๐ฅ1
โก ๐ฆฬ1 โค โกโ2 0 1 โค โก ๐ฆ1 โค
โข๐ฅฬ2 โฅ โข 0 0 0 1 โฅ โข๐ฅ2 โฅ โข ๐ฆฬ2 โฅ โข 1 0 โ2 0 1 โฅ โข ๐ฆ2 โฅ
โข๐ฅฬ3 โฅ = โข 0 0 0 0 1 โฅ โข๐ฅ3 โฅ
โข ๐ฆฬ3 โฅ โข 1 0 โ2 0 1 โฅ โข ๐ฆ3 โฅ
โข โฎ โฅ โข โฑ โฑ โฑ โฑ โฑ โฅ โข โฎ โฅ
โข๐ฅฬ๐โฅ โข 0 0 0 0 1โฅ โข๐ฅ๐โฅ
โฃ๐ฆฬ๐ โฆ โฃ 1 0 โ2 0โฆ โฃ๐ฆ๐ โฆ
The output is a data matrix with rows ๐ฅ1, ๐ฅฬ1, ๐ฅ2, ๐ฅฬ2, โฏ
Generate a plot of ๐ฅ1(๐ก) to check that everything went according to plan.
6. Split the data into two parts ๐1 and ๐2, the first half from ๐ก = 0 to ๐ก = 5 and the second half ๐ก = 5 to ๐ก = 10. Calculate the spefctrum of ๐ด with ๐ = 10 using ๐1.
7. Use the first column of ๐2 as the initial condition. Use the spectrum you found to predict the future dynamics. [Hint: use the initial condition to find the ๐๐s, which is a matrix solve. Then use the equations in part 1.1 to calculate the prediction.]
8. Plot the prediction for the 10 springs on the same axis as the true solution. What happens?
9. Repeat [3.6โ3.7] for ๐ = 15 and ๐ = 20. What do you observe?
ODE Code:
struct RKMethod{T} c::Vector{T} b::Vector{T} a::Matrix{T} s::Int
# Make sure that the matrices and vectors have the correct size function RKMethod(c::Vector{T}, b::Vector{T}, a::Matrix{T}, s::Int) where T lc = length(c); lb = length(b); sa1, sa2 = size(a) if lc == sa1 == sa2 == s-1 && lb == s new{T}(c, b, a, s)
else
error(“Sizes should be (s = $s) : length(c) = s-1 ($lc) length(b) = s end
end end function (method::RKMethod)(f, x, t, h) # Extract the parameters
a, b, c, s = method.a, method.b, method.c, method.s
# Vector to hold the k terms k = [f(t, x)]
for i in 1:s-1
tn = t + c[i]*h xn = x + h*sum(a[i, j] * k[j] for j in 1:i)
push!(k, f(tn, xn))
end
return x + h * sum(b.*k)
end
function integrate(method, f, x0, t0, tf, h)
# Calculate the number of time steps N = ceil(Int, (tf – t0) / h) hf = tf – (N – 2)*h
#initiate tracking vectors xs = [copy(x0)] ts = [t0]
#step
for i in 1:N-1
push!(xs, method(f, xs[i], ts[i], h)) push!(ts, ts[i] + h)
end
# Special last step push!(xs, method(f, xs[N-1], ts[N-1], hf)) push!(ts, ts[N-1] + hf)
return ts, xs
end
c = [1/2, 1/2, 1] b = (1/6) .* [1, 2, 2, 1] a = [1/2 0 0; 0 1/2 0; 0 0 1] rk4 = RKMethod(c, b, a, 4)
function build_springmat(N) springmat = zeros(2N,2N) for i = 1:2N
(i < 2N) && (springmat[i, i+1] = 1.0)
if iseven(i) springmat[i, i-1] = -2.0
(i > 3) && (springmat[i, i-3] = 1.0) end end springmat
end
N = 10
const spmat = build_springmat(N) spf(t, x) = spmat*x x0 = zeros(2N); x0[1] = 0.5
ts, xs = integrate(rk4, spf, x0, 0.0, 20.0, 0.005); X = hcat(xs…) plot(ts, X[1:2:2N, :]’, leg=:outertopright, box=:on)
Exercise 4: Fourier integrals
In lectures we saw that we could write periodic functions in the form
๐ ๐(๐ฅ) = โ ๐๐ฬ ๐๐๐๐ฅ
๐=โ๐
ฬ2๐ ๐(๐ฅ) ๐โ๐๐๐ฅ. where ๐๐
1. Consider the saw-tooth function,
โง{๐ฅ 0 โค ๐ฅ < ๐
๐(๐ฅ) = โจ{โฉ2๐(๐ โ ๐ฅmod(๐ฅ, 2๐)) ๐ โค ๐ฅ < 2๐else
Calculate the Fourier series coefficients analytically.
2. Write a function fourier_coefficients(f::Vector, n::Int) that takes in a vector of samples of ๐ uniformly distributed over [0, 2๐] and returns an approximation to ๐๐ฬ by calculating the integral using the trapezoidal rule.
3. Now calculate ๐๐ฬ using your trapezoidal code using 100 points and ๐ = โ3, โ2, โฆ , 3. How do they compare to the theoretical results?
4. Fix ๐ to be 1. Plot the relative error between the theoretical result and the result from using fourier_coefficients for calculating ๐1ฬ using a number of points between 10 and 1000. What does the convergence look like? Does it agree with what we discussed in class?
5. Now consider the smooth periodic function exp(cos(๐ฅ)). Repeat [4.3โ
4.4] for this function. The analytical result is given by ๐๐ฬ = ๐ผ|๐|(1).
You can calculate this using the besseli(abs(n), 1) in SpecialFunctions.jl.
6. Plot the magnitude of ๐๐ฬ as a function of ๐ for the two functions. How do the coefficients decay? Is this what you expected?
Reviews
There are no reviews yet.