I have the matrix a=[5 5 10 10 2 4 5],I want the result to be d=[5 1 2 7;10 3 4 0;2 5 0 0;4 6 0 0],
Show older comments
I have the matrix
a=[5 5 10 10 2 4 5],
I want the result to be
d=[ 5 1 2 7;
10 3 4 0;
2 5 0 0;
4 6 0 0],
3 Comments
the cyclist
on 25 Nov 2013
It is not at all clear to me how d relates to a .
Azzi Abdelmalek
on 25 Nov 2013
How?
yousef Yousef
on 25 Nov 2013
Answers (4)
Image Analyst
on 25 Nov 2013
How about this:
a=[5 5 10 10 2 4 5]
d = transforma(a); % Call transforma() in the main program.
function d = transforma(a)
d=[ 5 1 2 7;
10 3 4 0;
2 5 0 0;
4 6 0 0];
It meets all the criteria you've given.
4 Comments
Azzi Abdelmalek
on 25 Nov 2013
Nice answer!
yousef Yousef
on 25 Nov 2013
Image Analyst
on 25 Nov 2013
There is once I defined it. Did you overlook the
function d = transforma(a)
statement where I defined it?
yousef Yousef
on 25 Nov 2013
Sean de Wolski
on 25 Nov 2013
a=[5 5 10 10 2 4 5],
clear d;
[u,~,iy] = unique(a,'stable');
for ii = numel(u):-1:1
lhs = [u(ii) find(iy==ii).'];
d(ii,1:numel(lhs)) = lhs;
end
6 Comments
Image Analyst
on 25 Nov 2013
Edited: Image Analyst
on 25 Nov 2013
I knew it . They are getting very close to finishing the Crystal Ball Toolbox. Sean, care to say when it will be released, or is it still a closely held secret?
Walter Roberson
on 25 Nov 2013
It can be done without using find() at all, by using bsxfun(@eq) and logical indexing that against 1:length(a)
yousef Yousef
on 25 Nov 2013
yousef Yousef
on 25 Nov 2013
Edited: Walter Roberson
on 26 Nov 2013
yousef Yousef
on 25 Nov 2013
Sean de Wolski
on 26 Nov 2013
Edited: Sean de Wolski
on 26 Nov 2013
@Walter, I'd be curious to time bsxfun(...) against find. I agree that any opportunity for a bsxfun, it should be used just 'cuz it's awesome.
@IA, you know how silent we are on future features :)
@Yousef, I do see the duplicated 20 in column two above. But I don't know how you got it. Please give me full reproduction steps.
When I run something like the following, it passes as I expect:
a = randi(700,[1 10000]);
% a=[5 5 10 10 2 4 5],
clear d;
[u,~,iy] = unique(a,'stable');
for ii = numel(u):-1:1
lhs = [u(ii) find(iy==ii).'];
d(ii,1:numel(lhs)) = lhs;
end
T = matlab.unittest.TestCase;
import matlab.unittest.constraints.IsEqualTo
T.verifyThat(ismember(1:numel(a),d(:,2:end)),IsEqualTo(true(1,numel(a))));
T.verifyThat(nnz(d(:,2:end)),IsEqualTo(numel(a)));
Interactive verification passed.
Interactive verification passed.
Andrei Bobrov
on 26 Nov 2013
Edited: Andrei Bobrov
on 26 Nov 2013
[a1,b,c] = unique(a(:),'first')
[~,ii] = sort(b);
a1 = a1(ii);
c = ii(c);
n = max(histc(c,(1:max(c))'));
f1 = @(x){[x(:)',zeros(1,n-numel(x))]};
p = accumarray(c,(1:numel(c))',[],f1)
out = [a1, cat(1,p{:})];
or with Nan
[a1,b,c] = unique(a(:),'first')
[~,ii] = sort(b);
a1 = a1(ii);
c = ii(c);
idx = bsxfun(@times,1:numel(a),bsxfun(@eq,a1,a));
idx(idx==0) = nan;
ii = sort(idx,2);
out = [a1,ii(:,~all(isnan(ii)))];
Roger Stafford
on 27 Nov 2013
Edited: Roger Stafford
on 27 Nov 2013
Here's another version. Let a be your array and d be the desired result.
[u,t,q] = unique(a(:),'first','stable');
[q,p] = sort(q);
r = p;
n = size(p,1);
r(p) = (1:n)';
t = r(t);
r = cumsum(1-accumarray(t(2:end),diff(t),[n,1]));
d = [i.accumarray([q,r],p)];
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!