Gershgorin Circles Demo¶

Prelims¶

In [1]:
import numpy as np
import matplotlib.pyplot as plt
In [2]:
# Draw the circles from the matrix
def GershgorinCircles(B):
    '''
     GershgorinCircles(B)
     
     Create a plot of the Gershgorin circles from the rows
     of the square matrix B. It also plots the eigenvalues.
    '''
    c = []
    for k,r in enumerate(B):
        ctr = r[k]
        radius = np.sum(np.abs(r)) - np.abs(ctr)
        print('Centre = '+str(ctr)+' ,  Radius = ',str(radius))
        c.append( plt.Circle((np.real(ctr), np.imag(ctr)), radius=radius, fill=True, alpha=0.25) )

    # Create the plot, and add the eigenvalues on top
    fig = plt.figure(figsize=(6,6))
    ax = plt.gcf().gca()
    ax.set_xlim(left=-4, right=4); plt.xlabel('Real')
    ax.set_ylim(bottom=-4, top=4); plt.ylabel('Imag')
    ax.grid('on')
    if True:
        v = np.linalg.eig(B)[0]

        for cc in c:
            plt.gcf().gca().add_artist(cc)

        for vv in v:
            plt.plot([np.real(vv)], [np.imag(vv)], 'bo')

Try it out¶

In [3]:
rr = np.random.randint(0, 500)
np.random.seed(seed=rr)
In [7]:
# Random matrix
B = np.random.normal(size=(3,3))
B = np.round(B, decimals=1)
v = np.linalg.eig(B)[0]
print(B)
for vv in v:
    print(np.round(vv, decimals=3))
[[ 1.6  0.3  1.6]
 [ 1.   1.1 -0.2]
 [-1.1  1.9  1.5]]
(0.916+1.572j)
(0.916-1.572j)
(2.367+0j)
In [5]:
B = np.array([[1,0.5,0.5],[0.5,2,1],[1,1,-2.]])
In [8]:
GershgorinCircles(B)
Centre = 1.6 ,  Radius =  1.9
Centre = 1.1 ,  Radius =  1.2000000000000002
Centre = 1.5 ,  Radius =  3.0
In [13]:
# Try a different random matrix
B = np.random.normal(size=(5,5))
B = np.round(B, decimals=1)
v = np.linalg.eig(B)[0]
print(B)
for vv in v:
    print(np.round(vv, decimals=3))

GershgorinCircles(B)
[[ 0.1 -0.1  1.  -1.7 -0.5]
 [-0.4 -0.1 -0.9  1.1 -0.7]
 [-1.  -0.2 -1.3  1.3 -0.1]
 [ 0.   0.4 -0.2  0.9 -0.6]
 [-0.  -0.3  0.7 -0.6  1.1]]
(-0.754+0.679j)
(-0.754-0.679j)
(1.601+0j)
(0.836+0j)
(-0.23+0j)
Centre = 0.1 ,  Radius =  3.3
Centre = -0.1 ,  Radius =  3.1
Centre = -1.3 ,  Radius =  2.5999999999999996
Centre = 0.9 ,  Radius =  1.2000000000000002
Centre = 1.1 ,  Radius =  1.6

How about a diagonally dominant matrix?¶

In [16]:
n = 7
B = 2.*(np.random.random(size=(n,n)) - 0.5)/n
B += np.eye(n) * np.diag(np.random.choice([-1,1], size=n))
print(np.round(B, decimals=2))
print(np.sum(np.abs(B), axis=1))

GershgorinCircles(B);
[[-0.95  0.09 -0.03 -0.08 -0.13  0.07  0.02]
 [-0.09  0.86  0.07  0.13  0.05 -0.06 -0.1 ]
 [-0.03  0.01 -0.88 -0.04 -0.08  0.03 -0.02]
 [ 0.13  0.1  -0.07  1.09  0.11 -0.07 -0.03]
 [-0.08  0.02  0.12  0.01  1.12  0.09 -0.05]
 [-0.12  0.09  0.11 -0.   -0.07 -1.03 -0.06]
 [ 0.14 -0.08  0.14  0.05 -0.08  0.09 -0.97]]
[1.36165453 1.37148231 1.0851152  1.60191412 1.48072878 1.48511705
 1.54852841]
Centre = -0.9463885465169354 ,  Radius =  0.41526598754973876
Centre = 0.8647414916368589 ,  Radius =  0.5067408141796949
Centre = -0.8842808702076845 ,  Radius =  0.20083432927191613
Centre = 1.0938722058927026 ,  Radius =  0.508041912255891
Centre = 1.1199962337524076 ,  Radius =  0.360732546716112
Centre = -1.0343301508791742 ,  Radius =  0.4507868942597655
Centre = -0.9714165941695723 ,  Radius =  0.5771118113108078
In [ ]: