0

I get an error for undefined function or variable in the if statement (last line before last end), when I have already assigned the equalities.

l_min = nan(372,1);
A = randn(372,3);
B= randn(372,3);
for t=1:372
    min_ct = min( A(t,:));
      if min_ct == A(t,1);
        l = B(t,1);
        if min_ct == A(t,2);
            l = B(t,2);
        elseif min_ct == A(t,3);
            l = B(t,3);
        end
    end
    l_min(t) = l;
end

Could anyone help with this one?

user7137145
  • 57
  • 1
  • 1
  • 7
  • You don't define `l` anywhere if your initial logic statement is false (`if min_ct == A(t,1)`), so `l_min(t) = l;` cannot be evaluated. In the future, it's much more helpful if you provide the *actual* error message, not your paraphrasing of it, since it tells the exact line where the issue is located. – sco1 Oct 30 '17 at 13:58
  • It is impossible not to satisfy one of the criteria since the minimum value of A(1,:), for example, must be equal to some of the elements of A(1,:)!! All I want to get is the position of the minimum value for every iteration of t. For example if A(1,:) = [5 3 2], the minimum value is obvious that it is 2, which is the third element. I would like the code to pick the third element of a vector B(1,:) allocate it in the first position of the vector l_min. – user7137145 Oct 30 '17 at 14:01
  • 2
    I Imagine the second 'if' is actually meant to be an 'elseif' and one of the 'end's removed. – Daniel Aldrich Oct 30 '17 at 14:02
  • It's clearly not impossible because that's what's happening. You can [use the debugger](https://www.mathworks.com/help/matlab/matlab_prog/debugging-process-and-features.html) to convince yourself. You're never going to get to the inner criteria if `min_ct ~= A(t,1)`. I suggest you reevaluate your logic block. – sco1 Oct 30 '17 at 14:04
  • @DanielAldrich Is correct: you need to change the 2nd `if` to `elseif`. You can also avoid the chain of `if`'s altogether by using the second output of `min` that gives you the index of the minimum found. – beaker Oct 30 '17 at 14:30

2 Answers2

1

Your if logic is flawed, and should instead be

min_ct = min(A(t,:));
if min_ct == A(t,1);
    l = B(t,1);
elseif min_ct == A(t,2); % <-- Note thise is an *else*if
    l = B(t,2);
elseif min_ct == A(t,3);
    l = B(t,3);
end

Your weird half-indentation probably acted to confuse the flow of your logic.


Note: using == on doubles is prone to give you unexpected results as well, so you should consider using a better method for this anyway. In particular, the second output of the min function is designed to do exactly what you want!

Replace your if ladder with the following:

for t=1:372
    [~, min_idx] = min(A(t,:));
    l_min(t) = B(t, min_idx);
end
Wolfie
  • 27,562
  • 7
  • 28
  • 55
0

You can accomplish your task even without the for loop, using vectorization.

This is done by using the index output from the min function and specifying which direction you wish to determine the minimums in. Just replace everything in and after for loop with:

[~, ind] = min(A,[],2); % Determine minimum locations
bindex = sub2ind(size(B),1:size(B,1),ind') % Convert the subscripts to indices 
l_min = B(bindex)';
Daniel Aldrich
  • 328
  • 3
  • 10