【问题标题】:Sum of matrix elements between diagonals efficiently in RR中对角线之间的矩阵元素之和有效
【发布时间】:2016-06-24 08:20:31
【问题描述】:

我有n*n 矩阵形式的数据,我想对其元素放置在对角线之间(不包括对角线)进行一些计算(例如sum)。

例如对于这个矩阵:

     [,1] [,2] [,3] [,4] [,5]
[1,]    2    0    1    4    3
[2,]    5    3    6    0    4
[3,]    3    5    2    3    1
[4,]    2    1    5    3    2
[5,]    1    4    3    4    1

sum(在对角元素之间)的结果是:

# left slice 5+3+2+5 = 15
# bottom slice 4+3+4+5 = 16
# right slice 4+1+2+3 = 10
# top slice 0+1+4+6 = 11

# dput(m)
m <- structure(c(2, 5, 3, 2, 1, 0, 3, 5, 1, 4, 1, 6, 2, 5, 3, 4, 0, 
3, 3, 4, 3, 4, 1, 2, 1), .Dim = c(5L, 5L))

如何有效地做到这一点?

【问题讨论】:

  • 你的问题不清楚。请详细说明“左切片”等是什么意思的数值计算。
  • 已更新。现在应该清楚了。
  • package Matrix 应该破解这个...
  • @ColonelBeauvel 我一直支持(可能)与base R 一起完成我的任务。

标签: r matrix diagonal


【解决方案1】:

以下是获得“顶部切片”的方法:

sum(m[lower.tri(m)[nrow(m):1,] & upper.tri(m)])
#[1] 11

将其可视化:

lower.tri(m)[nrow(m):1,] & upper.tri(m)
#      [,1]  [,2]  [,3]  [,4]  [,5]
#[1,] FALSE  TRUE  TRUE  TRUE FALSE
#[2,] FALSE FALSE  TRUE FALSE FALSE
#[3,] FALSE FALSE FALSE FALSE FALSE
#[4,] FALSE FALSE FALSE FALSE FALSE
#[5,] FALSE FALSE FALSE FALSE FALSE

以下是计算所有 4 个切片的方法:

up <- upper.tri(m)
lo <- lower.tri(m)
n <- nrow(m)

# top
sum(m[lo[n:1,] & up])
# left
sum(m[lo[n:1,] & lo])
# right
sum(m[up[n:1,] & up])
# bottom
sum(m[up[n:1,] & lo])

【讨论】:

  • 感谢您提供干净整洁的解决方案。投赞成票 + 接受。
【解决方案2】:
sum(sapply(1:dim(m)[[2L]], function(i) sum(m[c(-i,-(dim(m)[[1L]]-i+1)),i])))

这是逐列的,每列取出对角线元素并对其余元素求和。然后总结这些部分结果。

我相信这会很快,因为我们逐列进行,并且 R 中的矩阵是逐列存储的(即它对 CPU 缓存友好)。我们也不必为每列生成大的索引向量,只需生成两个索引(取出的)的向量。

编辑:我再次仔细阅读了这个问题。可以更新代码以为 sapply 中的每个元素生成列表四个值:对于每个区域。这个想法保持不变,对于大型矩阵,如果你逐列而不是在列之间来回跳跃,它会很快。

【讨论】:

  • 嗯,是的,但是从列方面来说,这意味着您的第一列中的数据是一块内存,然后是第二列中的数据等。我的意思是虽然它都是连续的内存,但它更快在本地访问它en.wikipedia.org/wiki/Locality_of_reference
  • 如果需要所有切片的总和,那么为什么不这样做:diag(m)=0; diag(m[5:1,])=0; sum(m); 等于 52。但我想分别对每个切片进行计算。
  • 如果零对角线没问题,那么这可能会更快
  • 即使不行,我们也可以简单地复制矩阵。
  • 但是我们正在复制可能很大的矩阵,我不确定这会表现得更好
猜你喜欢
  • 2016-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
相关资源
最近更新 更多