split a vecor into several parts (of different sizes) to later fill a matrix.
Mostrar comentarios más antiguos
Hi!
I have a vector V and I want to split it in several parts of different known sizes (in the example below, the sizes would be: [3,6,5,...]), to build a matrix like this one (example):
M = [ V(1) V(4) V(10) ....
V(2) V(5) V(11) ....
V(3) V(6) V(12)
0 V(7) V(13)
0 V(8) V(14)
0 V(9) 0
0 0 0 ]
so each column is padded with zeros until a certain number of rows is reached (fixed a priori)
Any idea of how to do that WITHOUT using a loop (for ... end)? i.e. doing it in just one step (like matricial operation) because this has to be done a lot of times and with a loop the required time would be too much.
Thanks in advance!
Merce
3 comentarios
Davide Ferraro
el 30 de Ag. de 2012
I can't understand how your matrix should be structured. Can you please clarify?
Sean de Wolski
el 30 de Ag. de 2012
My guess is the loop is the fastest way to do this.
Tom
el 30 de Ag. de 2012
I agree with Sean, you already know the size M has to be so you can preallocate M as a matrix of zeros and then fill it in a column at a time in a loop
Respuestas (4)
Andrei Bobrov
el 30 de Ag. de 2012
Editada: Andrei Bobrov
el 30 de Ag. de 2012
try this is code
V = 10:10:140; % eg
s =[3 6 5];
b = cumsum(s) - s + 1;
i0 = bsxfun(@plus,b,(0:max(diff(b))-1)');
t = bsxfun(@lt,i0,[b(2:end) numel(V)+1]);
i0(~t) = 1;
out = V(i0).*t;
OR
V = 10:10:140;
s =[3 6 5];
a = cellfun(...
@(x,y)[x(:);zeros(max(s)-y,1)],mat2cell(V(:)',1,s),num2cell(s(:)'),'un',0);
out = [a{:}];
2 comentarios
David T_
el 30 de Ag. de 2012
Nice code, but you have an extra row at the bottom filled with zeros. Just a very small change needed:
here
V=(1:15)/pi; % e.g. |
b = [1 4 10 12]; V
i0 = bsxfun(@plus,b,(0:max(diff(b))-1)');
t = bsxfun(@lt,i0,[b(2:end) numel(V)+1]);
i0(~t) = 1;
out = V(i0).*t;
Andrei Bobrov
el 30 de Ag. de 2012
Hello David, thank you for reply, I corrected.
Jos (10584)
el 30 de Ag. de 2012
Editada: Andrei Bobrov
el 30 de Ag. de 2012
Take a look at MAT2CELL and PADCAT
% data
V = 1:15 ;
sz = [3 5 6 1] ; % lengths
% engine
C = mat2cell(V(:),sz,1) ;
[M,tf] = padcat(C{:}) ;
M(~tf) = 0 ; % replace NaNs by 0, per request
Sean de Wolski
el 30 de Ag. de 2012
Editada: Sean de Wolski
el 30 de Ag. de 2012
I have a simple for-loop showing a 2.7x and a 9.5x speed up over Andrei's solutions for V,S being this size. In general, a for-loop will smoke conversions so cell arrays any time and with the JIT accelerator it can generally hold up to complicated vectorized methods. Consider Andrei's dataset:
function looptest
%Data: same data all
V = 10:10:140; % eg
s =[3 6 5];
times = zeros(1,3);
for ii = 1:100;
%Andrei's first method
tic
b = cumsum(s) - s + 1;
i0 = bsxfun(@plus,b,(0:max(diff(b))-1)');
t = bsxfun(@lt,i0,[b(2:end) numel(V)+1]);
i0(~t) = 1;
out = V(i0).*t;
times(1) = times(1)+toc;
%Andrei's second method
tic;
a = cellfun(...
@(x,y)[x(:);zeros(max(s)-y,1)],mat2cell(V(:)',1,s),num2cell(s(:)'),'un',0);
out2 = [a{:}];
times(2) = times(2)+toc;
%trivial for-loop
tic
ns = numel(s);
out3 = zeros(max(s),ns);
sel = cumsum([1 s(1:end-1)]); %start element
eel = sel+s-1; %end element
for jj = 1:ns
out3(1:s(jj),jj) = V(sel(jj):eel(jj));
end
times(3) = times(3)+toc;
end
disp(times./times(3));
My System: 2.7907 9.5219 1.0000
Note if we blow V and S up a fair amount, Andrei's bsxfun solution does surpass the for-loop for at least a little while.
Merce Casas Prat
el 30 de Ag. de 2012
0 votos
Categorías
Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!