split a vecor into several parts (of different sizes) to later fill a matrix.
Ältere Kommentare anzeigen
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 Kommentare
Davide Ferraro
am 30 Aug. 2012
I can't understand how your matrix should be structured. Can you please clarify?
Sean de Wolski
am 30 Aug. 2012
My guess is the loop is the fastest way to do this.
Tom
am 30 Aug. 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
Antworten (4)
Andrei Bobrov
am 30 Aug. 2012
Bearbeitet: Andrei Bobrov
am 30 Aug. 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 Kommentare
David T_
am 30 Aug. 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
am 30 Aug. 2012
Hello David, thank you for reply, I corrected.
Jos (10584)
am 30 Aug. 2012
Bearbeitet: Andrei Bobrov
am 30 Aug. 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
am 30 Aug. 2012
Bearbeitet: Sean de Wolski
am 30 Aug. 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
am 30 Aug. 2012
0 Stimmen
Kategorien
Mehr zu Loops and Conditional Statements finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!