Star
Star

Reputation: 2299

Simplify a Matlab code involving finding the position of maximum elements of array

I would like your help to make more efficient (maybe, by vectorising) the Matlab code below. The code below does essentially the following: take a row vector A; consider the maximum elements of such a row vector and let, for example, be i and j their positions; construct two columns vectors, the first with all zeros but a 1 positioned at i, the second with all zeros but a 1 positioned at j.

This is my attempt with loops, but it looks more complicated than needed.

clear
rng default
A=[3 2 3];
max_idx=ismember(A,max(A));
vertex=cell(size(A,2),1);
for j=1:size(max_idx,2)
    if max_idx(j)>0
       position=find(max_idx(j));
       vertex_temp=zeros(size(A,2),1);
       vertex_temp(position)=1;
       vertex{j}=vertex_temp;
    else
       vertex{j}=[];
    end
end
vertex=vertex(~cellfun('isempty',vertex)); 

Upvotes: 0

Views: 71

Answers (3)

Max Coar
Max Coar

Reputation: 1

Is there a specific reason you want a cell array rather than a matrix?

If you can have it all in one vector:

A = [3 2 3] 
B_rowvec = A == max(A)
B_colvec = B_rowvec'

If you need them separated into separate vectors:

A = [3 2 3]
Nmaxval = sum(A==max(A))
outmat = zeros(length(A),Nmaxval)
for i = 1:Nmaxval
    outmat(find(A==max(A),i),i)=1;
end
outvec1 = outmat(:,1)
outvec2 = outmat(:,2)

Basically, the second input for find will specify which satisfactory instance of the first input you want.

so therefore

example = [ 1 2 3 1 2 3 1 2 3 ] 
first = find(example == 1, 1) % returns 1
second = find(example == 1, 2) % returns 4
third = find(example == 1, 3) % returns 7

Upvotes: 0

Craig Arnold
Craig Arnold

Reputation: 58

If you really wanted to avoid a for loop, you could probably also use something like this:

A=[3 2 3];

max_idx = find(A==max(A));
outMat = zeros(numel(A), numel(max_idx));

outMat((0:(numel(max_idx)-1)) * numel(A) + max_idx) = 1;

then optionally, if you want them in separate cells rather than columns of a matrix:

outCell = mat2cell(outMat, numel(A), ones(1,numel(max_idx)))';

However, I think this might be less simple and readable than the existing answers.

Upvotes: 0

rinkert
rinkert

Reputation: 6863

Still using a for loop, but more readable:

A = [3 2 3];

% find max indices
max_idx = find(A == max(A));
vertex = cell(numel(max_idx),1);

for k = 1:numel(max_idx)
    vertex{k} = zeros(size(A,2),1);   % init zeros
    vertex{k}(max_idx(k)) = 1;        % set value in vector to 1
end

Upvotes: 1

Related Questions