Stuck in a While loop...sometimes

조회 수: 3 (최근 30일)
Amy
Amy 2011년 11월 8일
Hi
So the code below works when the conditional values for the second while loop are 5, 10, and 20. However, when I change any of those values (20 --> 81.5 for example), this causes the LAST while loop to freeze, and I must ctrl+c to exit. Why will this code fail when I change some conditional values?
x = rand(1,500); %Random People Coordinates
y = rand(1,500);
x = 170*x'-85;
y = 170*y'-85;
prev_dist = zeros(500,1);
i=1;
while i<501
prev_dist(i) = (x(i)^2) + (y(i)^2);
i = i+1;
end
Dead = 20.5;
Immobile = 54.5;
Slow = 81.5;
living = zeros(500,1);
i = 1;
while i<501
if prev_dist(i) < (5)^2
living(i) = 0;
else
living(i) = 1;
end
if prev_dist(i) < (10)^2 && prev_dist(i) > (5)^2
living(i) = 0.5;
end
if prev_dist(i) < (20)^2 && prev_dist(i) > (10)^2
living(i) = 0.8;
end
i = i+1;
end
new_dist = zeros(500,1);
xdum = zeros(500,1);
ydum = zeros(500,1);
i=1;
while i<501
if living(i) == 1 || living(i) == 0.8
while new_dist(i) < prev_dist(i)
xdir = rand();
ydir = rand();
if xdir < 0.5 %Left
xdum(i) = x(i)-2;
elseif xdir > 0.5 %Right
xdum(i) = x(i)+2;
end
if ydir < 0.5 %Down
ydum(i) = y(i)-2;
elseif ydir > 0.5 %Up
ydum(i) = y(i)+2;
end
if living(i) == 1
new_dist(i) = (xdum(i)^2) + (ydum(i)^2);
elseif living(i) == 0.8
new_dist(i) = (0.8)*((xdum(i)^2) + (ydum(i)^2));
end
end
else
new_dist(i) = prev_dist(i);
end
i = i+1;
end
i = 1;
while i<501
if living(i) == 1 || living(i) == 0.8
prev_dist(i) = new_dist(i);
end
i = i + 1;
end
prev_dist
  댓글 수: 1
Image Analyst
Image Analyst 2011년 11월 8일
You have 5 while loops and they are all "while i<501" except for the 4th one which is "while new_dist(i) < prev_dist(i)" so in which condition are you changing a 5, 10, or 20 to 81.5?

댓글을 달려면 로그인하십시오.

답변 (3개)

Fangjun Jiang
Fangjun Jiang 2011년 11월 8일
I think it is this while loop that causes the problem.
while new_dist(i) < prev_dist(i)
It might be an infinite loop.
All your other while-loop can be changed to for-loop. You really should look into it. For fixed number of iterations, for-loop is a better option. You really don't need all the i=i+1; lines.
  댓글 수: 5
Dr. Seis
Dr. Seis 2011년 11월 8일
No Fangjun, "prev_dist" doesn't change based on the numbers she describes. "prev_dist" is defined before "Dead", "Immobile", and "Slow" so that doesn't explain it. The only place "prev_dist" changes is at the end, which isn't apart/inside of that problematic while loop.
In fact, changing those numbers doesn't appear to affect anything in her code. I wish we knew how those numbers factor in.
Fangjun Jiang
Fangjun Jiang 2011년 11월 8일
Good point, Elige! I assumed too soon.
I found out that even without changing the value from 20 to 81.5, it could also be trapped in the infinite while loop. I think it is data dependent because the code used lots of random number. 81.5 just makes it happen more often.
Without any comments, it's hard to understand the intent of the code. But with enough time, I wouldn't think this is a hard problem to solve.

댓글을 달려면 로그인하십시오.


Image Analyst
Image Analyst 2011년 11월 8일
Normal debugging can solve this. For some reason your " while new_dist(i) < prev_dist(i)" loop never exits when i = 112. I don't know why but I'm sure you can track it down using regular debugging techniques like everyone knows (setting breakpoints, examining variables, etc.) just as well as I can.
  댓글 수: 1
Amy
Amy 2011년 11월 8일
Is this for the new values of 20.5, 54.5 and 81.5? And I'm not really familiar with breakpoints adn the actual Matlab debugger. Hopefully I can figure it out.

댓글을 달려면 로그인하십시오.


Dr. Seis
Dr. Seis 2011년 11월 8일
The problem is with the population where "living" is equal to (0.8). There are cases where no combination of adding or subtracting 2 from the x- and y-coordinates (then of course squaring the sum/differences, then summing the squares, and then multiplying the sum of the squares by 0.8) will allow the "new_dist" to ever be greater than "prev_dist".
In the following code, I show you visually the whereabouts of the problematic x- and y-coordinate pairs:
[X,Y] = meshgrid(-85:0.1:85);
prev_dist = X.^2 + Y.^2;
prev_dist(prev_dist > (20)^2) = 0;
prev_dist(prev_dist < (10)^2) = 0;
range = zeros(size(X));
range(prev_dist > 0) = 1;
counter = 0;
for ii = 1 : size(X,1)
for jj = 1 : size(X,2)
if range(ii,jj)
x = X(ii,jj);
y = Y(ii,jj);
for i = 1 : 4
for j = 1 : 4
r = ((x+2*(-1)^i)^2 + (y+2*(-1)^j)^2)*0.8;
if r > prev_dist(ii,jj)
counter = counter + 1;
break;
end
end
if r > prev_dist(ii,jj)
break;
end
end
if r <= prev_dist(ii,jj)
range(ii,jj)=0.5;
end
end
end
end
figure;
imagesc(-85:0.1:85,-85:0.1:85,range);
colorbar;
xlabel('x');
ylabel('y');
title(sprintf('Location of data with "living" equal 0.8 has amplitude of 1 or 0.5'));
The x- and y- points that are associated with a "living" value of (0.8) have an amplitude greater than 0. Those points that are able to exit out of the while loop (eventually) have an amplitude of 1. The points that will never, ever, ever be able to exit out of the while loop (under the conditions you set above) will have an amplitude of 0.5.

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by