help with nested loop and plot

hello everyone, i need help with the following code.
i am trying to plot the boundary of the region that satisfies the following conditions:
solve and plot for x and y
x+y+e+t>=0
And
x*y-e*t>=0
where x and y are the two variables while e and t are two constants whose values has to vary in a range.
so far i have got (which is working fine for fixed e and t):
n= 101;
x = linspace(-100, 100, n);
y = linspace(-100, 100, n);
[X, Y] = meshgrid(x, y);
Z = zeros(n, n);
e= 10;
t=-25;
B = X + Y + e + t;
D = X.*Y - e.*t;
for i= 1:n
for j= 1:n
if B(i,j) >= 0
Z(i,j) = D(i,j);
else
Z(i,j) = -1;
end
end
end
v = [0,0];
contour(X,Y,Z,v, 'LineWidth', 1.5)
grid on
axis equal
xline(0, 'Color', 'k', 'LineWidth', 0.5);
yline(0, 'Color', 'k', 'LineWidth', 0.5);
now i would like to see the effects of the two constants e and t on the above mentioned boundary. i would like to plot different curves with varying e and t on the same graph but i am having troubles to understand an efficient way to do it.
e and t are two arrays such as linspace(-25, 25, 3), so i want to check how the plot evolves over 3x3 combiations of e and t.
i tried nesting for loops but it didn't work as i got a blank plot. could anybody please give me any suggestions as to do it with for loops or with any other way?
i know i could do it "manually", changing e and t every time and using hold on to plot the curves on the same figure but it is rather inefficient.
thanks to anyone who will help

 Risposta accettata

Here's another way, still using nested loops:
n= 101;
x = linspace(-100, 100, n);
y = linspace(-100, 100, n);
[X, Y] = meshgrid(x, y);
figure
xline(0, 'Color', 'k', 'LineWidth', 0.5);
yline(0, 'Color', 'k', 'LineWidth', 0.5);
hold on
for e = -25:10:25
for t = -25:10:25
Z = fn(X,Y,e,t,n);
v = [0,0];
contour(X,Y,Z,v, 'LineWidth', 1.5)
end
end
grid on
axis equal
function Z = fn(X,Y,e,t,n)
Z = zeros(n, n);
B = X + Y + e + t;
D = X.*Y - e.*t;
for i= 1:n
for j= 1:n
if B(i,j) >= 0
Z(i,j) = D(i,j);
else
Z(i,j) = -1;
end
end
end
end

9 Commenti

