简体   繁体   中英

“Find” function with two outputs needed?

I am trying to use a 'for' loop find the number of values in a randomly generated vector that are 1) greater than 0.5 and output also 2) the number of values greater than 0.8. This is what I have

function bigger1 = bigger(input, max)
for max = 0.5:0.3:0.8;
 index = find(input > max);

end 
  bigger1=length(index);
end

For instance, with the input bigger([.1 .2 .3 .4 .5 .6 .7 .8 .9 3 5]) I would like to output "6" and "3"

So far it only gives me the output for one of the 'max' values.

There's a couple of things not quite right with what you're doing.

  • Don't use max as a variable name. It is also the name of a built-in function, and using it as a variable name shadows that function. BAD practice.
  • Same for input
  • You give max as an input, while you re-define it as the loop variable. This new definition overwrites the old one, so the max function input is useless.
  • At each iteration, you re-define what index is--the output of the next call to find . Therefore, don't be surprised that you have only the outcomes of the last iteration.
  • Your call to find will actually find the indices to all true values, in general. You have to sum all these occurrences, not find the index.
  • ... I'll stop there for now :)

A better implementation:

function out = bigger(in, mx)        
    out = zeros(size(mx));
    for ii = 1:numel(mx)
        out(ii) = sum(in > mx(ii)); end        
end

A more "hacky" one eliminates one line of code, while preserving performance:

function out = bigger(in, mx)                
    for ii = numel(mx):-1:1
        out(ii) = sum(in > mx(ii)); end        
end

The one that will probably teach you the most once you've figured it all out (it's also fastest BTW):

out = @(in, mx) reshape( sum(bsxfun(@gt, in(:).', mx(:)), 2), size(mx) );

Since you're using only one variable in the for loop, you overwrite it in each iteration - so it is natural that you get only one value. Ie, if you want to store both, make a vector 2 by 1.

Adiel has explained how to do it your way in a comment, however this is not really the Matlab way to solve this problem. Here is a neater way to do it:

I = rand(50,1);   %// btw input is a bad choice of variable name as it is a built-in matlab function which you are overriding.

bigger(1) = sum(I > 0.5);
bigger(2) = sum(I > 0.8);

or to put this in a loop:

limits = [0.5, 0.8];
for n = 1:length(limits)
    bigger(n) = sum(I > limits(n));
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM