fmincon for multiple variables
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
Hi,
I want to perform a constrained optimization,that makes fmincon a good option.
However, it returns the error '' fmincon requires all values returned by the functions to be of data type double''.
Y is the objective that I want to optimize,with three variables a1,a2,a3.
function Y = optfun(z)
a1 = z(1);
a2 = z(2);
a3 = z(3);
y1 = abs(vpa("0.129")*a1*sym(1i) + vpa("0.01")*a2*sym(1i) + vpa("8.57e-4")*a3*sym(1i) - vpa("2410.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) - vpa("2410.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) - vpa("2410.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("25.0") + vpa("96.4i"))/abs(vpa("0.129")*a1*sym(1i) + vpa("0.01")*a2*sym(1i) + vpa("8.57e-4")*a3*sym(1i) + vpa("2410.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) + vpa("2410.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) + vpa("2410.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("125.0") + vpa("96.4i"));
y2 = abs(vpa("0.173")*a1*sym(1i) + vpa("0.0135")*a2*sym(1i) + vpa("0.00115")*a3*sym(1i) - vpa("3250.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) - vpa("3250.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) - vpa("3250.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("25.0") + vpa("130.0i"))/abs(vpa("0.173")*a1*sym(1i) + vpa("0.0135")*a2*sym(1i) + vpa("0.00115")*a3*sym(1i) + vpa("3250.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) + vpa("3250.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) + vpa("3250.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("125.0") + vpa("130.0i"));
y3 = abs(vpa("0.197")*a1*sym(1i) + vpa("0.0153")*a2*sym(1i) + vpa("0.00131")*a3*sym(1i) - vpa("3690.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) - vpa("3690.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) - vpa("3690.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("25.0") + vpa("148.0i"))/abs(vpa("0.197")*a1*sym(1i) + vpa("0.0153")*a2*sym(1i) + vpa("0.00131")*a3*sym(1i) + vpa("3690.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) + vpa("3690.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) + vpa("3690.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("125.0") + vpa("148.0i"));
Y = (1-y1)+(1-y3)+(y2);
end
By the way,I want to know is there possibilities to add constration to my objective value?
For example, 0<[y1,y2,y3]<1.
Any help will be appreciate,thx!
1 件のコメント
Stephen23
2023 年 8 月 23 日
Note: the context is explained in the comments here:
採用された回答
Y = double( (1-y1)+(1-y3)+(y2) );
But I don't see why you are using vpa and other sym operations. I don't think it really increases precision for you since all your coefficients have substantially less than 32 decimal places.
20 件のコメント
By the way,I want to know is there possibilities to add constration to my objective value? For example, 0<[y1,y2,y3]<1.
Of course! That's why it's called fmincon. For the constraints you describe, you would need to use the nonlcon argument.
I want to add them on y1 y2 y3.
Yes, you will need a nonlinear constraint for that.
I have not used the optimization app, but presumably the "Nonlinear" button will prompt you to provide a constraint function handle as described here:
Guan Hao
2023 年 8 月 23 日
I think maybe I can create a constraint function like this:
function [c,ceq] = constraintFcn(z)
% Example:
% Constrain a solution to the region
% x^2 + y^2 <= 5
% x^2 + y^2 >= 2
% y = x^3
% Edit the lines below with your calculation
% Note, if no inequality constraints, specify c = []
% Note, if no equality constraints, specify ceq = []
y1 = z(1);
y2 = z(2);
y3 = z(3);
c(1) = y1-1;
c(2) = y3-1;
ceq=[];
end
Matt J
2023 年 8 月 23 日
Yes, although this only implements 2 of the 6 bounds you said you wanted.
Guan Hao
2023 年 8 月 24 日
@Matt J Hi,sorry to bother you again.
After I try my constraint function,the value didn't meet my requirement.(y1,y2,y3 returns the values of 0.2 0.2 0.2,respectively)
I'm trying to add constraint to my output function,not variables.
Is it correct to write the code like this?
function [c,ceq] = constraintFcn(z)
% My Constraint
% 0.9 <= y1 <= 1
% 0 <= y2 <= 0.1
% 0.9 <= y3 <= 1
y1 = z(1);
y2 = z(2);
y3 = z(3);
c(1) = -y1+0.9;
c(2) = y2-0.1;
c(3) = -y3+0.9;
c(4) = y1-1;
c(5) = y2;
c(6) = y3-1;
ceq=[];
end
All these constraints can be set in the arrays "lb" and "ub" which are direct inputs to "fmincon":
lb = [0.9 0 0.9];
ub = [1 0.1 1]
And c(5) = y2 is incorrect because it sets y2 <= 0, not y2 >= 0.
Guan Hao
2023 年 8 月 24 日
Thanks for your reply.
Isn't that setting bounds for the variables (a1 a2 a3)?
I want to set constrait to y1 y2 y3,which are functions of a1 a2 a3.
Torsten
2023 年 8 月 24 日
Yes, you are right.
But c(5) should be -y2, not y2.
But you set the constraints on the parameters to be fitted, not on y1, y2 and y3 which you claim are functions of a1, a2 and a3. The vector z in "constraintFcn" is the vector (a1,a2,a3) from which you first have to compute y1,y2 and y3 (whatever they are). That's why I said that its the same as setting
lb = [0.9 0 0.9];
ub = [1 0.1 1]
And as I can see from your output: the vector x returned from "fmincon" satisfies lb <= x <= ub.
Torsten
2023 年 8 月 24 日
Compute y1, y2 and y3 in "constraintFcn" from the z-vector and set the constraints as you did:
y = fun_z_to_y(z);
y1 = y(1);
y2 = y(2);
y3 = y(3);
c(1) = -y1+0.9;
c(2) = y2-0.1;
c(3) = -y3+0.9;
c(4) = y1-1;
c(5) = -y2;
c(6) = y3-1;
Guan Hao
2023 年 8 月 24 日
@Torsten Thanks for your patience.
Did you mean something like this? It returns a error message that '' fmincon requires all values returned by the functions to be of data type double''.
Sorry,I must misunderstand your meaning...
function [c,ceq] = constraintFcn_new(z)
% My Constraint
% 0.9 <= y1 <= 1
% 0 <= y2 <= 0.1
% 0.9 <= y3 <= 1
a1 = z(1);
a2 = z(2);
a3 = z(3);
y = [abs(- vpa("0.122")*a1*sym(1i) - vpa("0.00895")*a2*sym(1i) - vpa("7.32e-4")*a3*sym(1i) + vpa("1530.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("8.0e-6")*a3 + vpa("4.0e-4")*a2 + vpa("0.02")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("6.4e-5")*a3 + vpa("0.0016")*a2 + vpa("0.04")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("5.12e-4")*a3 + vpa("0.0064")*a2 + vpa("0.08")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("2.16e-4")*a3 + vpa("0.0036")*a2 + vpa("0.06")*a1) - vpa("25.0") - vpa("102.0i"))/abs(vpa("0.122")*a1*sym(1i) + vpa("0.00895")*a2*sym(1i) + vpa("7.32e-4")*a3*sym(1i) + vpa("1530.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("8.0e-6")*a3 + vpa("4.0e-4")*a2 + vpa("0.02")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("6.4e-5")*a3 + vpa("0.0016")*a2 + vpa("0.04")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("5.12e-4")*a3 + vpa("0.0064")*a2 + vpa("0.08")*a1) + vpa("1530.0i")/(vpa("50.0") + vpa("2.16e-4")*a3 + vpa("0.0036")*a2 + vpa("0.06")*a1) + vpa("125.0") + vpa("102.0i"));
abs(- vpa("0.176")*a1*sym(1i) - vpa("0.0129")*a2*sym(1i) - vpa("0.00106")*a3*sym(1i) + vpa("2200.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("8.0e-6")*a3 + vpa("4.0e-4")*a2 + vpa("0.02")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("6.4e-5")*a3 + vpa("0.0016")*a2 + vpa("0.04")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("5.12e-4")*a3 + vpa("0.0064")*a2 + vpa("0.08")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("2.16e-4")*a3 + vpa("0.0036")*a2 + vpa("0.06")*a1) - vpa("25.0") - vpa("147.0i"))/abs(vpa("0.176")*a1*sym(1i) + vpa("0.0129")*a2*sym(1i) + vpa("0.00106")*a3*sym(1i) + vpa("2200.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("8.0e-6")*a3 + vpa("4.0e-4")*a2 + vpa("0.02")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("6.4e-5")*a3 + vpa("0.0016")*a2 + vpa("0.04")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("5.12e-4")*a3 + vpa("0.0064")*a2 + vpa("0.08")*a1) + vpa("2200.0i")/(vpa("50.0") + vpa("2.16e-4")*a3 + vpa("0.0036")*a2 + vpa("0.06")*a1) + vpa("125.0") + vpa("147.0i"));
abs(- vpa("0.223")*a1*sym(1i) - vpa("0.0163")*a2*sym(1i) - vpa("0.00134")*a3*sym(1i) + vpa("2790.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("8.0e-6")*a3 + vpa("4.0e-4")*a2 + vpa("0.02")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("6.4e-5")*a3 + vpa("0.0016")*a2 + vpa("0.04")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("5.12e-4")*a3 + vpa("0.0064")*a2 + vpa("0.08")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("2.16e-4")*a3 + vpa("0.0036")*a2 + vpa("0.06")*a1) - vpa("25.0") - vpa("186.0i"))/abs(vpa("0.223")*a1*sym(1i) + vpa("0.0163")*a2*sym(1i) + vpa("0.00134")*a3*sym(1i) + vpa("2790.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("8.0e-6")*a3 + vpa("4.0e-4")*a2 + vpa("0.02")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("6.4e-5")*a3 + vpa("0.0016")*a2 + vpa("0.04")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("5.12e-4")*a3 + vpa("0.0064")*a2 + vpa("0.08")*a1) + vpa("2790.0i")/(vpa("50.0") + vpa("2.16e-4")*a3 + vpa("0.0036")*a2 + vpa("0.06")*a1) + vpa("125.0") + vpa("186.0i"));];
y1 = y(1);
y2 = y(2);
y3 = y(3);
c(1) = -y1+0.9;
c(2) = y2-0.1;
c(3) = -y3+0.9;
c(4) = y1-1;
c(5) = -y2;
c(6) = y3-1;
ceq=[];
end
Insert the line
y = double(y)
before you assign
y1 = y(1);
y2 = y(2);
y3 = y(3);
...
I wonder why you need symbolic variables to define y. Using numerical variables will usually speed up the numerical solver "fmincon" remarkably.
Steven Lord
2023 年 8 月 24 日
Rather than duplicating your objective function's code in your constraint function, I'd define your objective function to return multiple outputs (the second and later ones being the quantities you're trying to constraint) and call it with multiple outputs in your constraint function.
Note that as per the description of the fun input argument on the fmincon documentation page, if you're using the SpecifyObjectiveGradient and HessianFcn options you may need to push these "supplementary outputs" later in the output list.
Y = optfun([1; 2; 3])
Y = 1.8024
confun([1; 2; 3])
Y is 1.80239
y1 is 0.198814
y2 is 0.198692
y3 is 0.197487
check: 1.80239
function [Y, y1, y2, y3] = optfun(z)
a1 = z(1);
a2 = z(2);
a3 = z(3);
y1 = abs(vpa("0.129")*a1*sym(1i) + vpa("0.01")*a2*sym(1i) + vpa("8.57e-4")*a3*sym(1i) - vpa("2410.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) - vpa("2410.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) - vpa("2410.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("25.0") + vpa("96.4i"))/abs(vpa("0.129")*a1*sym(1i) + vpa("0.01")*a2*sym(1i) + vpa("8.57e-4")*a3*sym(1i) + vpa("2410.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) + vpa("2410.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) + vpa("2410.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("125.0") + vpa("96.4i"));
y2 = abs(vpa("0.173")*a1*sym(1i) + vpa("0.0135")*a2*sym(1i) + vpa("0.00115")*a3*sym(1i) - vpa("3250.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) - vpa("3250.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) - vpa("3250.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("25.0") + vpa("130.0i"))/abs(vpa("0.173")*a1*sym(1i) + vpa("0.0135")*a2*sym(1i) + vpa("0.00115")*a3*sym(1i) + vpa("3250.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) + vpa("3250.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) + vpa("3250.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("125.0") + vpa("130.0i"));
y3 = abs(vpa("0.197")*a1*sym(1i) + vpa("0.0153")*a2*sym(1i) + vpa("0.00131")*a3*sym(1i) - vpa("3690.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) - vpa("3690.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) - vpa("3690.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("25.0") + vpa("148.0i"))/abs(vpa("0.197")*a1*sym(1i) + vpa("0.0153")*a2*sym(1i) + vpa("0.00131")*a3*sym(1i) + vpa("3690.0i")/(vpa("50.0") + vpa("3.7e-5")*a3 + vpa("0.00111")*a2 + vpa("0.0333")*a1) + vpa("3690.0i")/(vpa("50.0") + vpa("2.96e-4")*a3 + vpa("0.00444")*a2 + vpa("0.0667")*a1) + vpa("3690.0i")/(vpa("50.0") + vpa("0.001")*a3 + vpa("0.01")*a2 + vpa("0.1")*a1) + vpa("125.0") + vpa("148.0i"));
% Converting to double after the fact is simpler to type for this example
% than removing all your vpa and sym calls, but for your real code I'd
% perform the removal to avoid involving Symbolic Math Toolbox at all
y1 = double(y1);
y2 = double(y2);
y3 = double(y3);
Y = (1-y1)+(1-y3)+(y2);
end
function confun(z)
% Reuse rather than duplicating
[Y, y1, y2, y3] = optfun(z);
fprintf(" Y is %g\n y1 is %g\n y2 is %g\n y3 is %g\n", Y, y1, y2, y3)
fprintf("check: %g\n", (1-y1)+(1-y3)+y2)
end
Matt J
2023 年 8 月 24 日
Or better still, follow the guidelines here,
for avoiding repeated computations in the constraint and objective function code.
Guan Hao
2023 年 8 月 24 日
This is all of my code,it removes all vpa and sym things.
However,when I run the optimization,it seems that the constraints are on a1,a2,a3 again.

function [Y, y1, y2, y3] = optfun_new(z)
Z01=50;
Z02=75;
v=3e+8;
section=100;
L=0.1;
a=L/section;
a0=Z01;
f1=1e+9;
f2=2e+9;
w1=2*pi*f1;
w2=2*pi*f2;
syms w
beta=w/v;
a1 = z(1);
a2 = z(2);
a3 = z(3);
% ABCD Matrix
for m=1:1:section
l=m*a;
Z0=a0+(a1*l)+(a2*(l^2))+(a3*(l^3));
B(m)=1i*Z0*sin(beta*a);
C(m)=1i*(1/Z0)*sin(beta*a);
end
Bsum=sum(B);
Csum=sum(C);
ABCD=[1 Bsum ; Csum 1];
% Convert into S11
S11=((ABCD(1,2)-ABCD(2,1)*Z01*Z02)+((ABCD(1,1)*Z02)-(ABCD(2,2)*Z01)))/((ABCD(1,2)+ABCD(2,1)*Z01*Z02)+((ABCD(1,1)*Z02)+(ABCD(2,2)*Z01)));
gamma=abs(S11);
% Optimize objective
y1=subs(gamma,w,w1);
y2=subs(gamma,w,((w1+w2)/2));
y3=subs(gamma,w,w2);
% Converting to double after the fact is simpler to type for this example
% than removing all your vpa and sym calls, but for your real code I'd
% perform the removal to avoid involving Symbolic Math Toolbox at all
y1 = double(y1);
y2 = double(y2);
y3 = double(y3);
Y = (1-y1)+(1-y3)+(y2);
end
function [c,ceq] = constraintFcn_new(z)
% Reuse rather than duplicating
[Y, y1, y2, y3] = optfun(z);
fprintf(" Y is %g\n y1 is %g\n y2 is %g\n y3 is %g\n", Y, y1, y2, y3)
fprintf("check: %g\n", (1-y1)+(1-y3)+y2)
y1 = z(1);
y2 = z(2);
y3 = z(3);
c(1) = -y1+0.9;
c(2) = y2-0.1;
c(3) = -y3+0.9;
c(4) = y1-1;
c(5) = -y2;
c(6) = y3-1;
ceq=[];
end
Steven Lord
2023 年 8 月 24 日
You're calling the optfun to generate the intermediate values of your objective function, then after the fprintf lines (which I added just to show you that the constraint function had correctly obtained the values from the objective function) you throw away those intermediate values and replace them with elements of the input with which fmincon called the constraint function. Don't do that. Delete these lines from your constraint function:
y1 = z(1);
y2 = z(2);
y3 = z(3);
Guan Hao
2023 年 8 月 25 日
@Steven Lord Thank you sir !!! It's working now.
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Linear Least Squares についてさらに検索
タグ
参考
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)


