You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
if and else loop problem
1 view (last 30 days)
Show older comments
if (loop==false && centre(ii,1)<95 )
centre(ii,:) = centre(ii,:)+ [0.1 0];
elseif (loop==false && centre(ii,2)<95)
centre(ii,:) = centre(ii,:)+ [0 0.1];
elseif (loop==false && centre(ii,1)>5)
centre(ii,:) = centre(ii,:)- [0.1 0];
elseif (loop==false && centre(ii,2)>5)
centre(ii,:) = centre(ii,:)- [0 0.1];
else
break
end
Lets's say centre(ii,1)=94.95, then the first if increases it to 95.05.
As soon as centre(ii,1)=95.05, the third condition makes it again 94.95 and the process continues. I want, once the first condition is achieved i.e. x>95, it should go to third condition. The similar case is for 2nd and 4th condition. How to do this?
19 Comments
Voss
on 26 Dec 2021
"As soon as centre(ii,1)=95.05, the third condition makes it again 94.95 and the process continues."
The earliest the third condition would be checked is the next time through the loop (I know code is within a loop because of the break statement, but it is not clear whether the rest of the loop ever changes the values of any of the relevant variables). If you want it to be truly "as soon as" centre(ii,1)=95.05, you would split the conditions into separate if blocks.
However, it's not clear how what you want is different from what you have. Can you please give a concrete example of how the variable centre should be changing each time through the loop?
CHANDRABHAN Singh
on 28 Dec 2021
Dear Benjmin thank you for yur response and sprry for the delay. I modified the loop as shown below. If you have better idea please share.
jj=1;
if (loop==false && centre(ii,1)<95 && jj==1 )
centre(ii,:) = centre(ii,:)+ [0.1 0];
if centre(ii,1)>95
jj=2;
end
elseif (loop==false && centre(ii,2)<95 && jj==2)
centre(ii,:) = centre(ii,:)+ [0 0.1];
if centre(ii,2)>95
jj=3;
end
elseif (loop==false && centre(ii,1)>5 && jj=3)
centre(ii,:) = centre(ii,:)- [0.1 0];
if centre(ii,1)<5
jj=4;
end
elseif (loop==false && centre(ii,2)>5 && jj==4)
centre(ii,:) = centre(ii,:)- [0 0.1];
if centre(ii,2)<5
jj=5;
end
elseif (jj==5)
break
end
Walter Roberson
on 28 Dec 2021
elseif (loop==false && centre(ii,1)>5 && jj=3)
The jj=3 would have to be jj==3
Voss
on 28 Dec 2021
@CHANDRABHAN Singh Take a look at this:
x = 1;
if x == 1
x = 2;
elseif x == 2
x = 3;
end
display(x);
x = 2
Compared to this:
x = 1;
if x == 1
x = 2;
end
if x == 2
x = 3;
end
display(x);
x = 3
Are those values of x what you expect?
In your code, you set jj = 1 at the top, so that any if or elseif condition of the form "(jj == something that's not 1) && (some other stuff)" will always be false because "jj == something that's not 1" will be false because jj == 1. In other words, all but the first condition (i.e., all the elseif's) are unnecessary. I don't imagine that this is what you intend, but since I don't know what you intend, I'll take a shot in the dark and say, try this and see if it does what you want:
jj=1;
if (loop==false && centre(ii,1)<95 && jj==1 )
centre(ii,:) = centre(ii,:)+ [0.1 0];
if centre(ii,1)>95
jj=2;
end
end
if (loop==false && centre(ii,2)<95 && jj==2)
centre(ii,:) = centre(ii,:)+ [0 0.1];
if centre(ii,2)>95
jj=3;
end
end
if (loop==false && centre(ii,1)>5 && jj==3)
centre(ii,:) = centre(ii,:)- [0.1 0];
if centre(ii,1)<5
jj=4;
end
end
if (loop==false && centre(ii,2)>5 && jj==4)
centre(ii,:) = centre(ii,:)- [0 0.1];
if centre(ii,2)<5
jj=5;
end
end
if (jj==5)
break
end
CHANDRABHAN Singh
on 29 Dec 2021
Edited: Walter Roberson
on 29 Dec 2021
@Benjamin, I am posting the complete code. This code generates meso model of concrete which gives random radius and centre of aggregate. I will delete this comment after your observation.
%% This is for generating the circular aggregate %%
xmin = 5; xmax = 45;
%ymin = 5; ymax = 95;
%the function "randnum" for generating random number is saved in the directory
n = 20;
centre = zeros(n,2);
r = zeros(n,1);
centre(1,:) = xmin + rand(1,2).*(xmax-xmin);
r(1) = (4.75 + rand(1)*(10-4.75))/2;
t = 2*pi.*linspace(0,1,50);
plot(r(1).*sin(t)+centre(1,1),r(1).*cos(t)+centre(1,2));
no_of_agg=1;
%% Condition that no circle should overlap %
%This loop has to start with ii= 2 because the r(1) has been obtained in the
%previous section
% this is defined to be used in the conditional statement if else
for ii =2:35
jj = 1;
eta1 = randnum;
eta2 = randnum;
centre(ii,:) = xmin + ([eta1 eta2]).*(xmax-xmin);
% cx and cy are defined to control the if else loop at the end for
% shifting of the centre of the aggregate
cx=centre(ii,1);
cy = centre(ii,2);
loop = 0;
r(ii) = (4.75 + randnum*(10-4.75))/2;
% the p matrix is a condition employed to chech the two circles do not
% intersect
while (loop==0)
p=zeros(ii,ii);
for m = 1:ii
p(m,m)=1;
for n = (m+1):ii
p(n,n)=1;
p(m,n)=(1.1*(r(m)+r(n))< sqrt((centre(m,1)-centre(n,1))^2+ (centre(m,2)-centre(n,2))^2 ) );
p(n,m)=(1.1*(r(m)+r(n))< sqrt((centre(m,1)-centre(n,1))^2+ (centre(m,2)-centre(n,2))^2 ) );
end
% while loop parameter is loop and is checked where loop is
% equal to 1 or not
loop = all(all(p));
end
if (loop==false && centre(ii,1)<45 && jj==1)
disp('loop1')
centre(ii,:) = centre(ii,:)+ [0.1 0]
if (centre(ii,1)>45)
jj=2;
end
elseif (loop==false && centre(ii,2)<45 && jj==2)
centre(ii,1)=5;
disp('loop2')
centre(ii,:) = centre(ii,:)+ [0 0.1]
jj=1;
if centre(ii,2)>45
centre(ii,2)=cy;
centre(ii,1) =cx;
jj=3;
end
elseif (loop==false && centre(ii,1)>5 && jj==3 )
disp('loop3')
centre(ii,:) = centre(ii,:)-[0.1, 0]
if (centre(ii,1)<5)
jj=4;
end
elseif (loop==false && centre(ii,2)>5 && jj==4 )
centre(ii,1)=45;
disp('loop4')
centre(ii,:) = centre(ii,:)-[0, 0.1]
jj=3;
if (centre(ii,2)<5)
jj=5;
end
elseif (loop==false && jj==5)
r(ii)=r(ii)-0.1;
centre(ii,:)=[cx, cy];
jj=1;
disp('radius')
if (r(ii)<(4.5/2))
jj=6;
end
elseif (jj==6)
break
end
end
if (loop==true)
no_of_agg=no_of_agg+1;
plot(r(ii).*sin(t)+centre(ii,1),r(ii).*cos(t)+centre(ii,2));
end
end
Unrecognized function or variable 'randnum'.
Voss
on 29 Dec 2021
Maybe try this:
% %% This is for generating the circular aggregate %%
xmin = 5; xmax = 45;
%ymin = 5; ymax = 95;
%the function "randnum" for generating random number is saved in the directory
n = 20;
centre = zeros(n,2);
r = zeros(n,1);
centre(1,:) = xmin + rand(1,2).*(xmax-xmin);
r(1) = (4.75 + rand(1)*(10-4.75))/2;
t = 2*pi.*linspace(0,1,50);
figure
hold on
plot(r(1).*sin(t)+centre(1,1),r(1).*cos(t)+centre(1,2));
no_of_agg=1;
% %% Condition that no circle should overlap %
%This loop has to start with ii= 2 because the r(1) has been obtained in the
%previous section
% this is defined to be used in the conditional statement if else
for ii =2:n
jj = 1;
% eta1 = randnum;
% eta2 = randnum;
eta1 = rand;
eta2 = rand;
centre(ii,:) = xmin + ([eta1 eta2]).*(xmax-xmin);
% cx and cy are defined to control the if else loop at the end for
% shifting of the centre of the aggregate
cx = centre(ii,1);
cy = centre(ii,2);
loop = 0;
% r(ii) = (4.75 + randnum*(10-4.75))/2;
r(ii) = (4.75 + rand*(10-4.75))/2;
% the p matrix is a condition employed to chech the two circles do not
% intersect
while (loop==0)
p=zeros(ii,ii);
for m = 1:ii
p(m,m)=1;
for n = (m+1):ii
p(n,n)=1;
p(m,n)=(1.1*(r(m)+r(n))< sqrt((centre(m,1)-centre(n,1))^2+ (centre(m,2)-centre(n,2))^2 ) );
% p(n,m)=(1.1*(r(m)+r(n))< sqrt((centre(m,1)-centre(n,1))^2+ (centre(m,2)-centre(n,2))^2 ) );
p(n,m) = p(m,n);
end
end
% while loop parameter is loop and is checked where loop is
% equal to 1 or not
loop = all(p(:));
if (loop==false && centre(ii,1)<45 && jj==1)
% disp('loop1')
centre(ii,:) = centre(ii,:)+ [0.1 0];
if (centre(ii,1)>45)
jj=2;
end
end
if (loop==false && centre(ii,2)<45 && jj==2)
centre(ii,1)=5;
% disp('loop2')
centre(ii,:) = centre(ii,:)+ [0 0.1];
jj=1;
if centre(ii,2)>45
centre(ii,2)=cy;
centre(ii,1) =cx;
jj=3;
end
end
if (loop==false && centre(ii,1)>5 && jj==3 )
% disp('loop3')
centre(ii,:) = centre(ii,:)-[0.1, 0];
if (centre(ii,1)<5)
jj=4;
end
end
if (loop==false && centre(ii,2)>5 && jj==4 )
centre(ii,1)=45;
% disp('loop4')
centre(ii,:) = centre(ii,:)-[0, 0.1];
jj=3;
if (centre(ii,2)<5)
jj=5;
end
end
if (loop==false && jj==5)
r(ii)=r(ii)-0.1;
centre(ii,:)=[cx, cy];
jj=1;
% disp('radius')
if (r(ii)<(4.5/2))
jj=6;
end
end
if (jj==6)
break
end
end
if (loop==true)
no_of_agg=no_of_agg+1;
plot(r(ii).*sin(t)+centre(ii,1),r(ii).*cos(t)+centre(ii,2));
end
end
Walter Roberson
on 29 Dec 2021
I am not sure what the question is?
If I make randnum() the same as rand(), and I comment out the disp() and I put semi-colons at the end of assignments to centre(), and I put
title("agg = " + no_of_agg);
drawnow();
after the plot() call...
then I do get progressive output. Some iterations take longer than others. I am up to agg = 30 so far.
CHANDRABHAN Singh
on 30 Dec 2021
@Walter Roberson rand does not include 0 but randnum does.
CHANDRABHAN Singh
on 30 Dec 2021
randnum = randi ( [ 0 4294967295 ] ) / 4294967296.0;
CHANDRABHAN Singh
on 30 Dec 2021
@Benjamin I have two questions.
- Why did you use 'figure' command before 'plot' command?
- Is loop = all(p(:)) better then all(all(p))? If yes, how?
CHANDRABHAN Singh
on 30 Dec 2021
@Walter Roberson This program is used to generate non-overlapping aggregates (random location and random radius, in between the given limit). Then this information will be imported to ansys for geometrical modeling. This is just a initial phase. So, i want my program to be concise and accurate.
Voss
on 30 Dec 2021
1.) figure() is used to make a new figure for the plots to come (basically a clean slate so I'm not accidentally plotting to an existing figure, leading to unintended results)
2.) all(p(:)) is better than all(all(p)) stylistically (to me) because it's simpler (and I wouldn't be surprised if it's slightly faster, but I don't know that for sure), but the main reason all(p(:)) is better is because it works for any dimensionality of p. Say you had some code that used all(all(p)) to find whether all elements of a 2D matrix were non-zero. But then six months after you wrote it, the code needed to be upgraded to handle p being a 3D matrix. You would have to be sure to change that all(all(p)) to all(all(all(p))), and there may be many such instances in your code, so you better not miss any! On the other hand, if you use all(p(:)) you don't have to touch it; it works for 2D, 3D, 4D, ...
Walter Roberson
on 30 Dec 2021
"Why did you use 'figure' command before 'plot' command?"
When you figure() in that place, you can be sure that you have an empty figure, and you can be sure that the "hold on" that follows right after the figure() call will not be accidentally holding anything that might have previously be in the display. Another way to achieve the same thing would have been to call cla() instead of figure()
"Is loop = all(p(:)) better then all(all(p))? If yes, how?"
Although technically speaking p(:) involves a call, in the special case that p is numeric and not complex, the (:) operation is the fastest operation in MATLAB (other than constants and assignment of a complete variable to another complete variable.) The (:) operation only requires bashing the shape information but keeping the data pointer; no data needs to be copied at all for it. Then the all() call is working on a vector of all of the elements and can process everything at the same time to come up with a single answer.
The alternative, all(all(p)) requires two calls to all(), with the inner call having to produce one result per column. Although part of that can potentially be run on other cores, producing and saving the partial results is more work than just producing one result. Especially since, in theory, all() could abort processing as soon as it hit a single value that is 0.
Walter Roberson
on 30 Dec 2021
"So, i want my program to be concise and accurate."
Okay, but that is not a question. What are you asking us to do for you?
CHANDRABHAN Singh
on 30 Dec 2021
Can it be done in a much better way? Or is this fine?
Walter Roberson
on 30 Dec 2021
switch() would probably be better.
But I suspect that you can be more efficient.
Consider the way that you build p. Suppose that on round 4 you create p(2,4) . And suppose that loop is false that time, so you loop back and re-create p . Now, under what circumstances can the just-recalculated p(2,4) be different than the p(2,4) that you calculated the previous time? Okay, now suppose that you get through and loop becomes true, and you make it through to the next ii value, and you go to rebuild p again. You get to the point where you are going to rebuild p(2,4) . Under what circumstances can the outcome be different than the time you last built p(2,4) for the previous ii value?
I suspect that if you map the flow out, that you will find that you can calculate how far you are going to have to move centre(ii,:) . And as each state is associated with a direction vector, you might even be able to calculate how many iterations within that state are going to be needed to get to the point where you switch states.
Your while loop is determininstic, and that means that instead of looping all the time, you should be able to directly calculate what you need to do in order to change state.
CHANDRABHAN Singh
on 4 Jan 2022
Edited: CHANDRABHAN Singh
on 4 Jan 2022
@Benjamin, @Walter Roberson, I have further modifeid the code as shown below. Now, the aggregates are not circular rather they are polygons of sides 3 -10 (number of sides is random). The condition for non intersecting circles was easy. But this time i want the condition for non-intersection polygons, but the circles can intersect. Currently, i have no idea how this can be done.
Can you do little help in this regards? I am posting the code below. The function is also attached. Currently the while loop ensures that no circle intesects.
xmin = 5; xmax = 45;
%ymin = 5; ymax = 95;
%the function "randnum" for generating random number is saved in the directory
n = 20;
centre = zeros(n,2);
r = zeros(n,1);
centre(1,:) = xmin + rand(1,2).*(xmax-xmin);
% 14.67 is used based on the elongation index
r(1) = (4.75 + rand(1)*(14.67-4.75))/2;
% random_aggregate_generation is a function for aggregate generation
random_aggregate_generation(r(1),centre(1,1),centre(1,2));
%t = 2*pi.*linspace(0,1,50);
%plot(r(1).*sin(t)+centre(1,1),r(1).*cos(t)+centre(1,2));
no_of_agg=1;
%% Condition that no circle should overlap %
%This loop has to start with ii= 2 because the r(1) has been obtained in the
%previous section
% this is defined to be used in the conditional statement if else
for ii =2:30
jj = 1;
eta1 = randnum;
eta2 = randnum;
centre(ii,:) = xmin + ([eta1 eta2]).*(xmax-xmin);
% cx and cy are defined to control the if else loop at the end for
% shifting of the centre of the aggregate
cx=centre(ii,1);
cy = centre(ii,2);
loop = 0;
r(ii) = (4.75 + randnum*(7.335-4.75))/2;
% the p matrix is a condition employed to chech the two circles do not
% intersect
while (loop==0)
p=zeros(ii,ii);
for m = 1:ii
p(m,m)=1;
for n = (m+1):ii
p(n,n)=1;
p(m,n)=(1.05*(r(m)+r(n))< sqrt((centre(m,1)-centre(n,1))^2+ (centre(m,2)-centre(n,2))^2 ) );
p(n,m)=p(m,n);
end
% while loop parameter is loop and is checked where loop is
% equal to 1 or not
loop = all(p(:));
end
if (loop==false && centre(ii,1)<45 && jj==1)
disp('loop1')
centre(ii,:) = centre(ii,:)+ [0.1 0];
if (centre(ii,1)>45)
jj=2;
end
elseif (loop==false && centre(ii,2)<45 && jj==2)
centre(ii,1)=5;
disp('loop2')
centre(ii,:) = centre(ii,:)+ [0 0.1];
jj=1;
if centre(ii,2)>45
centre(ii,2)=cy;
centre(ii,1) =cx;
jj=3;
end
elseif (loop==false && centre(ii,1)>5 && jj==3 )
disp('loop3')
centre(ii,:) = centre(ii,:)-[0.1, 0];
if (centre(ii,1)<5)
jj=4;
end
elseif (loop==false && centre(ii,2)>5 && jj==4 )
centre(ii,1)=45;
disp('loop4')
centre(ii,:) = centre(ii,:)-[0, 0.1];
jj=3;
if (centre(ii,2)<5)
jj=5;
end
elseif (loop==false && jj==5)
r(ii)=r(ii)-0.1;
centre(ii,:)=[cx, cy];
jj=1;
disp('radius')
if (r(ii)<(4.5/2))
jj=6;
end
elseif (jj==6)
break
end
end
if (loop==true)
no_of_agg=no_of_agg+1;
%plot(r(ii).*sin(t)+centre(ii,1),r(ii).*cos(t)+centre(ii,2));
random_aggregate_generation(r(ii),centre(ii,1),centre(ii,2));
end
end
%% The function - The sides of the aggreagte is in between 4 and 10 %%%
function [] = random_aggregate_generation(radius,centre_x,centre_y)
% This is for checking the function if necessary
%radius = 1.8*4;centre_x = 0; centre_y= 0;
number=randi([4 10]);
randum = rand(1,number);
theta = 2*pi.*(randum./sum(randum));
t = zeros(1,number);
t(1)=theta(1);
for i=2:number
t(i)=theta(i)+t(i-1);
end
rad_plot = radius.*ones(1,number);
t(number+1)=t(1);
% This is for rotating the aggregate randomly so that one corner is not
% fixed at t = 0
t = t + randi(259);
rad_plot(number+1)=rad_plot(1);
[x, y] = pol2cart(t,rad_plot);
% for elongation index
%% Check for the elongation index, the largesr size of the aggregate should be less than 1.8*d_mean
% d_mean = (10+6.3)/2 anf the elongation index is checked for rad_plot>3.15
% (or diameter = 6.3mm)
%if rad_plot>3.15
% distance = zeros((numel(x)-2),numel(x)-2);
% for jj = 1:(numel(x)-1)
% for kk=1:(numel(x)-1)
% distance(jj,kk) = sqrt( (x(jj)-x(kk))^2 +(y(jj)-y(kk))^2);
% end
% end
%largest_dim = 14.67>max(distance(:));
%if largest_dim==true
% polarplot(t,rad_plot);
%end
%else
% polarplot(t,rad_plot);
%end
%%
plot(x+centre_x,y+centre_y);
%end
Walter Roberson
on 4 Jan 2022
Maybe use polyshape() objects and intersect() ?
CHANDRABHAN Singh
on 5 Jan 2022
@Walter Roberson, thank you for your kind support.
Let's say
these are two non interscting ploygons (shown below). How can i get a logical relationship out of this. Something like, if the polygons intersect or touch
paramter = true;
otherwise
parameter = false;
x1 =[-2.6967 -2.0891 -0.0846 1.5544 2.6872 -2.6967];
x2 = [5.6494 6.6386 6.6898 4.0313 1.3002 1.9802 5.6494];
y1 = [ 0.1340 -1.7104 -2.6987 -2.2076 -0.2624 0.1340];
y2 = [1.8624 3.4274 4.2346 6.6998 3.9686 2.2082 1.8624];
plot(x1,y1,x2,y2);
grid on;
poly1 = polyshape(x1',y1');
poly2 = polyshape(x2',y2');
polyout = intersect(poly1,poly2);
Answers (1)
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)