Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

vectorized solution

0 views
Skip to first unread message

Joshua

unread,
Aug 8, 2008, 6:41:02 AM8/8/08
to
I was wondering if someone can help arrange data in the
following format.

1) I have a vector consisting of Vec1 = [1 1 1 2 2 2 2 2 3
3 4 4 4 4 4 etc....]. the lengths of 1's, 2's, 3's are all
different.

2) I have another vector Vec2 consisting of data with the
same length as Vec1

3) I would like to obtain a matrix such that the first
column consists of data in Vec2 at the position where 1's
occur in in Vec1, column 2 consists of data in Vec2 at the
position where 2's occur in Vec1 etc....

As the lengths of the 1's, 2's, 3's etc... are not the
same, the matrix would have to be padded with zeros.

Any thoughts would be appreciated. I can do this in a loop
format but I would have thought there should be a simpler
way which I can't figure out.

Thanks!

daniloz

unread,
Aug 8, 2008, 8:58:41 AM8/8/08
to

Hey,

what about:

N1=3
N2=2
N3=4
N4=2
v1 = [1*ones(1,N1) 2*ones(1,N2) 3*ones(1,N3) 4*ones(1,N4)]
N = N1+N2+N3+N4
v2 = 1:N
V = zeros(4)
V(sub2ind([4 4],[1:N1 1:N2 1:N3 1:N4],v1)) = v2

It's not exhaustively tested, but it should do the job.

Kind regards,
\daniloz

Matt Fig

unread,
Aug 8, 2008, 11:28:02 AM8/8/08
to
This function does all the work for you. All you need is
the vectors v and t. Note that v must have at least one of
each value up to the maximum. I tested it with all of these
vectors v.
I am not convinced that this would be faster than a well
done for loop with Matlabs JIT, but it was challenging to
figure out!

% v = [1 1 2 2 2 3 3 3 3 4 4 4 5 5 5 5 5 6 6 6 6 6];
% v = [1 1 2 2 2 3 3 3 3 4 4 4 5 5 5 5 5 5 6 6 6 6 6];
% v = [1 1 1 2 2 3 3 3 3 4 4 4 5 6 6 6 6 6 6];
% v = [ 1 2 2 2 2 2 3 4 5 5 6];
v = [1 1 1 1 1 1 2 3 4 5 6 6 6 7]; % The indeces.
t = round(rand(1,length(v))*100)/10+1; % Data
mat = makemat(v,t);

function [mat] = makemat(v,t)
%MAKEMAT...
[B,I,J] = unique(v);
lngths = diff([0,I]); % The number of repeats.
sz = max(lngths); % The largest number of repeats.
istrt = abs(sz*(0:max(B)-1) + 1); % Starting ind to matrix.
listrt = length(istrt);
iend = istrt + (lngths-1); % Stopping indices to matrix.
mat = zeros(max(lngths),length(B)); % Preallocate.
idxv = cumsum(iend-istrt+1); % last indeces into v.
idxmat = ones(1,idxv(end)); % The index into the matrix.
idxmat(1+idxv(1:end-1)) = istrt(2:listrt)-iend(1:listrt-1);
idxmat = cumsum(idxmat);
mat(idxmat) = t;

Joshua

unread,
Aug 8, 2008, 12:27:02 PM8/8/08
to
thanks. works great!

"Matt Fig" <spam...@yahoo.com> wrote in message <g7hom2$dmt
$1...@fred.mathworks.com>...

gg

unread,
Oct 4, 2008, 6:45:03 AM10/4/08
to
you might want to try accumarray. I have not checked whether this is faster than previous solutions. Note that indices in subs can be missing and must not be in any order.

Regards,
gg

%-----------------------------------------------------------
Vec1 = [2 2 1 5 2 2 3 1 3 5 5 5 2 5 5 5]';
Vec2 = rand(length(Vec1),1);
n = max(accumarray(Vec1,1));
tmp = accumarray(Vec1 ,Vec2 ,[],...
@(x)({[x;zeros(n - length(x),1)]}),{zeros(n,1)}...
)';
cell2mat(tmp)
%-----------------------------------------------------------

"Joshua " <joshu...@gmail.com> wrote in message <g7h7ru$rqo$1...@fred.mathworks.com>...

0 new messages