Gershgorin Disks Gershgorin Disks
Implement functions to calculate Greshgorin Disks and plot them on a cartesian plane.
.rmd knitted with execution results available for download here
Write functions deleted_row_sum and
deleted_col_sum
Both functions will take a square matrix M of dim = n as a parameter and each will return a vector of all the row/col sums.
Each row/col sum is the sum of the absolute values in the all the entries in the ith row/col excluding the ‘deleted’ ith entry.
deleted_row_sum = function(M){ # ensure M is square if(dim(M)[1] != dim(M)[2]){ # return error, quit function stop("Matrix given is not square.") } # continue # result is empty vector of size 'n x 1' res = matrix(nr=dim(M)[1], nc=1) for(i in 1:dim(M)[1]){ deleted_i = 0 # sum up all the values in ith row, excluding the ith value # deleted_i = sum(abs(M[i])) - abs(M[i,i]) for(j in 1:dim(M)[1]){ if(j != i){ deleted_i = deleted_i + abs(M[i,j]) } # else to do nothing res[i] = deleted_i } } return(res)}deleted_col_sum = function(M){ # ensure M is square if(dim(M)[1] != dim(M)[2]){ # return error, quit function stop("Matrix given is not square.") } # continue # result is empty vector of size 'n x 1' res = matrix(nr=dim(M)[1], nc=1) for(i in 1:dim(M)[1]){ # sum up all the values in ith col, then cancel out ith value deleted_i = 0 for(j in 1:dim(M)[1]){ if(j != i){ deleted_i = deleted_i + abs(M[j,i]) } # else to do nothing res[i] = deleted_i } res[i] = deleted_i } return(res)}Write function gershgorin_disks
Takes a square matrix M
Returns a 2-tuple of dataframes
1 dataframe is row_disks, the other is col_disks, so return is c(row_disks, col_disks)
both dataframes contain a column called ‘center’ containing the center coordinates of the disk and another column called ‘radius’ containing the radius of each disk.
The center of each disk in row_disk or col_disk is the deleted ith value, specifically the values on the main diagonal.
The radius of each disk is the deleted_row/col_sum associated with each center.
gershgorin_disks = function(M){ # ensure M is square if(dim(M)[1] != dim(M)[2]){ # return error, quit function stop("Matrix given is not square.") } # continue
# declare return values row_disks = data.frame(matrix(nr=dim(M)[1],nc=2)) col_disks = data.frame(matrix(nr=dim(M)[1],nc=2)) colnames(row_disks) = c("center", "radius") colnames(col_disks) = c("center", "radius")
# define return values row_disks$radius = deleted_row_sum(M) col_disks$radius = deleted_col_sum(M)
row_disks$center = diag(M) col_disks$center = diag(M) return(list(row_disks, col_disks))}Write function plot_gg_disks
Takes square matrix ‘M’
Returns two plots on with the real numbers on the x-axis, and imaginary numbers on the y-axis
Will plot both the ‘row_disks’ and the ‘col_disks’ from the gershgorin_disks function
Use distinct colors for the row disks and the col disks, so you know which is which
Will not be using fill when coloring the disks, due to the possibility of overlap, instead will just be doing an outline, which is technically not accurate, but I figured as long as I acknowledged it, the increase in clarity would be worth it.
plot_gg_disks = function(M){ # ensure M is square if(dim(M)[1] != dim(M)[2]){ # return error, quit function stop("Matrix given is not square.") } # continue disks = gershgorin_disks(M) # print(disks) # plot row_disk
# get data to plot r_x = Re(as.data.frame(disks[1])$center) r_y = Im(as.data.frame(disks[1])$center) r_r = Re(as.data.frame(disks[1])$radius) # * Since radius is the sum of absolute values, |i| = 1, so it's always Real # but, just to be sure c_x = Re(as.data.frame(disks[2])$center) c_y = Im(as.data.frame(disks[2])$center) c_r = Re(as.data.frame(disks[2])$radius)
# construct dataframes to plot circ1 = data.frame( x = r_x, y = r_y, r = r_r ) circ2 = data.frame( x = c_x, y = c_y, r = c_r )
print("row disks are:") print(circ1) print("col disks are:") print(circ2)
# plot both row and col disks ggplot() + geom_circle(aes(x0 = x, y0 = y, r = r), data=circ1, color="red") + geom_circle(aes(x0 = x, y0 = y, r = r), data=circ2, color="blue") + labs(x="Real Numbers", y="Imaginary Numbers") + coord_fixed()
}Write functions make_row_stochastic_matrix and make_col_stochastic_matrix
Start by making a helper function to normalize vectors
normalize = function(vec){ return(vec / sqrt(sum(vec^2)))}A matrix is row stochastic if:
- No entry is equal to zero
- All the entries in a row equal to 1
- Non-Negative Matrix (all entries positive)
- Create a square matrix of size ‘n’
make_row_stochastic_matrix = function(n){ # n x n matrix, all NA mat = matrix(nc=n,nr=n) # generate random n x 1 vectors, all normalized for(i in c(1:n)){ mat[i,] = normalize(runif(n, 0, 2)) } return(mat)}A matrix is col stochastic if:
- No entry is equal to zero
- All the entries in a col equal to 1
- Non-Negative Matrix (all entries positive)
- Create a square matrix of size ‘n’
make_col_stochastic_matrix = function(n){ # n x n matrix, all NA mat = matrix(nc=n,nr=n) # generate random n x 1 vectors, all normalized for(i in c(1:n)){ mat[,i] = normalize(runif(n, 0, 2)) } return(mat)}Use plot_gg_disks to plot the disks associated with the matrices in Q1
# ggplot2 extension package that has geom_circle in itif (!require("ggforce")) { install.packages("ggforce") library(ggforce)}## Loading required package: ggforce## Loading required package: ggplot2## Warning: package 'ggplot2' was built under R version 4.3.3A = matrix(c(1, -1, 1, -2), nc=2, nr=2)B = matrix(c(2, -1, 1i, 1, 1+2i, 0, 1, 2, -1), nc=3, nr=3)plot_gg_disks(A)## [1] "row disks are:"## x y r## 1 1 0 1## 2 -2 0 1## [1] "col disks are:"## x y r## 1 1 0 1## 2 -2 0 1plot_gg_disks(B)## [1] "row disks are:"## x y r## 1 2 0 2## 2 1 2 3## 3 -1 0 1## [1] "col disks are:"## x y r## 1 2 0 2## 2 1 2 1## 3 -1 0 3Plot Random Stochastic Matrices
S1 = make_row_stochastic_matrix(5)S1## [,1] [,2] [,3] [,4] [,5]## [1,] 0.5148093 0.5459863 0.3979048 0.50716414 0.1460365## [2,] 0.4766335 0.8404548 0.1053752 0.06975258 0.2246930## [3,] 0.1617591 0.0160156 0.0472864 0.67656080 0.7166638## [4,] 0.5287457 0.5341048 0.1808659 0.33785498 0.5369372## [5,] 0.2764034 0.4884809 0.5626943 0.59682373 0.1102913S2 = make_col_stochastic_matrix(5)S2## [,1] [,2] [,3] [,4] [,5]## [1,] 0.5581630 0.61107192 0.1159964 0.4579087 0.07239551## [2,] 0.1555763 0.38608039 0.3032119 0.6188590 0.56072628## [3,] 0.3065470 0.08878685 0.1543963 0.1277550 0.52300009## [4,] 0.5513180 0.60798285 0.6080962 0.1969303 0.55387090## [5,] 0.5160692 0.31623850 0.7078051 0.5934899 0.31629554plot_gg_disks(S1)## [1] "row disks are:"## x y r## 1 0.5148093 0 1.5970917## 2 0.8404548 0 0.8764543## 3 0.0472864 0 1.5709993## 4 0.3378550 0 1.7806536## 5 0.1102913 0 1.9244023## [1] "col disks are:"## x y r## 1 0.5148093 0 1.443542## 2 0.8404548 0 1.584588## 3 0.0472864 0 1.246840## 4 0.3378550 0 1.850301## 5 0.1102913 0 1.624330plot_gg_disks(S2)## [1] "row disks are:"## x y r## 1 0.5581630 0 1.257373## 2 0.3860804 0 1.638373## 3 0.1543963 0 1.046089## 4 0.1969303 0 2.321268## 5 0.3162955 0 2.133603## [1] "col disks are:"## x y r## 1 0.5581630 0 1.529511## 2 0.3860804 0 1.624080## 3 0.1543963 0 1.735110## 4 0.1969303 0 1.798013## 5 0.3162955 0 1.709993