2013-03-19 58 views
1

我有一个正整数和负整数的矩阵。我想将所有 的所有可能的组合加在一个特定列(在下面的示例中的列“a”)中具有相反符号的任意两行的行,使得该列中的加法值为零。矩阵所有可能的两行相反符号的组合

合并行数放在newmat,newmat[,"a"]只有零。

问题是我的解决方案对于较大的矩阵(> 500行)变得过于缓慢。

##initialize matrix 
nof.rows <- 100 
mat <- cbind(matrix(ncol=40, nrow=nof.rows, sample(40*nof.rows)), 
     matrix(ncol=6, nrow=nof.rows, c(1,2,-1,3, -2, -3), 
       dimnames=list(seq_len(nof.rows),c("a", "b", "c", "d", "e", "f")))) 

newmat <- matrix(ncol=ncol(mat), nrow=0) 

##column which will contain nothing but zeroes 
col <- "a" 

for (i in seq_len(nrow(mat))){ 
    curr.row <- mat[i,] 
    curr.col <- mat[,col] 
    opposite.sign.indices <- vector() 
    if(curr.row[col] > 0) 
    opposite.sign.indices <- which(curr.col<0) 
    else 
    opposite.sign.indices <- which(curr.col>0) 
    opposite.sign.indices <- setdiff(opposite.sign.indices, seq_len(i)) 
    for (j in opposite.sign.indices){ 
     opposite.sign.row <- mat[j,] 
     newrow <- (abs(opposite.sign.row[col]) * curr.row 
       + (abs(curr.row[col])*opposite.sign.row)) 
     newmat <- rbind(newmat, newrow) 
    } 
} 

newmat <- unique(newmat) 

有关我如何加速过程的任何想法?在此先感谢-H-

+0

是有更深层次的目标,或者你真的只想0的列?如果是这样,你可能会更好,只需计数 – 2013-03-19 16:49:01

+1

好吧,显而易见的是首先为'newmat'分配存储空间。此刻你分配0行。如果您不确切知道'newmat'需要多少行,请分配很多行,将其填入并在循环中检查已填充的行数。当你填满它时,分配更多的行并进行填充。这样你只需要复制/扩展几次迭代。目前,你在内部循环的每次迭代中增长'newdat',这是非常低效的。 – 2013-03-19 16:53:36

+0

@Ricardo Saporta在我的新矩阵中,我想要一个特定的列只包含零。 new'= | r2 ['a'] | * r1 + | r1 ['c'] | * r2在新的矩阵中,任何两列r1和r2在列'a' 。这样,我的专栏'a'得到平衡。 – user1981275 2013-03-19 16:54:21

回答

0

这是更快:

##initialize matrix 
nof.rows <- 100 
mat <- cbind(matrix(ncol=40, nrow=nof.rows, sample(40*nof.rows)), 
     matrix(ncol=6, nrow=nof.rows, c(1,2,-1,3, -2, -3), 
       dimnames=list(seq_len(nof.rows),c("a", "b", "c", "d", "e", "f")))) 
col="a" 

pos.row.idx <- which(mat[,col]>0) 
neg.row.idx <- which(mat[,col]<0) 
newmat <- unique(t(apply(expand.grid(pos.row.idx, neg.row.idx), 1, function(x){ 
    abs(mat[x[2],col]) * mat[x[1],] + abs(mat[x[1],col]) * mat[x[2],] 
})))