thank you very much, it is what i was looking for.
is there a way to make the different curves in different colors?
Here's a quick and dirty way:
n= 101;
x = linspace(-100, 100, n);
y = linspace(-100, 100, n);
[X, Y] = meshgrid(x, y);
clrs = ['r','g','b','c','m','y'];
figure
xline(0, 'Color', 'k', 'LineWidth', 0.5);
yline(0, 'Color', 'k', 'LineWidth', 0.5);
hold on
c = 0;
for e = -25:10:25
for t = -25:10:25
c = c+1;
Z = fn(X,Y,e,t,n);
v = [0,0];
c = mod(c,5)+1;
contour(X,Y,Z,v, 'LineWidth', 1.5,'LineColor', clrs(c))
end
end
grid on
axis equal
function Z = fn(X,Y,e,t,n)
Z = zeros(n, n);
B = X + Y + e + t;
D = X.*Y - e.*t;
for i= 1:n
for j= 1:n
if B(i,j) >= 0
Z(i,j) = D(i,j);
else
Z(i,j) = -1;
end
end
end
end
thank you very much
Torsten
Torsten il 3 Lug 2024
Modificato: Torsten il 3 Lug 2024
You must have at least 6x7/2 = 21 different colors for your nested loop over e and t ...
hi, sorry to bother you again.
i slightly changed the code to try and create a legend and to make it more readable with subplots. problem is the colors and the legend don't match the lines in the graphs.
would you be so kind to take a look and help me find the mistake? thank you
n = 1001;
x = linspace(-100, 100, n);
y = linspace(-100, 100, n);
[X, Y] = meshgrid(x, y);
clr = ['r','g','b','c','k'];
a = 4;
e = [-50 -10 0 50];
t = linspace(-50, 50, 5);
LegendsStrings = cell(length(t),1);
for q = 1:a
for r = 1:5
Z = fn(X, Y, e(q), t(r), n);
subplot(2, 2, q)
xline(0, 'Color', 'k', 'LineWidth', 0.5);
yline(0, 'Color', 'k', 'LineWidth', 0.5);
hold on
v = [0, 0];
contour(X, Y, Z, v, 'LineWidth', 1.5, 'LineColor', clr(r))
xlabel('x')
ylabel('y')
title("e = " + e(q))
grid on
axis equal
hold off
LegendsStrings{r} = ['t = ', num2str(t(r))];
end
legend(LegendsStrings, 'Interpreter', 'none')
end
Here's a possibility (though there is probably a much better one!). Note that I've just used n = 101 here for speed. You can change this to whatever you want.
n = 101;
x = linspace(-100, 100, n);
y = linspace(-100, 100, n);
[X, Y] = meshgrid(x, y);
clr = ['r','g','b','c','k'];
v = [0, 0];
a = 4;
e = [-50 -10 0 50];
t = linspace(-50, 50, 5);
% LegendsStrings = cell(length(t),1);
for q = 1:a
for r = 1:5
Z = fn(X, Y, e(q), t(r), n);
subplot(2, 2, q)
xline(0, 'Color', 'k', 'LineWidth', 0.5);
yline(0, 'Color', 'k', 'LineWidth', 0.5);
hold on
contour(X, Y, Z, v, 'LineWidth', 1.5, 'LineColor', clr(r))
xlabel('x')
ylabel('y')
title("e = " + e(q))
xp = [-95, -80]; yp = (-30-12*r)*ones(1,2);
plot(xp,yp,['-',clr(r)])
text(xp(2)+5, yp(2),['t = ', num2str(t(r))],'FontSize',8)
grid on
axis equal
hold off
end
end
function Z = fn(X,Y,e,t,n)
Z = zeros(n, n);
B = X + Y + e + t;
D = X.*Y - e.*t;
for i= 1:n
for j= 1:n
if B(i,j) >= 0
Z(i,j) = D(i,j);
else
Z(i,j) = -1;
end
end
end
end
thank you, it works well.
i don't understand why you create the two arrays xp and yp, though.
"...i don't understand why you create the two arrays xp and yp, though."
Comment them out and see what happens!
Incidentally, you could eliminate the need for your function fn, by using Matlab's indexing capabilities:
n = 101;
x = linspace(-100, 100, n);
y = linspace(-100, 100, n);
[X, Y] = meshgrid(x, y);
clr = ['r','g','b','c','k'];
v = [0, 0];
a = 4;
e = [-50 -10 0 50];
t = linspace(-50, 50, 5);
for q = 1:a
for r = 1:5
% the following three lines replace the need for the function
B = X + Y + e(q) + t(r);
Z = X.*Y - e(q).*t(r);
Z(B<0) = -1;
subplot(2, 2, q)
xline(0, 'Color', 'k', 'LineWidth', 0.5);
yline(0, 'Color', 'k', 'LineWidth', 0.5);
hold on
contour(X, Y, Z, v, 'LineWidth', 1.5, 'LineColor', clr(r))
xlabel('x')
ylabel('y')
title("e = " + e(q))
xp = [-95, -80]; yp = (-30-12*r)*ones(1,2); % coordinates for "legend" lines
plot(xp,yp,['-',clr(r)]) % "legend" lines
text(xp(2)+5, yp(2),['t = ', num2str(t(r))],'FontSize',8) % "legend" text
grid on
axis equal
hold off
end
end
i understand it more now. thank you for thaking time to answer my questions. i have been using matlab for the last month so it's nice when someone explains "tricks" to make code more efficient.
thank you very much

Accedi per commentare.

Più risposte (1)

Aquatris
Aquatris il 2 Lug 2024
Modificato: Aquatris il 2 Lug 2024
Here is one simple dirty way:
n= 101;
x = linspace(-100, 100, n);
y = linspace(-100, 100, n);
[X, Y] = meshgrid(x, y);
Z = zeros(n, n);
cnt = 0;
% this nested loop can probably be vectorized
for e = 8:12
for t = -27:-24
cnt = cnt+1;
B = X + Y + e + t;
D = X.*Y - e.*t;
% find indeces where both conditions hold
idx = find(B >= 0 & D>=0);
% store points that satisfy both conditions
Xsol{cnt} = X(idx);
Ysol{cnt} = Y(idx);
lgdText{cnt} = (sprintf('e = %d, t = %d',e,t));
end
end
for i = 1:length(Xsol)
plot(Xsol{i},Ysol{i},'.')
hold on
end
xlabel('X')
ylabel('Y')
xlim([-100 100])
ylim([-100 100])
legend(lgdText)
title('Points that satisfy both conditions')
hold off

Community Treasure Hunt

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

Start Hunting!

Translated by