pythonnumpynetworkxeigenvalue

python numpy and networkx returning different eigenvalues


I've been trying to calculate graph properties of any given graph using the networkx package and numpy in python. However, when I calculate the eigenvalues of a graph laplacian, it seems that numpy and networkx return different eigenvalues. Why is this happening?

import numpy as np
import networkx as nx

#function to normalize laplacian matrix
def symm_norm_laplacian(Lmat):
    Drootmat = np.zeros(shape=(len(Lmat),len(Lmat)))
    for i in range(0,len(Lmat)):
        Drootmat[i,i] = 1/np.sqrt(Lmat[i,i])  
    return Drootmat @ Lmat @ Drootmat

#build simple graph
nodeids = np.array([0,1,2,3,4,5])
parentids = np.array([1,0,0,0,3,3])
G = nx.Graph()
#add nodes
for j in range(0,len(nodeids)):
    G.add_node(nodeids[j])
#add edges
G.add_edge(0,1)
G.add_edge(0,2)
G.add_edge(1,2)
G.add_edge(4,5)
G.add_edge(4,3)
G.add_edge(4,0)
G.add_edge(3,5)

#get Laplacian matrix
LapMat = np.array(nx.laplacian_matrix(G).toarray())

#calculations through numpy
NormLapMat_np = symm_norm_laplacian(LapMat)
eval_np, evec_np = np.linalg.eigh(NormLapMat_np)
sortindex = np.argsort(eval_np)
print('numpy eigenvalues:',eval_np[sortindex])

#calculations through networkx
eval_nx = nx.laplacian_spectrum(G)
print('networkx eigenvalues:',eval_nx)

The output I get is:

numpy eigenvalues: [1.10622686e-16 2.04666355e-01 1.16666667e+00 1.50000000e+00
 1.50000000e+00 1.62866698e+00]
networkx eigenvals: [-6.25317335e-16  4.38447187e-01  3.00000000e+00  3.00000000e+00
  3.00000000e+00  4.56155281e+00]

When I run:

import numpy as np
print('numpy version:',np.__version__)
import networkx as nx
print('networkx version:',nx.__version__)

output is:

numpy version: 2.2.3
networkx version: 3.4.2

and python3 version is 3.12.2

It's driving me nuts trying to work out why the eigenvalues are so different. Could it be my specific machine (MacBook Pro M3 Max)?


Solution

  • You're performing a symmetric normalization on the Laplacian matrix when using NumPy, but not when using NetworkX's built-in function.

    With NumPy, you're calculating a normalized Laplacian matrix using your custom symm_norm_laplacian() function

    With NetworkX, you're getting the unnormalized Laplacian spectrum directly with nx.laplacian_spectrum(G)

    Example output with different methods:

    --- YOUR CODE ---
    NumPy eigenvalues (normalized): [-3.48799941e-16  2.04666355e-01  1.16666667e+00  1.50000000e+00
      1.50000000e+00  1.62866698e+00]
    NetworkX eigenvalues (unnormalized): [-1.25718377e-16  4.38447187e-01  3.00000000e+00  3.00000000e+00
      3.00000000e+00  4.56155281e+00]
    
    --- BOTH UNNORMALIZED ---
    NumPy unnormalized eigenvalues:  [-1.25718377e-16  4.38447187e-01  3.00000000e+00  3.00000000e+00
      3.00000000e+00  4.56155281e+00]
    NetworkX unnormalized eigenvalues: [-1.25718377e-16  4.38447187e-01  3.00000000e+00  3.00000000e+00
      3.00000000e+00  4.56155281e+00]
    Max difference: 0.0
    
    --- BOTH NORMALIZED ---
    NumPy custom normalized eigenvalues:  [-5.55574672e-17  2.04666355e-01  1.16666667e+00  1.50000000e+00
      1.50000000e+00  1.62866698e+00]
    NetworkX normalized eigenvalues:     [-5.55574672e-17  2.04666355e-01  1.16666667e+00  1.50000000e+00
      1.50000000e+00  1.62866698e+00]