How to solve for the maximum or minimum value of a symbolic function

19 ビュー (過去 30 日間)
xin
xin 2024 年 9 月 8 日
コメント済み: Umar 2024 年 9 月 9 日
I have a complex symbolic function and want to find the corresponding maximum or minimum value. So I make its derivative equal to 0, but I don't know how to solve it further.
syms Vr theta_r Vse rho gamma Ish positive real
syms X_r positive real
syms n_t positive real
syms Vs positive real
expr=sqrt(((3*Vs)/2 + Vse*n_t*cos(rho) - Vr*n_t*cos(theta_r))^2/(X_r^2*n_t^2) + ((sqrt(sym(3))*Vs)/2 + Vse*n_t*sin(rho) - Vr*n_t*sin(theta_r))^2/(X_r^2*n_t^2))
diff=simplify(diff(expr,rho))
The simplified derivative is .
While there are ways to solve for the maximum value by specifying a specific variable range, I'd like to get a more generalised expression than just a number.

採用された回答

Torsten
Torsten 2024 年 9 月 8 日
編集済み: Torsten 2024 年 9 月 8 日
syms Vr theta_r Vse rho gamma positive real
syms X_r positive real
syms n_t positive real
syms Vs positive real
syms x y lambda
expr = ((3*Vs)/2 + Vse*n_t*cos(rho) - Vr*n_t*cos(theta_r))^2/(X_r^2*n_t^2) + ((sqrt(sym(3))*Vs)/2 + Vse*n_t*sin(rho) - Vr*n_t*sin(theta_r))^2/(X_r^2*n_t^2)
expr = 
expr_xy = subs(expr,[cos(rho),sin(rho)],[x y])
expr_xy = 
% Build Lagrange Function and solve Lagrange Equations
L = expr_xy - lambda*(x^2+y^2-1);
Lx = diff(L,x);
Ly = diff(L,y);
Llambda = diff(L,lambda);
sol = solve([Lx==0,Ly==0,Llambda==0],[x y lambda])
sol = struct with fields:
x: [2x1 sym] y: [2x1 sym] lambda: [2x1 sym]
sol.x
ans = 
sol.y
ans = 
sol.lambda
ans = 
simplify((sol.x).^2 + (sol.y).^2)
ans = 
% Example
Vr_val = 1; % Assign a numeric value
theta_r_val = 0.5; % Assign a numeric value
Vse_val = 1; % Assign a numeric value
X_r_val = 1; % Assign a numeric value
n_t_val = 1; % Assign a numeric value
Vs_val = 1; % Assign a numeric value
% rho = atan(y/x)
rho_crit = atan(double(subs(sol.y,[Vr,theta_r,Vse,X_r,n_t,Vs],[Vr_val,theta_r_val,Vse_val,X_r_val,n_t_val,Vs_val]))./double(subs(sol.x,[Vr,theta_r,Vse,X_r,n_t,Vs],[Vr_val,theta_r_val,Vse_val,X_r_val,n_t_val,Vs_val])))
rho_crit = 2x1
0.5558 0.5558
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
rho_val = 0:0.001:2*pi;
expr_val = arrayfun(@(rho_val)double(subs(expr,[rho,Vr,theta_r,Vse,X_r,n_t,Vs],[rho_val,Vr_val,theta_r_val,Vse_val,X_r_val,n_t_val,Vs_val])),rho_val);
plot(rho_val,expr_val)
[~,idx] = max(expr_val);
rho_val(idx)
ans = 0.5560

その他の回答 (2 件)

