为什么拉普拉斯矩阵不对称?

Why is the Laplacian Matrix not symmetric?

我遇到了 why-laplacian-matrix-need-normalization-and-how-come-the-sqrt-of-degree-matrix

我有一个加权邻接矩阵 adjm(Google 驱动器上的文件 data.csv)。矩阵 adjm 是非对称的。我已经构建了有向图 graph,然后删除了循环和多条边。结果图是连接的且简单的。我使用了 igraph 包中的 graph.laplacian() 函数。我期望获得对称矩阵,但矩阵 L_matrix 不对称。

library(igraph)

# read from file    
adjm = as.matrix(read.csv("data.csv", sep=",", row.names = 1))

isSymmetric(adjm) # FALSE

graph <- graph_from_adjacency_matrix(adjm, weighted=TRUE)

table(count_multiple(graph))

# remove loops and multiple edges
graph <- simplify(graph) 

is_connected(graph) # TRUE

L_matrix <- graph.laplacian(graph, norm=TRUE, 
                            weights = E(graph)$weight, 
                            sparse=FALSE)

isSymmetric(L_matrix) # FALSE

编辑。 我尝试将公差 tol 从 0.1 更改为 0.0001,但结果是 FALSE

isSymmetric(L_matrix, tol = 0.01) # FALSE

L_matrix104104 矩阵的平方。我发现了第一行和第一列之间的区别。然后我计算了零的个数,小于104.

test0 <- L_matrix[1,] - L_matrix[,1]
test0 <- test0[test0 == 0]
length(test0[test0 == 0])
[1] 90

编辑 2.

我想做一个谱聚类。

问题。 为什么拉普拉斯矩阵不对称?

"The resulted graph is connected and simple" 不对:图形仍然是有向的,邻接矩阵不是对称的。例如,

as_adjacency_matrix(graph)[1:5, 1:5]
# 5 x 5 sparse Matrix of class "dgCMatrix"
#      dddd dddD ddDd ddDD dDdd
# dddd    .    .    .    .    .
# dddD    .    .    .    .    .
# ddDd    .    .    .    .    .
# ddDD    .    .    .    .    .
# dDdd    .    1    .    .    .

因此,拉普拉斯算子也不对称。

编辑: 为了使图形无向,我们可以使用

adjm <- pmax(adjm, t(adjm))
all(adjm == t(adjm))
# [1] TRUE

这样,元素 (i,j) 和 (j,i) 都被两者中较大的一个替换。有趣的是,它仍然没有使拉普拉斯算子对称:

L_matrix[1:5, 1:5]
#      dddd        dddD ddDd ddDD       dDdd
# dddd    1  0.00000000    0    0  0.0000000
# dddD    0  1.00000000    0    0 -0.0703125
# ddDd    0  0.00000000    1    0  0.0000000
# ddDD    0  0.00000000    0    1  0.0000000
# dDdd    0 -0.06575342    0    0  1.0000000

问题在于 normalized = TRUE 的工作方式(似乎是一个错误;至少它与文档相矛盾)。手动执行标准化步骤我们有

L_matrix <- graph.laplacian(graph, norm = FALSE, 
                            weights = E(graph)$weight,
                            sparse = FALSE)
L_matrix <- diag(1 / sqrt(diag(L_matrix))) %*% L_matrix %*% diag(1 / sqrt(diag(L_matrix)))
isSymmetric(L_matrix)
# [1] TRUE
L_matrix[1:5, 1:5]
#      [,1]        [,2] [,3] [,4]        [,5]
# [1,]    1  0.00000000    0    0  0.00000000
# [2,]    0  1.00000000    0    0 -0.06799476
# [3,]    0  0.00000000    1    0  0.00000000
# [4,]    0  0.00000000    0    1  0.00000000
# [5,]    0 -0.06799476    0    0  1.00000000