降低转换矩阵的RAM消耗

问题描述 投票:0回答:1

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

第一个函数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 <- 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 <- 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个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.