split a vecor into several parts (of different sizes) to later fill a matrix.
이전 댓글 표시
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
Davide Ferraro
2012년 8월 30일
I can't understand how your matrix should be structured. Can you please clarify?
Sean de Wolski
2012년 8월 30일
My guess is the loop is the fastest way to do this.
Tom
2012년 8월 30일
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
답변 (4개)
Andrei Bobrov
2012년 8월 30일
편집: Andrei Bobrov
2012년 8월 30일
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
David T_
2012년 8월 30일
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
2012년 8월 30일
Hello David, thank you for reply, I corrected.
Jos (10584)
2012년 8월 30일
편집: Andrei Bobrov
2012년 8월 30일
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
2012년 8월 30일
편집: Sean de Wolski
2012년 8월 30일
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.
카테고리
도움말 센터 및 File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!