pyplot (generic function with 1 method)
xxxxxxxxxx
begin
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
end
Eigenvalue 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)
xxxxxxxxxx
function 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)
end
5
xxxxxxxxxx
n1=5
5×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.0167818im
xxxxxxxxxx
A1=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)
end
So 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+α
A
end
jacobi_iteration_matrix (generic function with 1 method)
jacobi_iteration_matrix(A)=I-inv(Diagonal(A))*A
10
xxxxxxxxxx
N=10
10×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.0
A2=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.0
B2=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.0
xxxxxxxxxx
ρ2_gershgorin=maximum([sum( abs.(B2[i,:])) for i=1:size(B2,1)])
xxxxxxxxxx
pyplot(width=5, height=5) do
gershgorin_circles(B2)
xlabel("Re")
ylabel("Im")
PyPlot.grid(color=:gray)
end
So 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)
xxxxxxxxxx
function 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,elabel
end
rndmatrix (generic function with 1 method)
# sparse random matrix with entries with limited numbers decimal values
rndmatrix(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.0
xxxxxxxxxx
A3=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)
xxxxxxxxxx
GraphPlot.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!
1
xxxxxxxxxx
α=1
5
xxxxxxxxxx
N4=5
5×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.0
xxxxxxxxxx
A4=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.0
xxxxxxxxxx
B4=jacobi_iteration_matrix(A4)
0.9486832980505135
xxxxxxxxxx
ρ4=maximum(abs.(eigvals(Matrix(B4))))
1.0
xxxxxxxxxx
ρ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
xxxxxxxxxx
graph4,nlabel4,elabel4=create_graph(B4)
xxxxxxxxxx
GraphPlot.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
xxxxxxxxxx
pyplot(width=5, height=5) do
gershgorin_circles(B4)
xlabel("Re")
ylabel("Im")
PyPlot.grid(color=:gray)
end
Unfortunately, we don't get a quantitative estimate here.
Advantage: we don't need to assume symmetry of
or spectral equivalence estimates