How can stop "while" loop

Hi, I have a while loop, my code is inside the loop. I want to stop the loop when the same number (must be non zero)created in the matrix from the first row to the last row.
ex.
this matrix is inside the while loop:
U3(:,:,1) = [
0 , 0 , 0 , 1 , 0;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
U3(:,:,2) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 0
]
U3(:,:,3) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
Now, the loop will continue but if U3(1,2, 1) becomes equal to 1, the loop will stop. How can I do it?
Note:
The bath from the first row to the last row can go in any direction (x,y,z) but it must pass from the topped row to the bottom row similar to the above example. The bath from the topped row to the bottom row is as:
U3(1,2,1), U3(2,2,1), U3(3,2,1), U3(3,2,2), U3(4,2,2), U3(5,2,2) and U3(3,2,3) ONLY

 Réponse acceptée

Hisham
Hisham le 21 Août 2012

0 votes

But how can I do it for 3D matrix?
Note: I might have more than an island, but I want to stop the while loop when any of the islands created a path from the topped row to the bottom row.

Plus de réponses (2)

José-Luis
José-Luis le 21 Août 2012
Modifié(e) : José-Luis le 22 Août 2012

1 vote

Your condition should be
[x y z] = size(U3);
condZ = sum(sum(sum(U3,3) == z)) > 0;
condY = sum(sum(sum(U3,2) == y)) > 0;
condX = sum(sum(sum(U3) == x)) > 0;
stopBool = condX || condY || condZ;
Cheers!

27 commentaires

