Why does MATLAB confuse index variables in a for loop???

I wrote a program that looked like this.
X=ones(3,6);
for i=1:10000 % high number of iterations needed
X= function(X) % perform some operation on X
emptyness= zeros(3,6);
VonNeumann=(X==[max(X);max(X);max(X)]);
emptyness(VonNeumann)=1;
if max(sum(emptyness')) > 1
for i=1:6
emptyness(:,i)=emptyness(:,i)/sum(emptyness(:,i)); % scaling to 1
end
end
X=(1-1/i)*X + emptyness/i;
%#####
end
Now I've tested the emptyness thing and it did exactly what I wanted. Moreover the program as a whole works fine and I get the convergence results that I want. So I expected there to be nothing wrong with my code.
However when I tried to add a new function at the %##### place I noticed that i=6 always. Clearly this caused big errors. So then I noticed that I was sloppy, I used the index variable 'i' in both for loops. So then I changed the index variable in the emptyness for loop to j, changed this and nothing else. And then suddenly the whole program stopped working correctly!
At this point I have no idea why this is happening to me so please help me!

Respuestas (4)

Cedric
Cedric el 19 de Feb. de 2013
Editada: Cedric el 19 de Feb. de 2013
You are using the same index variable i in both nested loops. You should rename both differently (e.g. ii and jj) and then use the debug mode to step in your code, checking what happens when/where. For that, put your cursor on the first line of code and press F12 to set a break point; then press F5 to execute and it will stop at the break point. After that, press F10 to step and observe what happens (F11 if you want to step in the function).

5 comentarios

James
James el 19 de Feb. de 2013
Yes that is what I wrote in my opening post. But changing this caused the program to stop working!
Cedric
Cedric el 19 de Feb. de 2013
Well, the program cannot work with the same index variable. It may output some number, but it doesn't mean that it works, unless most of your computation has to be performed based on i=6.
So here I really recommend using two different index variables, which will eliminate the first source of error, and then work with the debugger step by step to eliminate the next source of error.
James
James el 19 de Feb. de 2013
Sorry but your edit does not answer my question. I have checked the functionality of the emptyness for loop many times in debug mode. It always did exactly what I was expecting and this was confirmed by the fact that the program was working correctly.
I don't understand how MATLAB works, it must be either of these 3 cases:
(1) It keeps giving 'i' the value of the first/outer "i=1:10000" for loop. In which case for i>6 the emptyness for loop should've stopped working totally. This is not what is happening since the program keeps converging for i >> 6.
(2) It keeps giving 'i' the value of the second/inner "i=1:6" for loop. But in this case the convergence of the "X=(1-1/i)*X + emptyness/i;" should be extremely bad, since X contains values between 0 and 1 and emptyness contains only values equal to 0 or 1 (multiple maximums are very rare and if they happen tghey result in 0s and 0.5s). But when I change the second index variable to 'j' the convergence becomes more than thousand times worse!!!!!
(3) MATLAB sees the second/inner "i=1:6" as a dummy variable, so nothing would happen if you change 'i' to 'j' but it changes everything!
At this point I feel liked I've ruled out (1) AND (2) AND (3) so I fail to see any solution!
Cedric
Cedric el 19 de Feb. de 2013
Editada: Cedric el 19 de Feb. de 2013
EDITED code - There is no situation where you want to interfere with the loop index increment mechanism (except when using break) within a loop in MATLAB.
Test e.g. this to understand what happens:
for i = 1:3
fprintf('\nOutter: %d\n',i);
for i = 4:6
fprintf('Inner : %d\n',i);
end
fprintf('Outter: %d\n',i);
end
You'll get
Outter: 1
Inner : 4
Inner : 5
Inner : 6
Outter: 6
Outter: 2
Inner : 4
Inner : 5
Inner : 6
Outter: 6
Outter: 3
Inner : 4
Inner : 5
Inner : 6
Outter: 6
that shows you how the outter/inner loops set a value to i. In your case, as Walter says below, it means that your last line will always be evaluated with i=6 when the conditional statement above it is executed.
James
James el 19 de Feb. de 2013
This makes a lotta sense. Now I've sent my entire folder of .m files to a different computer (using different index variables). And now everything works with no errors!
I guess the solution was to reboot MATLAB on the previous computer...

Iniciar sesión para comentar.

You should not use the same index variable for nested loops.
When you get to the statemet
X=(1-1/i)*X + emptyness/i;
then if the inner loop was run and the names are nested, then at that point "i" would be the maximum value it was assigned in the inner loop (6) rather than whatever value it "should" have in the outer loop. The outer loop will restore the proper next value for "i" (the change inside the loop will not affect the outer loop). So if it worked when your loops are nested and stops working when you renamed "i" to "j" for the inner loop, the implication is that the code relies on "i" being 6 there sometimes. That could indicate a convergence problem elsewhere in the code, if it was converging by mistake.

1 comentario

James
James el 19 de Feb. de 2013
I still don't know how my convergence could've depended on i=6 always, it makes no sense at all from a theoretical standpoint.

Iniciar sesión para comentar.

Muhammad Adil
Muhammad Adil el 2 de Abr. de 2016
Editada: Walter Roberson el 2 de Abr. de 2016
In the following code the idea is that i want to find the derivatives of aa binary sequence repeated untill the bit count reduce to 2; but for first derivative we get 1 bit less but after that same number of bits..... if some one can comment.... i want this result
for alice = [1 1 0 1]
1 1 0 1
0 1 1 (first deri)
1 0 (second deri)
Thanks
close all;
clear all;
clc;
format compact
alice = [1 0 1 1];
der = cell(length(alice)-1, 1);
onz = [];
der{1} = alice;
c = 1;
d=1;
alice_new = [];
in = 0;
% for b = 1:length(alice)-2
len = length(alice);
for b = 1:len-2
c = c+1;
in =0;
for a = 2:1:zz
d = d+1;
in = in+1;
x = xor(alice(d-1), alice(d));
alice_new(1,in)=x
end
der{c}= alice_new;
alice = alice_new;
zz=length(alice_new);
d=1;
end

1 comentario

You are using a function named "zz" whose code you did not show us.

Iniciar sesión para comentar.

Smith
Smith el 22 de Mzo. de 2020
Still having similar issue here on my system. I did transfer the code from matlab environment to java environment and it work very fine there.
I see that Matlab keep repeating some specific loop counter unnecessarily when it shouldn't even if I renamed the index variable. The counter I use to check it still comes out with some values repeating like
1 2 3 4 5 . . 21601 21601 21602 21602 21603 21603
You can see the manner it keep repeating it's index.

Categorías

Más información sobre Startup and Shutdown en Centro de ayuda y File Exchange.

Preguntada:

el 19 de Feb. de 2013

Respondida:

el 22 de Mzo. de 2020

Community Treasure Hunt

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

Start Hunting!

Translated by