How to fill a variable with the results of an if...elseif statement
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I am trying to apply the second derivative test to a function and find all the relative maxima, minima, saddlepoints, and inconclusive results from the function's critical points. I think I have my code where I want it, but my fmin, fmax, and saddlePts should have more than just one point (x,y) stored. I'm quite sure that each time a condition is met in the if...elseif statement, that the previous point store is getting overwritten, which results in just last indice to meet the criteria being stored.
How can I get all the 9 points to be stored properly in the if...elseif statement? I.e. How to a prevent the overwriting, and allow fmin, fmax, and saddlePts to be filled with more than one point?
% Using MATLAB, find and evaluate all maxima, minima, and saddle points of
% the function f(x,y)= x*y*(x^2+y^2-2.56).
clear
clc
syms x y % Initiate SYMBOLIC MATH
% Find fist-order partial derivative: fx and fy.
f(x,y)= x*y*(x^2+y^2-2.56);
fx = simplify(diff(f,x)); fy = simplify(diff(f,y));
% Set fx and fy equal to zero and solve for critical points. Save x and y
% values as xcrit and ycrit.
S = solve(fx,fy);
xcrit = S.x; ycrit = S.y;
% Find second-order partial derivatives: fxx, fyy, and fxy.
fxx = simplify(diff(fx,x));
fyy = simplify(diff(fy,y));
fxy = simplify(diff(fx,y));
% Perform a second-order derivative test of each critical point. Label and
% store all maximum, minimum, and saddle points based on criteria:
% If D>0 and fxx(Xc,Yc)>0, then f has a relative minimum at (Xc,Yc).
% If D>0 and fxx(Xc,Yc)>0, then f has a relative maximum at (Xc,Yc).
% If D<0, then f has a saddle point at (Xc,Yc).
% If D=0, then the test is inconclusive.
% Minimums are store as fmin, maximums as fmax, saddle points as saddlePts,
% and inconclusives as inconcl.
Xc = double(xcrit); Yc = double(ycrit);
for ind = 1:9
D=fxx(Xc(ind),Yc(ind))*fyy(Xc(ind),Yc(ind)) - (fxy(Xc(ind),Yc(ind)))^2;
if D > 0 && fxx(Xc(ind),Yc(ind)) > 0
fmin = [Xc(ind) Yc(ind)];
elseif (D > 0) && (fxx(Xc(ind),Yc(ind)) < 0)
fmax = [Xc(ind) Yc(ind)];
elseif (D < 0)
saddlePts = [Xc(ind) Yc(ind)];
elseif (D == 0)
inconcl = [Xc(ind) Yc(ind)];
end
end
% Print relative minimums and maximums, saddle points, and inconclusives.
L = exist('fmin'); K = exist('fmax'); H = exist('saddlePts');
G = exist('inconcl');
fprintf('f(x,y) = %s\n\n', simplify(f));
disp('f has a relative minimum at the following points:');
if (L ~= 0)
disp(array2table(fmin, 'VariableNames', {'x', 'y'})); disp(' ');
else
disp('None'); disp(' ');
end
disp('f has a relative maximum at the following points:');
if (K ~= 0)
disp(array2table(fmax, 'VariableNames', {'x', 'y'})); disp(' ');
else
disp('None'); disp(' ');
end
disp('f has a saddle point at the following points:');
if (H~=0)
disp(array2table(saddlePts, 'VariableNames', {'x', 'y'})); disp(' ');
else
disp('None'); disp(' ');
end
disp('The 2nd derivative test was inconclusive for the following points:');
if (G ~=0)
disp(array2table(inconcl, 'VariableNames', {'x', 'y'})); disp(' ');
else
disp('None');
end
0 commentaires
Réponse acceptée
Torsten
le 1 Oct 2024
Modifié(e) : Torsten
le 1 Oct 2024
Use
imin = 0;
imax = 0;
isaddlePts = 0;
iinconcl = 0;
for ind = 1:9
D=fxx(Xc(ind),Yc(ind))*fyy(Xc(ind),Yc(ind)) - (fxy(Xc(ind),Yc(ind)))^2;
if D > 0 && fxx(Xc(ind),Yc(ind)) > 0
imin = imin + 1;
fmin(imin,:) = [Xc(ind) Yc(ind)];
elseif (D > 0) && (fxx(Xc(ind),Yc(ind)) < 0)
imax = imax + 1;
fmax(imax,:) = [Xc(ind) Yc(ind)];
elseif (D < 0)
isaddlePts = isaddlePts + 1;
saddlePts(isaddlePts,:) = [Xc(ind) Yc(ind)];
elseif (D == 0)
iinconcl = iinconcl + 1;
inconcl(iinconcl,:) = [Xc(ind) Yc(ind)];
end
end
Plus de réponses (1)
Steven Lord
le 1 Oct 2024
Rather than creating variables whose number of rows is not known ahead of time, I'd consider creating a table of coordinates and have one or more variables in that table indicating what it is.
% Using MATLAB, find and evaluate all maxima, minima, and saddle points of
% the function f(x,y)= x*y*(x^2+y^2-2.56).
syms x y % Initiate SYMBOLIC MATH
% Find fist-order partial derivative: fx and fy.
f(x,y)= x*y*(x^2+y^2-2.56);
fx = simplify(diff(f,x)); fy = simplify(diff(f,y));
% Set fx and fy equal to zero and solve for critical points. Save x and y
% values as xcrit and ycrit.
S = solve(fx,fy);
xcrit = S.x; ycrit = S.y;
% Find second-order partial derivatives: fxx, fyy, and fxy.
fxx = simplify(diff(fx,x));
fyy = simplify(diff(fy,y));
fxy = simplify(diff(fx,y));
% Perform a second-order derivative test of each critical point. Label and
% store all maximum, minimum, and saddle points based on criteria:
% If D>0 and fxx(Xc,Yc)>0, then f has a relative minimum at (Xc,Yc).
% If D>0 and fxx(Xc,Yc)>0, then f has a relative maximum at (Xc,Yc).
% If D<0, then f has a saddle point at (Xc,Yc).
% If D=0, then the test is inconclusive.
% Minimums are store as fmin, maximums as fmax, saddle points as saddlePts,
% and inconclusives as inconcl.
Xc = double(xcrit); Yc = double(ycrit);
results = table('Size', [numel(Xc), 3], ...
'VariableTypes', ["sym", "sym", "string"], ...
'VariableNames', ["X", "Y", "type"]);
results.X = xcrit(:);
results.Y = ycrit(:);
% generalize the loop to handle case where xcrit/ycrit have different
% numbers of elements, using numel(Xc) instead of hard-coding 9
for ind = 1:numel(Xc)
D=fxx(Xc(ind),Yc(ind))*fyy(Xc(ind),Yc(ind)) - (fxy(Xc(ind),Yc(ind)))^2;
if D > 0 && fxx(Xc(ind),Yc(ind)) > 0
results.type(ind) = "min";
elseif (D > 0) && (fxx(Xc(ind),Yc(ind)) < 0)
results.type(ind) = "max";
elseif (D < 0)
results.type(ind) = "saddle";
elseif (D == 0) % May be able to just use "else" instead of "elseif (D==0)"
results.type(ind) = "inconclusive";
end
end
disp(results)
Then if you needed to do anything with points of a certain type:
minima = results(results.type == "min", :)
You could also have individual variables in the table if you want to have booleans to work with.
results.min = results.type == "min";
results.max = results.type == "max";
results.saddle = results.type == "saddle";
results.inconclusive = results.type == "inconclusive";
disp(results)
0 commentaires
Voir également
Catégories
En savoir plus sur Numbers and Precision dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!