将多个矩阵(不同大小)转换为单个1xN矩阵并再次返回

时间:2016-10-05 21:39:01

标签: matlab serialization matrix

很容易将几个矩阵(大小不同)折叠成一个1xN向量:

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个目标维度,所以我想我将不得不将该数据作为单独的参数发送:

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变量。

1 个答案:

答案 0 :(得分: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