为了完成,我还想展示这种技术。如果矩阵的下部(对角线下方)填充了值,则转置的添加将不起作用,因为它会将它们添加到矩阵的上部。
使用 Matrix 包我们可以创建一个稀疏矩阵,在创建一个大矩阵的对称的情况下,它需要更少的内存,甚至可以加快速度。
为了从矩阵e 创建一个对称稀疏矩阵,我们会这样做:
library(Matrix)
rowscols <- which(upper.tri(e), arr.ind=TRUE)
sparseMatrix(i=rowscols[,1], #rows to fill in
j=rowscols[,2], #cols to fill in
x=e[upper.tri(e)], #values to use (i.e. the upper values of e)
symmetric=TRUE, #make it symmetric
dims=c(nrow(e),nrow(e))) #dimensions
输出:
5 x 5 sparse Matrix of class "dsCMatrix"
[1,] . 2 3 4 5
[2,] 2 . 6 8 10
[3,] 3 6 . 12 15
[4,] 4 8 12 . 20
[5,] 5 10 15 20 .
微基准测试:
让我们编写一个函数,从一个矩阵中生成一个对称矩阵(默认将矩阵的上半部分复制到下半部分):
symmetrise <- function(mat){
rowscols <- which(upper.tri(mat), arr.ind=TRUE)
sparseMatrix(i=rowscols[,1],
j=rowscols[,2],
x=mat[upper.tri(mat)],
symmetric=TRUE,
dims=c(nrow(mat),ncol(mat)) )
}
然后测试:
> microbenchmark(
e + t(e),
symmetrise(e),
e[lower.tri(e)] <- t(e)[lower.tri(e)],
times=1000
)
Unit: microseconds
expr min lq mean median uq max neval cld
e + t(e) 75.946 99.038 117.1984 110.841 134.9590 246.825 1000 a
symmetrise(e) 5530.212 6246.569 6950.7681 6921.873 7034.2525 48662.989 1000 c
e[lower.tri(e)] <- t(e)[lower.tri(e)] 261.193 322.771 430.4479 349.968 395.3815 36873.894 1000 b
如您所见,symmetrise 实际上比 e + t(e) 或 df[lower.tri(df)] <- t(df)[lower.tri(df)] 慢得多,但至少您有一个自动对称矩阵的函数(默认情况下取上半部分并创建下半部分),以防万一有一个很大的矩阵,内存是个问题,这可能会派上用场。
附:无论您在矩阵中的何处看到.,这都表示零。通过使用不同的系统,稀疏矩阵是一种“压缩”对象,使其内存效率更高。