2013-03-19 64 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],] 
})))