【问题标题】:Lower RAM consumption for a transformation of a transition matrix转换矩阵的 RAM 消耗更低
【发布时间】:2018-03-02 17:25:04
【问题描述】:

我编写了以下两个函数,它们将转换矩阵作为输入,哪些节点应该处于吸收状态并对其进行转换。

第一个函数set.absorbing.states() 有3 个参数。 tm 是初始转移矩阵,第二个inn 是一个指定的初始节点,而第三个soi 是感兴趣的集合。 “感兴趣的集合”是指该矩阵中必须设置为吸收状态的一组节点。这样一个初始矩阵如下:

tm <- read.table(row.names=1, header=FALSE, text="
A 0.2 0.3 0.1 0.2 0.1 0.1 
B 0.3 0.1 0.1 0.2 0.2 0.1
C 0 0.2 0.4 0.1 0.2 0.1 
D 0.2 0.1 0.2 0.3 0.1 0.1
E 0.2 0.2 0.1 0.2 0.1 0.2
F 0.3 0.2 0.4 0.1 0 0")

colnames(tm) <- row.names(tm)

如您所见,该矩阵中没有吸收状态。例如,假设我们要将AE 以及随机选择的初始节点B 设置为吸收状态。

通过执行第一个函数tm1 &lt;- set.absorbing.states( tm , "B", c("A","E")),我们得到了一个已设置吸收状态的矩阵:

    A   B   C   D   E   F
A 1.0 0.0 0.0 0.0 0.0 0.0
B 0.3 0.1 0.1 0.2 0.2 0.1
C 0.0 0.2 0.4 0.1 0.2 0.1
D 0.2 0.1 0.2 0.3 0.1 0.1
E 0.0 0.0 0.0 0.0 1.0 0.0
F 0.3 0.2 0.4 0.1 0.0 0.0

如您所见,AE 已变为吸收状态。

下一步是将该矩阵转换为所有吸收状态节点(行和列)都到达末尾的方式。因此,通过运行ptm &lt;- transform.tm( tm1, c("A","E") ),我们得到了一个如下所示的矩阵:

    B   C   D   F   A   E
B 0.1 0.1 0.2 0.1 0.3 0.2
C 0.2 0.4 0.1 0.1 0.0 0.2
D 0.1 0.2 0.3 0.1 0.2 0.1
F 0.2 0.4 0.1 0.0 0.3 0.0
A 0.0 0.0 0.0 0.0 1.0 0.0
E 0.0 0.0 0.0 0.0 0.0 1.0

您现在可以清楚地看到AE 节点到达了该矩阵的末尾。

下面是我正在使用的函数。

set.absorbing.states <- function ( tm, inn, soi )
{
  set <- which( row.names(tm) %in% soi )
  set <- set[which( set != inn )]
  for (i in set )
    tm[i,] <- 0
  for (i in set)
    tm[i,i] <- 1
  tm
}

transform.tm <- function ( tm, soi )
{
  end_sets <- which(row.names(tm) %in% soi)
  ptm <- rbind( cbind(tm[-end_sets, -end_sets], tm[-end_sets, end_sets]) , cbind(tm[end_sets, -end_sets], tm[end_sets, end_sets]) )
  ptm
}

现在的问题是,有了这么小的矩阵,一切都正常工作。但是我尝试使用一个大矩阵(20.000*20.000),它需要 32GB RAM 来执行第二个函数。

那么有什么方法可以以更节省资源的方式执行此操作吗?

【问题讨论】:

    标签: r matrix transform


    【解决方案1】:

    使用索引将显着减少转换函数创建的副本数量(通过rbindcbind)。它在概念上可能更简单一些(前提是对使用[ 进行索引有充分的理解)。

    transform.tm1 <- function ( tm, soi ) {
      newOrder <- c(setdiff(row.names(tm), soi), soi)
      tm[newOrder, newOrder]
    }
    

    这里,setdiff 用于提取不匹配的名称并将它们放在向量的前面。然后,只需通过行/列名称重新排序矩阵。

    返回

    transform.tm1(tm1, c("A", "E"))
        B   C   D   F   A   E
    B 0.1 0.1 0.2 0.1 0.3 0.2
    C 0.2 0.4 0.1 0.1 0.0 0.2
    D 0.1 0.2 0.3 0.1 0.2 0.1
    F 0.2 0.4 0.1 0.0 0.3 0.0
    A 0.0 0.0 0.0 0.0 1.0 0.0
    E 0.0 0.0 0.0 0.0 0.0 1.0
    

    检查它们是否返回相同的结果

    identical(transform.tm(tm1, c("A", "E")), transform.tm1(tm1, c("A", "E")))
    [1] TRUE
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      相关资源
      最近更新 更多