我有一個m×m的矩陣,我想轉換爲一個m×m的矩陣,每個m×m的塊包含對角線每行。如何向量化矩陣的行對角化
例如,如果輸入是:
[1 2; 3 4; 5 6]
輸出應爲:
[1 0; 0 2; 3 0; 0 4; 5 0; 0 6]
當然,我不想通過步驟自己與for
組裝矩陣步驟循環。
有沒有一種矢量化和簡單的方法來實現這一目標?
我有一個m×m的矩陣,我想轉換爲一個m×m的矩陣,每個m×m的塊包含對角線每行。如何向量化矩陣的行對角化
例如,如果輸入是:
[1 2; 3 4; 5 6]
輸出應爲:
[1 0; 0 2; 3 0; 0 4; 5 0; 0 6]
當然,我不想通過步驟自己與for
組裝矩陣步驟循環。
有沒有一種矢量化和簡單的方法來實現這一目標?
對於要做到這一點的矢量化方法,請將對角線元素的線性索引創建到結果矩陣中,然後直接進行賦值。
%# create some input data
inArray = [10 11;12 13;14 15];
%# make the index array
[nr,nc]=size(inArray);
idxArray = reshape(1:nr*nc,nc,nr)';
idxArray = bsxfun(@plus,idxArray,0:nr*nc:nr*nc^2-1);
%# create output
out = zeros(nr*nc,nc);
out(idxArray) = inArray(:);
out =
10 0
0 11
12 0
0 13
14 0
0 15
下面是一個簡單的向量化溶液,假設X
被輸入矩陣:
Y = repmat(eye(size(X, 2)), size(X, 1), 1);
Y(find(Y)) = X;
另一種替代方法是使用sparse
,這可以寫爲一個整齊的一行:
Y = full(sparse(1:numel(X), repmat(1:size(X, 2), 1, size(X, 1)), X'));
我看到這樣做的最簡單方法其實很簡單,只需使用簡單的索引引用和重塑函數:
I = [1 2; 3 4; 5 6];
J(:,[1,4]) = I;
K = reshape(J',2,6)';
如果檢查J
,它看起來像這樣:
J =
1 0 0 2
3 0 0 4
5 0 0 6
矩陣K
正是想:
K =
1 0
0 2
3 0
0 4
5 0
0 6
由於埃坦噸的評論所指出的,上面是具體以此爲例,並未涵蓋一般解決方案。下面是一般解決方案,其中m和n如問題中所述。
J(:,1:(m+1):m^2) = I;
K=reshape(J',m,m*n)';
如果你想進行測試,看看它的工作,只需要使用
I=reshape(1:(m*n),m,n)';
注:如果j已經存在,這可能會導致問題。在這種情況下,你也需要使用
J=zeros(n,m^2);
-1:這會觸發一個錯誤:「腳本賦值維度不匹配。」。即使它能奏效,這甚至不是正確的輸出。 –
尺寸不匹配是由於一個錯字 - 我說J(:,1:4),但它應該說是J(:,[1,4])。我錯誤地轉錄了它,都是。錯誤已得到糾正,並且應該按預期工作。至於輸出,如果你注意,我正在描述矩陣J,這不是最終的輸出。 K是輸出,它看起來完全像Litro所要求的......至少,它是在Octave上。 –
現在有效,所以我刪除了downvote。但請注意,它不是通用的,因爲它只在'I'有兩列時才起作用。 –
它可能不是計算最有效的解決方案,但這裏的使用kron
1班輪:
A = [1 2; 3 4; 5 6];
B = diag(reshape(A', 6, 1) * kron(ones(3, 1), eye(2))
% B =
% 1 0
% 0 2
% 3 0
% 0 4
% 5 0
% 0 6
如果A是n×m的這個可推廣:
diag(reshape(A.', n*m, 1)) * kron(ones(n,1), eye(m))
你能解釋一下'bsxfun'的功能嗎? – ja72
@ ja72:bsxfun自動擴展數組,以便您可以例如添加一個n×1的數組到一個n×m的數組。開頭的句柄(在這種情況下爲「@ plus」)告訴執行哪個操作。使用'repmat'更快,更方便。 – Jonas
'bsxfun'岩石! – Shai