For Loop or if condition ignores the first value

9 views (last 30 days)
Hello everybody, I´ve got a problem with the following code. The code executes quite well, but the first value is ignored:
for j=1:n_pop
for i=1:n_auf*n_lkw
for k=1:n_auf
if matrix(j,i)==auftraege(k,1)
matrix(j,i)=auftraege(k,2);
end
end
end
end
(The 1 is the first value of the matrix called auftraege)
0 5 0 4 0 1 2 0 0 3
0 2 0 1 0 1 1 0 0 3
If I change the the code above (changing k into a 1 in the if condition):
for j=1:n_pop
for i=1:n_auf*n_lkw
for k=1:n_auf
if matrix(j,i)==auftraege(1,1)
matrix(j,i)=auftraege(k,2);
end
end
end
end
0 0 4 0 0 3 0 2 5 1
0 0 4 0 0 3 0 2 5 4
Now you can see that the code includes the first value (and is of course ignoring the other ones). I think the for loop skips the first value of k=1:n_auf, because if I change the k=1:n_auf to k=2:n_auf, I get the same solution as before.... Do you have another guess whats the problem with the code? Or do you even got a solution?
  1 Comment
dpb
dpb on 1 Jun 2019
We can't see anything without both matrix and auftragege
I'm quite sure the loop does what it says it does; the problem (if there is one) will be in either
  1. The data aren't what you think and so a comparison isn't T|F for a given element you think should be (but we don't have the data so don't know what would give), or
  2. You simply have incorrect expectation for what the code should do versus what was written.
I'd guess there's something not right and it's 2. above because as written the loop on k will leave the last element in column 2 of auftrage in the (j,i) element of matrix which, I'm guessing, is probably not what you're intending. But, you don't explain what it is that is intended so that's purely guesswork.
A (small) complete example of inputs and expected outputs would likely help...as would specifically illustrating what you think is incorrect above.
A walk thru the code in the debugger to catch logical errors in coding may lead to nirvana...

Sign in to comment.

Answers (1)

Guillaume
Guillaume on 1 Jun 2019
Note that for loops iterating over a whole matrices, it's safer to plug the matrix size directly into the loop rather than relying on intermediate variables:
for i = 1:size(matrix, 2) %rather than n_pop
for j = 1:size(matrix, 1)
for k = 1:size(auftraege, 1)
%...
end
end
end
As dpb said, most likely either your data is not what you think it is or your expectation of the code is wrong and we can't tell what it is without having some demo data.
As the code is not commented, we don't know what its intent is. I suspect that it's intent is to look up the values of matrix in the 1st column of auftraege and replace them by the corresponding value in the 2nd column. If that is indeed the intent, then there is a massive flaw in your code, in that you can have a chain reaction of replacements for the same matrix(i,j). e.g, let's say auftraege is:
auftraege = [1 3
2 2
3 4
4 1];
and matrix(i,j) is 1. You're now iterating over k.
  • k is 1, matrix(i,j) is 1, therefore matrix(i,j) == auftraege(1, 1) and you replace matrix(i,j) by matrix(i,j) becomes 3. Move on to next k step
  • k is 2, our new matrix(i,j) is 3. Not equal to auftraege(2, 1). No replacement, move on to next k step
  • k is 3, matrix(i,j) is also 3. Therefore matrix(i,j) == auftraege(3, 1) and we replace it again, now by aufraege(3, 1), so matrix(i,j) is now 4. Move on to next k step
  • k is 4, matrix(i,j) is also 4. Therefore matrix(i,j) == auftraege(4, 1) and we replace it again, now by aufraege(3, 1), so matrix(i,j) is now 1.
  • end of the k loop, matrix(i, j) is 1, it doesn't appear to have changed but in fact changed 3 time
If the above was actually the intent of the code, then a huge comment explaining it would be required and I'll note that the replacement is dependent on the order of the rows in auftraege which again would require a comment in code.
If the above wasn't intended, a simple fix is to add a break in the if branch:
for k = 1:size(auftraege, 1)
if matrix(j,i)==auftraege(k,1)
matrix(j,i)=auftraege(k,2);
break; %don't process any more rows of auftraege once we've found our look up value
end
end
But of course, as usual in matlab, the whole thing can be achieved a lot faster and simpler without any loops:
[found, where] = ismember(matrix, auftraege(:, 1)); %loop up all values of matrix in 1st column of auftraege
matrix(found) = auftraege(where(found), 2); %and replace those that where found by the 2nd column of auftraege in the matching row.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!