2016-10-05 29 views
1

這是很容易崩潰的幾個矩陣(不同尺寸的)合併爲一個1×N個向量:轉換多個矩陣(的不同大小)集成到一個1×N個矩陣,然後再返回

vec = [ A(:)', B(:)', C(:)' ]; 

...但如何我現在可以走另一條路,即從vec恢復U,V,W嗎?

我可以收集A,B,C的大小:

sizes = [ size(A), size(B), size(C) ]; 

...但我看不出做任何復甦的清潔方式。

k=0; 
U = reshape(vec(k+1:k+Ay*Ax), Ay, Ax); k = k+Ay*Ax; 
V = reshape(vec(k+1:k+By*Bx), By, Bx); k = k+By*Bx; 
W = reshape(vec(k+1:k+Cy*Cx), Cy, Cx); k = k+Cy*Cx; 

eeeeeyyuck!當然必須有比這更好的東西?


編輯:爲了應對CST-Link的問題,@ CST-Link的,我居然有7個對象,所以我並不需要過於通用的。但我實際上處理以下結構:

A = ...; B = ...; C = ...; % only 7 mats 
vec = pack(A,B,C); 
ret = f(vec, g); 
A_, B_, C_ = unpack(ret); 

function ret = g(vec) 
    U, V, W = unpack(vec); 
    % fiddle U V W 
    ret = pack(U,V,W); 
end 

...和f將調用g(vec)。

爲了進行內部解包,我需要養活7種的目標尺寸,所以我想我將不得不發送數據作爲單獨PARAM:

A = ...; B = ...; C = ...; % only 7 mats 
vec = pack(A,B,C); sizes = getsizes(A,B,C); 
ret = f(vec, g, sizes); 
A_, B_, C_ = unpack(ret); 

function ret = g(vec, sizes) 
    U, V, W = unpack(vec, sizes); 
    % fiddle U V W 
    ret = pack(U,V,W); 
end 

...儘管unpack函數仍然可以訪問A,B,C,所以實際上,不會混淆額外的變量sizes

+0

你想要一個通用的解決方案,還是隻需要3個矩陣? –

+0

@ CST-Link,好點,我編輯了這個問題。 –

回答

1

我不知道這是否回答您的問題(即,如果你認爲這是乾淨的),但這裏是3點矩陣的解決方案:

A = randi(10,3,1); 
B = randi(10,1,4); 
C = randi(10,5,1); 
vec = [ A(:).', B(:).', C(:).' ]; 
sizes = [size(A).', size(B).', size(C).' ]; 

U = zeros(sizes(:,1).'); 
V = zeros(sizes(:,2).'); 
W = zeros(sizes(:,3).'); 
L = prod(sizes); 
U(:) = vec(1:L(1)); 
V(:) = vec(L(1)+(1:L(2)); 
W(:) = vec(sum(L(1:2))+(1:L(3))); 

它可以很容易地擴展到一個通用的解決方案,但輸入和輸出向量應該存儲在單元陣列中:

function PackUnpack 
A = randi(10,3,2); 
B = randi(10,1,4); 
C = randi(10,5,3); 
[vec,sizes] = pack({A,B,C}); 
ret = unpack(vec,sizes); 
end 

function [vec,sizes] = pack(mats) 
sizes = zeros(2,numel(mats)); 
% build the size vector: 
for k = 1:numel(mats) 
    sizes(:,k) = size(mats{k}).'; 
end 
L = prod(sizes); 
vec = zeros(1,sum(L)); 
pos = cumsum([0 L]); 
% flattening all matrices to one vector 
for k = 1:numel(mats) 
    vec((pos(k)+1):pos(k+1)) = mats{k}(:).'; 
end 
end 

function cell_of_mat = unpack(vec,sizes) 
cell_of_mat = cell(size(sizes,2),1); 
sz = cumsum([0 prod(sizes)]); 
% initialize all matrices to correct size and fill with values 
for k = 1:numel(cell_of_mat) 
    cell_of_mat{k} = zeros(sizes(:,k).'); 
    cell_of_mat{k}(:) = vec((sz(k)+1):sz(k+1)); 
end 
end 
+0

@ p-i看看我對一般情況的編輯。我更喜歡使用'arrayfun'的隱藏符號來表示循環,而且它們也更快。 – EBH

+0

謝謝,不錯的代碼!看起來好像我只能用'''而不是''''。注意別人,我可以這樣做'[P,Q R] = ret {:};'把實際的矩陣作爲單獨的主題出來。我很驚訝你說'for'循環比'arrayfun'執行得更好 - 我已經在其他地方讀到過,顯式循環通常要儘可能避免。 –

+1

@Pi這是[更好的做法](http://stackoverflow.com/a/25150319/2627163)使用'。'','arrayfun'只是一個[花哨的循環](http://stackoverflow.com/a/12526940/2627163),它總是比一個簡單的unnested'for'慢。 – EBH

相關問題