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°

 Accepted Answer

Stephan
Stephan on 16 Oct 2018
Edited: Stephan on 16 Oct 2018
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 Comments

Joe
Joe on 16 Oct 2018
Edited: Joe on 16 Oct 2018
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.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2018a

Asked:

Joe
on 15 Oct 2018

Commented:

Joe
on 16 Oct 2018

Community Treasure Hunt

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

Start Hunting!