John D'Errico
John D'Errico 2024 年 9 月 8 日
You need to understand that not ALL equations you can write down have an analytical solution. In fact, it is trivial to formulate such a problem. And there are many reasons why such a solution will not be not found. Just wanting a nice pretty solution, wrapped up in a box with a bow on top is not sufficient.
Here you want to solve for rho, such that expr is maximized. A problem is, these parameters may take on any value, subject to the constraints of being positive and real.
syms Vr theta_r Vse rho gamma Ish positive real
syms X_r positive real
syms n_t positive real
syms Vs positive real
expr=sqrt(((3*Vs)/2 + Vse*n_t*cos(rho) - Vr*n_t*cos(theta_r))^2/(X_r^2*n_t^2) + ((sqrt(sym(3))*Vs)/2 + Vse*n_t*sin(rho) - Vr*n_t*sin(theta_r))^2/(X_r^2*n_t^2))
expr = 
By the way, you should understand just what a bad idea it is to create a variable named diff? You will no longer be able to use the FUNCTION diff. And that will just be the cause of an very quick and very anxious question on Answers, asking why diff no longer works for you.
Anyway, I'll name the derivative something else, to not step on the function diff.
exprdiff = simplify(diff(expr,rho))
exprdiff = 
An extremum (or sometimes a point of inflection) will exist where the derivative is zero, assuming the function is differentiable. That expression can only ever be zero when the numerator is zero, or as a limit if the denominator approaches +/- inf. But the denominator will always be finite for finite values of the parameters. So all you care about is the numerator. (What you show as the simplified derivative is not in fact the simplified derivative, just part of the numerator, as I show here.)
exprdiffnum = numden(exprdiff)
exprdiffnum = 
We can simplify a little since we know that Vse is non-zero, try to solve for that expression equal to zero, as I do here. The result is a mess.
solve(exprdiffnum/Vse == 0,rho,returnconditions = true)
ans = struct with fields:
rho: z parameters: z conditions: (in((z + log((2^(1/2)*exp((theta_r*1i)/2)*(6*Vs^2*exp(theta_r*1i) + 2*Vr^2*n_t^2*exp(theta_r*1i) - 3*Vr*Vs*n_t - 3*Vr*Vs*n_t*exp(theta_r*2i) - 3^(1/2)*Vr*Vs*n_t...
Even at that, you won't know if it has identified a maximum or a minimum, or a point of inflection. And depending on the values of those parameters, it might be any of the above. Can we do more? perhaps a little. We know that Vs is not zero, but strictly positive. And that allows us to divide by Vs also. The result will be a non-dimensional constant in the expression, I'll call it K. Do a substitution...
K = 2*Vr*n_t/Vs
syms K
edn = K*sin(rho - theta_r) - 3*sin(rho) + sqrt(3)*cos(rho)
edn = 
We can simplify that by a bit, though I'm not sure if it helps a lot.
simplify(edn)
ans = 
So if we knew the value of K, that should tell us a great deal. Essentially it drives the entire problem. Think of it as sort of a Reynolds number (if you know what that is.) You are now looking for the roots of that expression. But even then, you need to consider if it is a minimum of a maximum.

Umar
Umar 2024 年 9 月 8 日

Hi @xin,

You've defined a symbolic function involving several variables and taken its derivative with respect to rho. The goal is to find the critical points where the derivative equals zero and to determine whether these points correspond to maxima or minima using the second derivative test. In addition to your comments, I did add code to visualize its derivative to better understand the behavior over a specified range. Below is the complete MATLAB code that fulfills your requirements:

% Define symbolic variables
syms Vr theta_r Vse rho gamma Ish positive real
syms X_r positive real
syms n_t positive real
syms Vs positive real
% Define the expression
expr = sqrt(((3*Vs)/2 + Vse*n_t*cos(rho) - Vr*n_t*cos(theta_r))^2/
(X_r^2*n_t^2) + ...
           ((sqrt(3)*Vs)/2 + Vse*n_t*sin(rho) - Vr*n_t*sin(theta_r))^2/
(X_r^2*n_t^2));
   % Compute the derivative with respect to rho
   diff_expr = simplify(diff(expr, rho));
% Solve for critical points where derivative equals zero with conditions
critical_points = solve(diff_expr == 0, rho, 'ReturnConditions', true);
% Display critical points
disp('Critical points:');
disp(critical_points);
% Compute the second derivative
second_diff_expr = simplify(diff(diff_expr, rho));
% Evaluate the second derivative at critical points
second_derivative_values = subs(second_diff_expr, rho, critical_points.rho);
% Analyze the nature of critical points
disp('Second derivative values at critical points:');
disp(second_derivative_values);
% Create a range for rho for plotting
rho_values = linspace(0, 2*pi, 100); % Adjust range as needed
% Substitute numeric values for symbolic variables (example values)
Vr_val = 1; % Assign a numeric value
theta_r_val = 0.5; % Assign a numeric value
Vse_val = 1; % Assign a numeric value
X_r_val = 1; % Assign a numeric value
n_t_val = 1; % Assign a numeric value
Vs_val = 1; % Assign a numeric value
% Evaluate the expression and derivative numerically
% Using the correct syntax to substitute multiple variables
expr_values = subs(expr, {Vr, theta_r, Vse, X_r, n_t, Vs}, {Vr_val, theta_r_val,     
Vse_val, X_r_val, n_t_val, Vs_val});
diff_values = subs(diff_expr, {Vr, theta_r, Vse, X_r, n_t, Vs}, {Vr_val, 
theta_r_val, Vse_val, X_r_val, n_t_val, Vs_val});
% Convert symbolic results to double for plotting
expr_values_numeric = double(subs(expr_values, rho, rho_values));
diff_values_numeric = double(subs(diff_values, rho, rho_values));
% Plot the function
figure;
plot(rho_values, expr_values_numeric, 'LineWidth', 2);
xlabel('rho');
ylabel('Function Value');
title('Plot of the Function over rho');
grid on;
% Optionally, plot the derivative
figure;
plot(rho_values, diff_values_numeric, 'LineWidth', 2);
xlabel('rho');
ylabel('Derivative Value');
title('Plot of the Derivative over rho');
grid on;

Please see attached.

Explanation of the Code

Symbolic Variable Definition: The required symbolic variables are defined with appropriate constraints (e.g., positive real).

Expression Definition:The expression you provided is defined symbolically.

First Derivative:The derivative of the expression with respect to \( \rho \) is computed and simplified.

Critical Points:The critical points where the derivative equals zero are calculated using the `solve` function.

Second Derivative: The second derivative is computed to analyze the concavity at the critical points, which helps in determining whether they correspond to maxima or minima.

Evaluation of Second Derivative:The second derivative is evaluated at each critical point to ascertain the nature of those points.

Visualization: The function and its derivative are plotted over a specified range of rho values for visual analysis.

Now, if the second derivative at a critical point is positive, that point corresponds to a local minimum and if it is negative,then that indicates a local maximum. If it equals zero, further tests may be needed. Also, adjust the range of rho values based on the specific context of your problem to make sure you capture the relevant behavior of the function. When applying this code, you'll need to assign numerical values to the symbolic variables (e.g., Vr, Vs, etc.) to generate specific numerical results.

Please let me know if this helped resolve your problem.

  2 件のコメント
xin
xin 2024 年 9 月 9 日
Very nice code, thanks!
Umar
Umar 2024 年 9 月 9 日
Hi @Xin,
No problem. Thanks for the compliment.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCalculus についてさらに検索

製品


リリース

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by