2016-05-10 69 views
4

我想將列插入矩陣,但矩陣中插入列的位置因行而不同。我怎樣才能做到這一點,而不使用for循環?在Matlab中將列插入到矩陣中

以下是MATLAB中的簡化示例; 從A,X,P開始,我想在不使用for-loop的情況下獲得APX。

>> A = zeros(4,5)  % inclusive matrix 

A = 
    0 0 0 0 0 
    0 0 0 0 0 
    0 0 0 0 0 
    0 0 0 0 0 

>> X = [9,8;5,7;8,3;6,7] % data to insert 

    X = 
    9 8 
    5 7 
    8 3 
    6 7 

>> P = [3;2;4;1] % insertion position within the matrix 

P = 
    3 
    2 
    4 
    1 

>> APX = [0,0,9,8,0;0,5,7,0,0;0,0,0,8,3;6,7,0,0,0] % what I want 

    APX = 
    0 0 9 8 0 
    0 5 7 0 0 
    0 0 0 8 3 
    6 7 0 0 0 
+1

使用for循環有什麼問題? – ToBe

+0

向量化代碼比Matlab中的for循環要快得多,特別是當矩陣尺寸非常大時;即千萬x千分之一 –

+3

@HyungDonLee你真的應該嘗試使用循環,然後再嘗試向量化。 MATLAB R2015b有一個改進的JIT引擎,其循環現在具有競爭力。 – rayryeng

回答

6

它只是確定正確的列主要指標訪問矩陣,所以你可以用你想要的值填充它。首先需要生成正確的行和列值以訪問APX中的正確位置,以便您可以使用X來填充這些位置。

使用P,每個元素都會告訴您應該爲每行X開始填充哪個列。您需要按升序生成列索引,最多列數爲X。要生成行索引,只需創建一個與X大小相同的矩陣,其中每個列從0到最大行數與X減1(即0:size(X,2)-1)的行數相同。該矩陣爲您提供正確的偏移量,以便您可以採取P並將其與此矩陣相加。一旦你這樣做了,你將有一個列索引矩陣,它可以明確告訴你每個元素應該在哪裏去關於每行P的輸出矩陣的列。最後,使用sub2ind使用上面生成的行和列生成列主要索引,以將X放置在APX中。

換句話說:

P = [3;2;4;1]; 
X = [9,8;5,7;8,3;6,7]; 

rowInd = repmat((1:size(X,1)).', 1, size(X,2)); %' 
colInd = bsxfun(@plus, P, 0:size(X,2)-1); 
APX = zeros(size(X,1), max(colInd(:))); 
APX(sub2ind(size(APX), rowInd, colInd)) = X; 

要生成的行的位置,我們使用repmat創建一個矩陣,其大小相同X其中每列從1跨度達儘可能多的行作爲X。要生成列位置,我們使用bsxfun創建一個矩陣,其中每列是矢量P,但每列增加1。然後我們創建APX爲兼容大小,然後使用sub2ind最終填充矩陣。

與您上面的測試輸入,我們得到:

APX = 

    0  0  9  8  0 
    0  5  7  0  0 
    0  0  0  8  3 
    6  7  0  0  0 

小注

你真的應該真正嘗試嘗試它之前矢量使用循環。雖然在以前的MATLAB版本中使用循環很慢,但是MATLAB R2015b有一個改進的JIT引擎,其循環現在具有競爭力。您應該使用循環來確定代碼的時間,並確保在切換到矢量化實現之前它是合理的。

+0

在這種情況下'repmat'優於'meshgrid'或'bsxfun(@plus,zeros(1,size(X,2))',1:size(X,1))。''? –

+0

@StewieGriffin我沒有考慮'meshgrid',因爲它輸出兩個變量......我認爲它很浪費。我認爲'repmat'會比資源更保守。 – rayryeng

+0

我想它已經[測試](http://stackoverflow.com/a/29753104/2338750)。 –