6

Using MATLAB, I have an array of values of size 8 rows x N columns. I need to create a matrix of the same size, that counts maximum values in each column and puts 1 in the cell that contains maximum value, and 0 elsewhere.

A little example. Lets assume we have an array of values D:

    D =
      0.0088358   0.0040346   0.40276     0.0053221
      0.017503    0.011966    0.015095    0.017383
      0.14337     0.38608     0.16509     0.15763
      0.27546     0.25433     0.2764      0.28442
      0.01629     0.0060465   0.0082339   0.0099775
      0.034521    0.01196     0.016289    0.021012
      0.12632     0.13339     0.11113     0.10288
      0.3777      0.19219     0.005005    0.40137

Then, the output matrix for such matrix D would be:

    0    0    1    0
    0    0    0    0
    0    1    0    0
    0    0    0    0
    0    0    0    0
    0    0    0    0
    0    0    0    0
    1    0    0    1

Is there a way to do it without catching vector of indices from max function and then putting ones in the right place using for loop?

4
  • You could do this in Python in no time ;) Commented Jan 17, 2010 at 15:23
  • unfortunately I need to use Matlab :) Commented Jan 17, 2010 at 15:24
  • 2
    Out of curiosity, how would you want to handle the case where there are two or more values that equal the maximum in a column? Commented Jan 17, 2010 at 18:59
  • There always must be only one "1" in each column. This matrix D contains coefficients of credibility for some competitive algorithms, and there should be always only one selected. So if there are two or more equal values, algorithm must always select only one, no matter which. Commented Jan 18, 2010 at 11:04

3 Answers 3

8

A one-line answer:

M = D==repmat(max(D),size(D,1),1)

or more elegantly:

M = bsxfun(@eq, D, max(D))

Update:

According to the comments, if you want to be on the safe side and catch the accidental non-unique maximums, add the following statement:

M( cumsum(M)>1 ) = false

which will ensure that in the case of multiple maximums, only the first to occur has a corresponding one in the output matrix (this is equivalent to the behavior of the max() function's returned index).

Sign up to request clarification or add additional context in comments.

3 Comments

+1: This was the answer I was thinking of when I asked if the OP wanted to count repeated maxima. This will mark a "1" in every place in a column where a value equals the maxima for that column. Mikhail's solution will find just the first occurrence.
I guess the OP now can pick the adequate solution.. good catch though (the truth is I was just thinking of writing shorter code!)
Thanks, I forgot about the case of more than one max value. In fact, it is almost impossible to occur in my algorithm, but... Well, as I commented in other responses, I must select always only one value, so the other solution is better.
7

There are probably better ways to do it, my first approach is:

D          = rand(8,4)

[val, sub] = max(D)    
ind        = sub2ind( size(D), sub, 1:4 )

res        = false( size(D) )
res( ind ) = true

3 Comments

Works pretty like a charm. Thanks, Mikhail!
+1: This is the solution for the case when you just want to find the first occurrence of a maximum value in a column. To find every value equal to the maximum for each column, Amro's solution is best.
I see. Fortunately, there is always only one max value and in fact, there should be only one "1" in each column. In other case my algorithm would crash. So, a little by accident, this solution is the best for my case
1

I have written an extension to the original problem that can handle arbitrary multidimension array and search for maximum along any specified dimension.

I used it to solve for the Nash equilibrium in game theory. Hope others will find it helpful.

A = rand([3 3 2]);
i = 1; % specify the dimension of A through which we find the maximum

% the following codes find the maximum number of each column of A
% and create a matrix M of the same size with A
% which puts 1 in the cell that contains maximum value, and 0 elsewhere.

[Amax pos] = max(A, [], i);
% pos is a now 1x3x3 matrix (the ith dimension is "shrinked" by the max function)

sub = cell(1, ndims(A));
[sub{:}] = ind2sub(size(pos), (1:length(pos(:)))');
sub{i} = pos(:);

ind = sub2ind(size(A), sub{:});
M = false(size(A));
M(ind) = true;

Example:

A(:,:,1) =

0.0292    0.4886    0.4588
0.9289    0.5785    0.9631
0.7303    0.2373    0.5468

A(:,:,2) =

0.5211    0.6241    0.3674
0.2316    0.6791    0.9880
0.4889    0.3955    0.0377

M(:,:,1) =

 0     0     0
 1     1     1
 0     0     0

M(:,:,2) =

 1     0     0
 0     1     1
 0     0     0

1 Comment

Example: A(:,:,1) = 0.0292 0.4886 0.4588 0.9289 0.5785 0.9631 0.7303 0.2373 0.5468 A(:,:,2) = 0.5211 0.6241 0.3674 0.2316 0.6791 0.9880 0.4889 0.3955 0.0377 M(:,:,1) = 0 0 0 1 1 1 0 0 0 M(:,:,2) = 1 0 0 0 1 1 0 0 0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.