Getting all max, min values of a function as a set of coordinate points

My code only returns 1 set of points for max, min. There are more points based on the graph I provide. This is my code:
clear, clc
syms x y real
y=abs(x^3-9*x); fplot(y, [-5 5])
dy=diff(y); x_cps=solve(dy==0);
y_cps=subs(y,x_cps); y_max=(1); x_max=(1); y_min=(1); x_min=(1);
% % x_cps & y_cps are the critical points
for k=1:length(y_cps)
if y_cps(k)>y_max
y_max=y_cps(k);
x_max=x_cps(k);
elseif y_cps(k)<y_min
y_min=y_cps(k);
x_min=x_cps(k);
end
end
fprintf('(%s,%s)\n',x_max,y_max)
(3^(1/2),6*3^(1/2))
fprintf('(%s,%s)\n',x_min,y_min)
(-3,0)

Risposte (1)

I would use findpeaks
syms x y real
y=abs(x^3-9*x);
[X,Y] = fplot(y, [-5 5]);
Warning: Having two output arguments for fplot will be removed in a future release. Use the XData and YData properties instead.
[pk, loc] = findpeaks(Y,X);
[pkN, locN] = findpeaks(-Y,X);
plot(X,Y,loc,pk,'r*',locN,pkN,'m*')

9 Commenti

I don't have the toolbox to run your code.
Also, you didn't print what those points are.
findpeaks is in the Signal Processing Toolbox. If it is included on your license, you can install it using the Add-Ons Explorer.
The points are captured in variables [pk, loc] and [pkN, locN]. Your question didn't ask how to print them to the screen, but just remove the semicolon at the end fo those lines of code.
Otherwise, your approach is valid. You just need to account for all the points rather than just the first one. Here, I use the 2nd derivative to determine if the point is local min or max.
clear, clc
syms x y real
y=abs(x^3-9*x);
dy=diff(y);
ddy = diff(dy);
x_cps=solve(dy==0)
x_cps = 
y_cps=subs(y,x_cps)
y_cps = 
yddot = subs(ddy,x_cps)
yddot = 
y_max = y_cps(yddot<0)
y_max = 
x_max = x_cps(yddot<0)
x_max = 
y_min = y_cps(yddot>0)
y_min = 
x_min = x_cps(yddot>0)
x_min = 
fprintf('(%s,%s)\n',[x_max';y_max'])
(3^(1/2),6*3^(1/2)) (-3^(1/2),6*3^(1/2))
fprintf('(%s,%s)\n',[x_min';y_min'])
(-3,0) (0,0) (3,0)
You will need Symbolic Math Toolbox to use the syms function, but you could use the islocalmin and islocalmax functions from MATLAB instead of findpeaks from Signal Processing Toolbox.
First plot the function and retrieve the coordinate data:
syms x y real
y=abs(x^3-9*x);
h = fplot(y, [-5 5]);
xdata = h.XData;
ydata = h.YData;
Find and plot the local minima. You would repeat these lines but replace islocalmin with islocalmax to find the local maxima.
isLocalMinimum = islocalmin(ydata, SamplePoints=xdata);
hold on
xminima = xdata(isLocalMinimum)
xminima = 1×3
-2.9998 0 2.9999
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
yminima = ydata(isLocalMinimum)
yminima = 1×3
0.0043 0 0.0013
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
plot(xminima, yminima, 'o')
I added a bit more to your code and it runs great. Thank you.
disp('The local minimums are:')
for k=1:length(xminima)
fprintf('(%.2f,%.2f)\n',xminima(k),yminima(k))
end
disp('The local maximums are:')
for k=1:length(xmaxima)
fprintf('(%.2f,%.2f)\n',xmaxima(k),ymaxima(k))
end
You don't need a for loop, as I showed above.
syms x y real
y=abs(x^3-9*x);
h = fplot(y, [-5 5]);
xdata = h.XData;
ydata = h.YData;
isLocalMinimum = islocalmin(ydata, SamplePoints=xdata);
hold on
xminima = xdata(isLocalMinimum);
yminima = ydata(isLocalMinimum);
plot(xminima, yminima, 'o')
disp('The local minimums are:')
The local minimums are:
fprintf('(%.2f,%.2f)\n',[xminima;yminima])
(-3.00,0.00) (0.00,0.00) (3.00,0.00)
Great. Didn't know you could use fprintf that way.
You need to be careful when using fprintf() with multiple arguments that are non-scalar. fprintf() "consumes" all of the first parameter before moving on to all of the second parameter, and does so "down" columns first. That is why @Cris LaPierre constructed [xminima;yminima] which is two row vectors stacked on top of each other: going "down" the columns is picking out first an x and then a y, then back to the next x and the next y. The code as-is would not work properly if xminima and yminima started out as column vectors.

@ Steven Lord: Can we find intervals of increasing & decreasing with the code you have? That'd be awesome.

No, you cannot find intervals of increasing and decreasing with the code posted by @Steven Lord -- not without stripping down to all but the first 5 lines and then adding notable additional code.

Accedi per commentare.

Categorie

Prodotti

Release

R2021a

Richiesto:

il 6 Mag 2025

Community Treasure Hunt

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

Start Hunting!

Translated by