Hisham
Hisham le 21 Août 2012
Sorry, what do you mean by "data" and numbers "3 and 2" Thanks!:)
José-Luis
José-Luis le 21 Août 2012
Modifié(e) : José-Luis le 21 Août 2012
By data I meant U3., sorry. The numbers indicate along which dimension you do the sum. If the sum is equal to the matrix size along that dimension -> success. Any success-> Great success!
Hisham
Hisham le 21 Août 2012
Modifié(e) : Hisham le 21 Août 2012
Actually, I've tried to apply it but it shows me error. Here is the code and the error message.
________
The Code
________
[x y z] = size(U3);
condX = sum(sum(U3,3) == z) > 0;
condY = sum(sum(U3,2) == y) > 0;
condZ = sum(sum(U3) == x) > 0;
if ((sum(sum(U3,3) == z) > 0) (sum(sum(U3,2) == y) > 0) (sum(sum(U3) == x) > 0))
disp('Bath has been created')
break;
else
disp('the bath has not been created yet')
end
_______________
The output
_______________
Operands to the and && operators must be convertible to logical scalar values.
José-Luis
José-Luis le 21 Août 2012
Modifié(e) : José-Luis le 21 Août 2012
The operator for the while loop is stopBool
while (~stopBool)
%do your stuff
end
Hisham
Hisham le 21 Août 2012
Modifié(e) : Hisham le 21 Août 2012
I did this code but there is an error):
________
while (~stopBool)
[x y z] = size(U3);
condX = sum(sum(U3,3) == z) > 0;
condY = sum(sum(U3,2) == y) > 0;
condZ = sum(sum(U3) == x) > 0;
if ((sum(sum(U3,3) == z) > 0) || (sum(sum(U3,2) == y) > 0) || (sum(sum(U3) == x) > 0))
disp('Bath has been created')
break;
else
disp('the bath has not been created yet')
end
end
How can I defin stopBool?
Undefined function or variable 'stopBool'.
Also,I definded stopBool as equal to 0. The out put still the same: Operands to the and && operators must be convertible to logical scalar values.
José-Luis
José-Luis le 21 Août 2012
Look at my original answer...
Hisham
Hisham le 21 Août 2012
I did as you said but the error stil the same.
Here is the code:
while(~stopBool)
[x y z] = size(U3);
condX = sum(sum(U3,3) == z) > 0;
condY = sum(sum(U3,2) == y) > 0;
condZ = sum(sum(U3) == x) > 0;
stopBool = condX || condY || condZ;
end
Operands to the and && operators must be convertible to logical scalar values.
José-Luis
José-Luis le 21 Août 2012
You are totally right, i forgot that you need to aggregate along two dimensions. It should be sum(sum(sum....)). Modified the original posting.
Hisham
Hisham le 22 Août 2012
I think the code that you provided is not true. The reason is the value of "stopBool", either the bath created or not created, is equal to 1. Thus, the code should has something to distinguish whether the bath has been created or not?
Here is the code:
while(~stopBool)
[x y z] = size(U3);
condX = sum(sum(U3,3) == z) > 0;
condY = sum(sum(U3,2) == y) > 0;
condZ = sum(sum(U3) == x) > 0;
stopBool = condX || condY || condZ;
end
Just to let you know, the value of "stopBool" must be defined before the "while" loop, I defined it as 0.
Here is an example when the bath is created in the 3D matrix.
U3(:,:,1) = [
0 , 1 , 0 , 1 , 0;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
U3(:,:,2) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 0
]
U3(:,:,3) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
However, here is the 3D matrix but the bath has not been created yet.
U3(:,:,1) = [
0 , 0 , 0 , 1 , 0;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
U3(:,:,2) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 0
]
U3(:,:,3) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
José-Luis
José-Luis le 22 Août 2012
I think i understand what you mean. I have a question. Should the "islands" be in contact to form a path. That is, do U(1,2,1)=1 together with U(2,2,3)=1 form a path segment or not? The solution will be different whether they do or not.
Hisham
Hisham le 22 Août 2012
Yes the "islands" will be in contact to form a path.
José-Luis
José-Luis le 22 Août 2012
Use bwconncomp, if you have the image processing toolbox. If i understand correctly you want connectivity 26. Look at all the connected components and find whether any of them goes from one side to the other.
Hisham
Hisham le 22 Août 2012
Here is the problem in "bwconncomp".
See the whole example please.
U3(:,:,1) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0
];
U3(:,:,2) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 0
];
U3(:,:,3) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 1
];
Now I will explain the all chain(s):
The first chain is: U3(3,2,1) and U3(3,2,2)and U3(4,2,2) and U3(5,2,2)and U3(3,2,3)
The second chain is: U3(3,5,1) and U3(4,5,1) and U3(3,5,2)
The third chain is: U3(4,5,3) and U3(5,5,3)
to give each chain a similar individual number
(i.e).
U3(3,2,1) and U3(3,2,2)and U3(4,2,2) and U3(5,2,2)and U3(3,2,3)=2
U3(3,5,1) and U3(4,5,1) and U3(3,5,2)=3
U3(4,5,3) and U3(5,5,3)=4
One of the suggested solutions is to use :
CC = bwconncomp(U3);
labelmatrix(CC)
But this function is not valid for my case because it gives the first chain individual number (which is fine), and combined the second and third chains in one number (which is not fine)
See the output (which is wrong not as I want).
CC = bwconncomp(U3); labelmatrix(CC)
ans(:,:,1) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 2
0 0 0 0 2
0 0 0 0 0
ans(:,:,2) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 2
0 1 0 0 0
0 1 0 0 0
ans(:,:,3) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 2
0 0 0 0 2
Hisham
Hisham le 22 Août 2012
I did as you suggested but the output still the same. Only two chains but in the reality there are three chains.
CC = bwconncomp(U3,26)
CC =
Connectivity: 26
ImageSize: [5 5 3]
NumObjects: 2
PixelIdxList: {[5x1 double] [5x1 double]}
labelmatrix(CC)
ans(:,:,1) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 2
0 0 0 0 2
0 0 0 0 0
ans(:,:,2) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 2
0 1 0 0 0
0 1 0 0 0
ans(:,:,3) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 2
0 0 0 0 2
You can see there is no connection between ans(3,5,2) and ans(4,5,3)
José-Luis
José-Luis le 22 Août 2012
I think i finally got it:
conn = zeros(3,3,3);
conn(2,2,:) = 1;
conn(:,2,2) = 1;
conn(2,:,2) = 1;
CC = bwconncomp(U3,conn); labelmatrix(CC)
ans(:,:,1) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 2
0 0 0 0 2
0 0 0 0 0
ans(:,:,2) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 2
0 1 0 0 0
0 1 0 0 0
ans(:,:,3) =
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
0 0 0 0 3
0 0 0 0 3
Hisham
Hisham le 22 Août 2012
Great...Real you are expert and intelligent. I appreciate your helps.... Thanks so much for your helps.
José-Luis
José-Luis le 22 Août 2012
Modifié(e) : José-Luis le 22 Août 2012
I'm no expert nor intelligent, just stubborn. I learned something new today. I'm liking Matlab answers.
Hisham
Hisham le 22 Août 2012
So, Now how can I stop the "while loop"? Is it by using the same code
while(~stopBool)
[x y z] = size(U3);
condX = sum(sum(U3,3) == z) > 0;
condY = sum(sum(U3,2) == y) > 0;
condZ = sum(sum(U3) == x) > 0;
stopBool = condX || condY || condZ;
end
Or by applying another thing?
Also, if I want to use the same code, I need to defined "stopBool " befor the while loop. What shall I define it please?
Hisham
Hisham le 22 Août 2012
Modifié(e) : Hisham le 22 Août 2012
If I use this example:
U3(:,:,1) = [
0 , 1 , 0 , 1 , 0;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
U3(:,:,2) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 1 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 0
]
U3(:,:,3) = [
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0;
0 , 1 , 0 , 0 , 1;
0 , 0 , 0 , 0 , 0;
0 , 0 , 0 , 0 , 0
]
Then put your code:
conn = zeros(3,3,3);
conn(:,:,2) = 1;
conn(:,2,:) = 1;
conn(2,:,:) = 1;
CC = bwconncomp(U3,conn);
[x y z] = size(U3);
isConnected = false;
while (~isConnected)
%Do your stuff here
for i = CC.PixelIdxList
[sub_x sub_y sub_z] = ind2sub([x y z],cell2mat(i));
if (sum(sub_x==1) && (sub_x==x))
isConnected = true;
end
end
end
The output is error:
Operands to the || and && operators must be convertible to logical scalar values.
Hisham
Hisham le 22 Août 2012
Modifié(e) : Hisham le 22 Août 2012
I think you missed some bracts. The correct is: if ((sum(sub_x==1)) && ((sub_x==x)))
But I have a small question pleas.. If I use more than layer in depth (i.e. U3(:,:,4) , and U3(:,:,5).....U3(:,:,i)
Do I need to make any change in this code:
conn = zeros(3,3,3);
conn(:,:,2) = 1;
conn(:,2,:) = 1;
conn(2,:,:) = 1;
José-Luis
José-Luis le 22 Août 2012
conn = zeros(3,3,3);
conn(:,:,2) = 1;
conn(:,2,:) = 1;
conn(2,:,:) = 1;
CC = bwconncomp(U3,conn);
[x y z] = size(U3);
isConnected = false;
while (~isConnected)
%Do your stuff here
for i = CC.PixelIdxList
[sub_x sub_y sub_z] = ind2sub([x y z],cell2mat(i));
if (~isempty(find(sub_x == 1)) && ~isempty(find(sub_x == x)) )
isConnected = true;
end
end
end
José-Luis
José-Luis le 22 Août 2012
Nope, no changes, unless you want a different connectivity pattern. You can read the documentation:
doc bwconncomp;
Hisham
Hisham le 23 Août 2012
Modifié(e) : Hisham le 23 Août 2012
I would like to thank you for your helps.
I left the last part to explain it to you. If I imagine that the "U3" is represented as a box, and I want to plot the number ones in U3 matrix to see the created path. How can I do it in 3D matrix?
Hisham
Hisham le 23 Août 2012
I downloaded the file from the above link. Then I used this code:
load exampleA.mat
figure
hpat = PATCH_3Darray(gridINPUT,gridX,gridY,gridZ);
But the issue is about how can I put U3 matrix in the code.
Do I need to change "gridINPUT" to "U3"? or how to plot the U£ matrix?
José-Luis
José-Luis le 23 Août 2012
Hisham, I would strongly recommend reading the getting started part of the documentation. grinInput, gridX, gridY, and gridZ are just placeholder variable names that are passed to the function PATCH_3Darray. You can name them whatever you want. In this case, yes, gridINPUT would be U3. Copy/pasting from the function description:
gridX (optional) - A 1xP array - List of the X axis coordinates.
gridY (optional) - A 1xQ array - List of the Y axis coordinates.
gridZ (optional) - A 1xR array - List of the Z axis coordinates.
That means that passing PATCH_3Darray(U3) should be enough to produce some results.
Hisham
Hisham le 23 Août 2012
Modifié(e) : Hisham le 23 Août 2012
I tried the above function but it is suitable for my case. Do you know any function or way to plot similar to the link below?
I did it for 2D by using the following code:
[r,c]=size(U3);
figure
for cIdx=1:c,
y=find(U3(:,cIdx)==1);
if length(y)>1
y=(r+1)-y;
x=ones(size(y))*cIdx;
for idx=1:length(x)-1
if abs( y(idx) - y(idx+1))<=1
line(x(idx:idx+1),y(idx:idx+1),'LineWidth',4)
end
end
hold on
end
end
for rIdx=1:r,
x=find(U3(rIdx,:)==1);
if length(x)>1
y=(r+1)-ones(size(x))*rIdx;
for idx=1:length(x)-1
if abs( x(idx) - x(idx+1))<=1
line(x(idx:idx+1),y(idx:idx+1),'LineWidth',4)
end
end
hold on
end
end
It is very complicated to do it for 3D. Do you know any function able to do it?
Thanks!

Connectez-vous pour commenter.

Azzi Abdelmalek
Azzi Abdelmalek le 21 Août 2012

0 votes

add a condition to your while loop
test=1
while condition1 & test==1
%your program
%if you want exit a loop change the value of test for example
test=0, %any value different from 1

1 commentaire

Hisham
Hisham le 22 Août 2012
It is very nice, but my problem is how can I build the condition that should be valid for a 3D matrix.
can you help me more...please

Connectez-vous pour commenter.

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by