pyplot (generic function with 1 method)xxxxxxxxxxbegin using Pkg Pkg.activate(mktempdir()) Pkg.add("PyPlot") Pkg.add("PlutoUI") Pkg.add("GraphPlot"); Pkg.add("LightGraphs"); Pkg.add("Colors") using PlutoUI using PyPlot using LinearAlgebra using SparseArrays using GraphPlot, LightGraphs,Colors function pyplot(f;width=3,height=3) clf() f() fig=gcf() fig.set_size_inches(width,height) fig end endEigenvalue analysis for more general matrices
For 1D heat conduction we had a very special regular structure of the matrix which allowed exact eigenvalue calculations.
We need a generalization to varying coefficients, nonsymmetric problems, unstructured grids
The Gershgorin Circle Theorem
Theorem (Varga, Th. 1.11) Let
If
Proof: Assume
From
Corollary Any eigenvalue
Corollary The Gershgorin circle theorem allows to estimate the spectral radius
Proof:
Furthermore,
This appears to be very easy to use, so let us try:
gershgorin_circles (generic function with 1 method)xxxxxxxxxxfunction gershgorin_circles(A) t=0:0.01*π:2π # α is the trasnparency value. circle(x,y,r;α=0.3)=fill(x.+r.*cos.(t),y.+r.*sin.(t),alpha=α) n=size(A,1) for i=1:n Λ=0 for j=1:n if j!=i Λ+=abs(A[i,j]) end end circle(real(A[i,i]),imag(A[i,i]),Λ,α=0.5/n) end σ=eigvals(Matrix(A)) scatter(real(σ),imag(σ),sizes=10*ones(n),color=:red)end5xxxxxxxxxxn1=55×5 Array{Complex{Float64},2}:
0.178502+0.0192365im 0.744411+0.093342im … 0.392995+0.0961931im
0.285649+0.0786766im 0.196577+0.0252502im 0.564553+0.0803397im
0.169284+0.0438933im 0.755742+0.0518099im 0.55119+0.0852875im
0.669057+0.0866883im 0.867834+0.0229806im 0.607358+0.0276727im
0.480013+0.0704921im 0.581088+0.0177494im 0.247122+0.0167818imxxxxxxxxxxA1=rand(n1,n1)+0.1*rand(n1,n1)*1im-0.518821-0.0347195im
-0.417636+0.115591im
-0.207874-0.151289im
0.321384+0.0359316im
2.48231+0.220633im
eigvals(A1)x
pyplot(width=5, height=5) do gershgorin_circles(A1) xlabel("Re") ylabel("Im") PyPlot.grid(color=:gray)endSo this is kind of cool! Let us try this out with our heat example and the Jacobi iteration matrix:
heatmatrix1d (generic function with 1 method)function heatmatrix1d(N;α=100) A=zeros(N,N) h=1/(N-1) A[1,1]=1/h+α for i=2:N-1 A[i,i]=2/h end for i=1:N-1 A[i,i+1]=-1/h end for i=2:N A[i,i-1]=-1/h end A[N,N]=1/h+α Aendjacobi_iteration_matrix (generic function with 1 method)jacobi_iteration_matrix(A)=I-inv(Diagonal(A))*A10xxxxxxxxxxN=1010×10 Tridiagonal{Float64,Array{Float64,1}}:
109.0 -9.0 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
-9.0 18.0 -9.0 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ -9.0 18.0 -9.0 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ -9.0 18.0 -9.0 ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ -9.0 18.0 -9.0 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ -9.0 18.0 -9.0 ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ -9.0 18.0 -9.0 ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ -9.0 18.0 -9.0 ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ -9.0 18.0 -9.0
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ -9.0 109.0A2=Tridiagonal(heatmatrix1d(N))10×10 Tridiagonal{Float64,Array{Float64,1}}:
0.0 0.0825688 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
0.5 0.0 0.5 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ 0.5 0.0 0.5 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ 0.5 0.0 0.5 ⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ 0.5 0.0 0.5 ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ 0.5 0.0 0.5 ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ 0.5 0.0 0.5 ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 0.5 0.0 0.5 ⋅
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 0.5 0.0 0.5
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 0.0825688 0.0B2=jacobi_iteration_matrix(A2)0.9421026930965894ρ2=maximum(abs.(eigvals(Matrix(B2))))We have
We see two circles around 0: one with radius 1 and one with radius
We can also caculate the value from the estimate: Gershgorin circles of
1.0xxxxxxxxxxρ2_gershgorin=maximum([sum( abs.(B2[i,:])) for i=1:size(B2,1)])xxxxxxxxxxpyplot(width=5, height=5) do gershgorin_circles(B2) xlabel("Re") ylabel("Im") PyPlot.grid(color=:gray)endSo the estimate from the Gershgorin Circle theorem is very pessimistic... Can we improve this ?
Matrices and Graphs
Permutation matrices are matrices which have exactly one non-zero entry in each row and each column which has value
.There is a one-to-one correspondence permutations
of the the numbers and permutation matrices such that
Permutation matrices are orthogonal, and we have
permutes the rows of permutes the columns of
Define a directed graph from the nonzero entries of a matrix
Nodes:
Directed edges:
Matrix entries
weights of directed edges1:1 equivalence between matrices and weighted directed graphs
Create a bidirectional graph (digraph) from a matrix in Julia. Create edge labels from off-diagonal entries and node labels combined from diagonal entries and node indices.
create_graph (generic function with 1 method)xxxxxxxxxxfunction create_graph(matrix) size(matrix,1)==size(matrix,2) n=size(matrix,1) g=LightGraphs.SimpleDiGraph(n) elabel=[] nlabel=Any[] for i in 1:n push!(nlabel,"""$(i) \n $(matrix[i,i])""") for j in 1:n if i!=j && matrix[i,j]>0 add_edge!(g,i,j) push!(elabel,matrix[i,j]) end end end g,nlabel,elabelendrndmatrix (generic function with 1 method)# sparse random matrix with entries with limited numbers decimal valuesrndmatrix(n,p)=rand(0:0.01:1,n,n).*Matrix(sprand(Bool,n,n,p))5×5 Array{Float64,2}:
0.0 0.0 0.77 0.0 0.0
0.0 0.0 0.0 0.0 0.0
0.84 0.9 0.0 0.33 0.0
0.0 0.0 0.0 0.0 0.32
0.0 0.41 0.0 0.38 0.0xxxxxxxxxxA3=rndmatrix(5,0.3){5, 7} directed simple Int64 graph"1 \n 0.0"
"2 \n 0.0"
"3 \n 0.0"
"4 \n 0.0"
"5 \n 0.0"
0.77
0.84
0.9
0.33
0.32
0.41
0.38
graph3,nlabel3,elabel3=create_graph(A3)xxxxxxxxxxGraphPlot.gplot(graph3, nodelabel=nlabel3, edgelabel=elabel3, nodefillc=RGB(1.0,0.6,0.5), EDGELABELSIZE=6.0, NODESIZE=0.1, EDGELINEWIDTH=1)Matrix graph of
is strongly connected: falseMatrix graph of
is weakly connected: true
Definition A square matrix
Theorem (Varga, Th. 1.17):
Equivalently, for each
The Taussky theorem
Theorem (Varga, Th. 1.18) Let
Then, all
Proof Assume
Due to irreducibility there is at least one
Due to irreducibility, this is true for all
Apply this to the Jacobi iteration matrix for the heat conduction problem: We know that
Assume
Contradiction!
1xxxxxxxxxxα=15xxxxxxxxxxN4=55×5 Tridiagonal{Float64,Array{Float64,1}}:
5.0 -4.0 ⋅ ⋅ ⋅
-4.0 8.0 -4.0 ⋅ ⋅
⋅ -4.0 8.0 -4.0 ⋅
⋅ ⋅ -4.0 8.0 -4.0
⋅ ⋅ ⋅ -4.0 5.0xxxxxxxxxxA4=Tridiagonal(heatmatrix1d(N4,α=α))5×5 Tridiagonal{Float64,Array{Float64,1}}:
0.0 0.8 ⋅ ⋅ ⋅
0.5 0.0 0.5 ⋅ ⋅
⋅ 0.5 0.0 0.5 ⋅
⋅ ⋅ 0.5 0.0 0.5
⋅ ⋅ ⋅ 0.8 0.0xxxxxxxxxxB4=jacobi_iteration_matrix(A4)0.9486832980505135xxxxxxxxxxρ4=maximum(abs.(eigvals(Matrix(B4))))1.0xxxxxxxxxxρ4_gershgorin=maximum([sum( abs.(B4[i,:])) for i=1:size(B4,1)]){5, 8} directed simple Int64 graph"1 \n 0.0"
"2 \n 0.0"
"3 \n 0.0"
"4 \n 0.0"
"5 \n 0.0"
0.8
0.5
0.5
0.5
0.5
0.5
0.5
0.8
xxxxxxxxxxgraph4,nlabel4,elabel4=create_graph(B4)xxxxxxxxxxGraphPlot.gplot(graph4, # rand(n),rand(n), nodelabel=nlabel4, edgelabel=elabel4, nodefillc=RGB(1.0,0.6,0.5), EDGELABELSIZE=6.0, NODESIZE=0.1, EDGELINEWIDTH=1)Matrix graph is strongly connected: true
Matrix graph is weakly connected: true
xxxxxxxxxxpyplot(width=5, height=5) do gershgorin_circles(B4) xlabel("Re") ylabel("Im") PyPlot.grid(color=:gray)endUnfortunately, we don't get a quantitative estimate here.
Advantage: we don't need to assume symmetry of
or spectral equivalence estimates