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

时间:2019-04-13 06:53:32

标签: r matrix igraph symmetric

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

我有一个加权邻接矩阵adjm(Google云端硬盘上的文件data.csv)。矩阵adjm是非对称的。我建立了有向图graph,然后删除了循环和多条边。结果图是连接且简单的。我使用了graph.laplacian()包中的igraph函数。我期望获得对称矩阵,但是矩阵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_matrix104乘以104矩阵的平方。我发现第一行和第一列之间的区别。然后,我计算了零个数,它小于104

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

编辑2。

我想进行光谱聚类。

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

1 个答案:

答案 0 :(得分:1)

“结果图已连接且简单” 是不正确的:该图仍然是有向图,并且邻接矩阵不是对称的。例如,

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