split a vecor into several parts (of different sizes) to later fill a matrix.
Mostra commenti meno recenti
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 Commenti
Davide Ferraro
il 30 Ago 2012
I can't understand how your matrix should be structured. Can you please clarify?
Sean de Wolski
il 30 Ago 2012
My guess is the loop is the fastest way to do this.
Tom
il 30 Ago 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
Risposte (4)
Andrei Bobrov
il 30 Ago 2012
Modificato: Andrei Bobrov
il 30 Ago 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 Commenti
David T_
il 30 Ago 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
il 30 Ago 2012
Hello David, thank you for reply, I corrected.
Jos (10584)
il 30 Ago 2012
Modificato: Andrei Bobrov
il 30 Ago 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
il 30 Ago 2012
Modificato: Sean de Wolski
il 30 Ago 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
il 30 Ago 2012
0 voti
Categorie
Scopri di più su Loops and Conditional Statements in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!