How to make a multivariable goal optimization

Im trying to understand multivariable goal optimization, I will need to optimize complex functions, but to start, I need to optimize the following function:
function ap_phase = objecfun(tau)
f = 1000; %Frequency
w = 2*pi*f; %Angular Frequency
trans_func = @(taux) (1-1i*w*taux)./(1+1i*w*taux); %Transfer function
trans_zero = trans_func(tau(1)); %Transfer function with the first variable
trans_quad = trans_func(tau(2)); %Transfer function with the second variable
ap_phase = rad2deg(phase(trans_zero)-phase(trans_quad)); %Phase difference
end
The function objecfun takes one vector of length 2 as an input, computes two transfer functions, then substracts the phase of the transfer functions.
My goal is that the phase should be around 90°
The script im using to make the optimization is the following
tau0 = [2E-5, 1E-3]; %Initial Value for tau(1) and tau(2)
lb = [1E-7, 1E-7]; %Lower bound for tau(1) and tau(2)
ub = [1E-2, 1E-2]; %Upper bound for tau(1) and tau(2)
goal = 90; %Optimization goal
weight = 1; %Weight
[x,fval] = fgoalattain(@objecfun,tau0,goal,weight,[],[],[],[],lb,ub)
The optimizer converges but im getting a wrong answer, im getting
x =
0.0100 0.0000
fval =
-178.1044
That's wrong, fval should be near 90°

 采纳的回答

Hi,
fgoalattain calculates a result:
f(x) <= goal
Better use fsolve - this will try to calculate:
f(x)=0
Check this:
[x, fval] = phase_delta_90;
fprintf('tau(1) = %.12f\ntau(2) = %.12f\nPhase delta = %2.8f degree',x(1),x(2),fval)
function [x, fval] = phase_delta_90
goal = 90;
tau0 = [2E-5, 1E-3]; %Initial Value for tau(1) and tau(2)
x = fsolve(@calculate_tau,tau0);
fval = check_result(x);
function tau_result = calculate_tau(tau)
f = 1000; %Frequency
w = 2*pi*f; %Angular Frequency
trans_func = @(taux) (1-1i*w*taux)./(1+1i*w*taux); %Transfer function
trans_zero = trans_func(tau(1)); %Transfer function with the first variable
trans_quad = trans_func(tau(2)); %Transfer function with the second variable
tau_result = rad2deg(phase(trans_zero)-phase(trans_quad))-goal; %Phase difference minus goal
end
function ap_phase = check_result(x)
f = 1000; %Frequency
w = 2*pi*f; %Angular Frequency
trans_func = @(taux) (1-1i*w*taux)./(1+1i*w*taux); %Transfer function
trans_zero = trans_func(x(1)); %Transfer function with the first variable
trans_quad = trans_func(x(2)); %Transfer function with the second variable
ap_phase = rad2deg(phase(trans_zero)-phase(trans_quad)); %Phase difference after optimization
end
end

5 个评论

Thanks for your answer,but although your code does solve the problem I proposed, it is somehow limited, as far as I know fsolve is not an optimizer instead it solves the system of equations but doesnt do the same job as an optimizer, for instance what happens if I dont have one but many goals, can fsolve be used? Is there an optimizer that instead of solving f(x)<goal or f(x)=goal, it solves lower_goal<f(x)<upper_goal?
You're right - I misused fsolve here a bit to achieve the goal. I think to solving the problem you have posed, this solver simply fits better than fgoalattain to achieve the goal.
If you want to work with bounds, another solver may be appropriate.
For the given question, the goal was a phase difference of 90 ° as well as possible. This is easier to solve with fsolve than with fgoalattain. That's why I chose it and hope it helped you solve your problem.
Is there an optimizer that instead of solving f(x)<goal or f(x)=goal, it solves lower_goal<f(x)<upper_goal?
Consider:
tau0 = [2E-5, 1E-3]; %Initial Value for tau(1) and tau(2)
lb = [1E-7, 1E-7]; %Lower bound for tau(1) and tau(2)
ub = [1E-2, 1E-2]; %Upper bound for tau(1) and tau(2)
goal = [90.1 -89.9]; %Optimization goal
weight = [1 1]; %Weight
[x,fval] = fgoalattain(@objecfun,tau0,goal,weight,[],[],[],[],lb,ub)
function ap_phase = objecfun(tau)
f = 1000; %Frequency
w = 2*pi*f; %Angular Frequency
trans_func = @(taux) (1-1i*w*taux)./(1+1i*w*taux); %Transfer function
trans_zero = trans_func(tau(1)); %Transfer function with the first variable
trans_quad = trans_func(tau(2)); %Transfer function with the second variable
ap_phase(1) = rad2deg(phase(trans_zero)-phase(trans_quad)); %Phase difference
ap_phase(2) = -(rad2deg(phase(trans_zero)-phase(trans_quad))); %Phase difference
end
What happens here? I used a second Goal with the negative value of your desired Goal with a Little toerance to both sides. This way i told fgoalattain to do exactly what you want:
89.9 <= Goal <= 90.1
If you see the results, it works properly:
x =
1.0e-03 *
0.115220205761474 0.993932451929828
fval =
89.999999999233822 -89.999999999233822
Perhaps you like this solution more ;-)
That is exactly what I was looking for, thank you, just one other thing the lower goal you selected is 85 not -85 right? you only put -85 to invert the inequality sign?
you only put -85 to invert the inequality sign?
Exactly
Thanks Stephan that was really helpful.

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Get Started with Optimization Toolbox 的更多信息

产品

版本

R2018a

标签

Community Treasure Hunt

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

Start Hunting!

Translated by