Setting nonlcon for fmincon / patternsearch as a matlabfunction

2 ビュー (過去 30 日間)
Ash Ash
Ash Ash 2020 年 3 月 25 日
コメント済み: Ash Ash 2020 年 3 月 27 日
Hi everyone,
I am encountering some difficulties when trying to structure the nonlinear inequalities as inputs (for the "nonlcon" input in the function "patternsearch"), and I have referred to the matlab documentation on "Nonlinear Constraints" that says:
"Write a nonlinear constraint function as follows:"
c = @(x)[x(1)^2/9 + x(2)^2/4 - 1;
x(1)^2 - x(2) - 1];
ceq = @(x)tanh(x(1)) - x(2);
nonlcon = @(x)deal(c(x),ceq(x));
Due to the requirements of my problem, I cannot (or don't know how to) prepare an explicit mfile or function handle for my system of nonlinear inequality constraints. This is because the system of nonlinear inequality constraints have been constructed using the Symbolic Toolbox because are very long and vary with every iteration. Hence I have tried to use "matlabFunction" to try to convert the equations (in as symbolic variables) to function handles as follows
a_sym=sym('a',[10 10]);
eqn_nonlin=sym(zeros(10,1));
for i=1:10
eqn_nonlin(i)=mean(abs(eqn_sym{i}/2));
end
c=matlabFunction(vertcat(eqn_nonlin-1,-eqn_nonlin+0.8));
ceq=[];
nonlcon = @(a_sym)deal(c(a_sym),ceq(a_sym));
where "c" is a function of all the elements above the diagonal of "a_sym" (a total of 45 elements)
>> c
c =
function_handle with value:
@(a1_2,a1_3,a1_4,a1_5,a1_6,a1_7,a1_8,a1_9,a2_3,a2_4,a2_5,a2_6,a2_7,a2_8,a2_9,a3_4,a3_5,a3_6,a3_7,a3_8,a3_9,a4_5,a4_6,a4_7,a4_8,a4_9,a5_6,a5_7,a5_8,a5_9,a6_7,a6_8,a6_9,a7_8,a7_9,a8_9,a1_10,a2_10,a3_10,a4_10,a5_10,a6_10,a7_10,a8_10,a9_10)[abs(((a1_2.*(-5.249914648266426e-5)-a1_3.*5.250328005396799e-5-a1_4.*5.07598403480356e-5-a1_5.*5.156525926342894e-5-a1_6.*5.138443653182008e-5-a1_7.*5.191200741797726e-5-a1_8.*5 [truncated due to length]
It seems that this method of structuring the nonlinear inequality constraint is not correct beacuise I get an error when I try
>> nonlcon(ones(45,1))
Not enough input arguments.
Error in symengine>@(a1_2,a1_3,a1_4,a1_5,a1_6,a1_7,a1_8,a1_9,a2_3,a2_4,a2_5,a2_6,a2_7,a2_8,a2_9,a3_4,a3_5,a3_6,a3_7,a3_8,a3_9,a4_5,a4_6,a4_7,a4_8,a4_9,a5_6,a5_7,a5_8,a5_9,a6_7,a6_8,a6_9,a7_8,a7_9,a8_9,a1_10,a2_10,a3_10,a4_10,a5_10,a6_10,a7_10,a8_10,a9_10)[abs(((a1_2.*(-5.249914648266426e-5)-a1_3.*5.250328005396799e-5-a1_4.*5.07598403480356e-5-a1_5.*5.156525926342894e-5-a1_6.*5.138443653182008e-5-a1_7.*5.191200741797726e-5-a1_8.*5. [truncated due to length]
Error in @(a_sym)deal(c(a_sym),[])
or
>> nonlcon(1,2,3,4,5,6,7,8,9,0,...
1,2,3,4,5,6,7,8,9,0,...
1,2,3,4,5,6,7,8,9,0,...
1,2,3,4,5,6,7,8,9,0,...
1,2,3,4,5)
Error using @(a_sym)deal(c(a_sym),[])
Too many input arguments.
Would you please advice me on how I should structure the nonlinear inequalities from a symbolic variable?
Thank you very much. I appreciate your time and patience.
  2 件のコメント
darova
darova 2020 年 3 月 25 日
Can you show simple example of your system on nonlinear inequalititeS?
Ash Ash
Ash Ash 2020 年 3 月 25 日
編集済み: Ash Ash 2020 年 3 月 25 日
Thanks for your reply, darova. The equations have the same form "A/abs(A)", as follows:
>> vpa(eqn_sym{1}(1),2)
ans =
((1.2e-5*a2_3 - 5.2e-5*a1_3 - 5.1e-5*a1_4 - 5.1e-5*a1_5 - 5.1e-5*a1_6 - 5.2e-5*a1_7 - 5.1e-5*a1_8 - 5.2e-5*a1_9 - 5.2e-5*a1_2 + 1.4e-5*a2_4 + 1.4e-5*a2_5 + 1.3e-5*a2_6 + 1.4e-5*a2_7 + 1.3e-5*a2_8 + 1.1e-5*a2_9 + 1.4e-5*a3_4 + 1.4e-5*a3_5 + 1.3e-5*a3_6 + 1.4e-5*a3_7 + 1.3e-5*a3_8 + 1.1e-5*a3_9 + 1.6e-5*a4_5 + 1.6e-5*a4_6 + 1.6e-5*a4_7 + 1.5e-5*a4_8 + 1.3e-5*a4_9 + 1.5e-5*a5_6 + 1.6e-5*a5_7 + 1.5e-5*a5_8 + 1.3e-5*a5_9 + 1.6e-5*a6_7 + 1.4e-5*a6_8 + 1.2e-5*a6_9 + 1.5e-5*a7_8 + 1.3e-5*a7_9 + 1.2e-5*a8_9 - 5.2e-5*a1_10 + 1.1e-5*a2_10 + 1.1e-5*a3_10 + 1.3e-5*a4_10 + 1.3e-5*a5_10 + 1.2e-5*a6_10 + 1.3e-5*a7_10 + 1.2e-5*a8_10 + 1.0e-5*a9_10)/(4.6e-6*a2_3 - 1.8e-5*a1_3 - 1.8e-5*a1_4 - 1.8e-5*a1_5 - 1.8e-5*a1_6 - 1.9e-5*a1_7 - 1.8e-5*a1_8 - 1.7e-5*a1_9 - 1.8e-5*a1_2 + 4.3e-6*a2_4 + 4.4e-6*a2_5 + 4.5e-6*a2_6 + 4.5e-6*a2_7 + 4.4e-6*a2_8 + 4.6e-6*a2_9 + 4.3e-6*a3_4 + 4.4e-6*a3_5 + 4.4e-6*a3_6 + 4.5e-6*a3_7 + 4.4e-6*a3_8 + 4.6e-6*a3_9 + 4.2e-6*a4_5 + 4.2e-6*a4_6 + 4.2e-6*a4_7 + 4.2e-6*a4_8 + 4.3e-6*a4_9 + 4.3e-6*a5_6 + 4.3e-6*a5_7 + 4.3e-6*a5_8 + 4.4e-6*a5_9 + 4.3e-6*a6_7 + 4.3e-6*a6_8 + 4.4e-6*a6_9 + 4.3e-6*a7_8 + 4.4e-6*a7_9 + 4.4e-6*a8_9 - 1.7e-5*a1_10 + 4.6e-6*a2_10 + 4.6e-6*a3_10 + 4.3e-6*a4_10 + 4.4e-6*a5_10 + 4.4e-6*a6_10 + 4.4e-6*a7_10 + 4.4e-6*a8_10 + 4.6e-6*a9_10) - 2.8)/abs((1.2e-5*a2_3 - 5.2e-5*a1_3 - 5.1e-5*a1_4 - 5.1e-5*a1_5 - 5.1e-5*a1_6 - 5.2e-5*a1_7 - 5.1e-5*a1_8 - 5.2e-5*a1_9 - 5.2e-5*a1_2 + 1.4e-5*a2_4 + 1.4e-5*a2_5 + 1.3e-5*a2_6 + 1.4e-5*a2_7 + 1.3e-5*a2_8 + 1.1e-5*a2_9 + 1.4e-5*a3_4 + 1.4e-5*a3_5 + 1.3e-5*a3_6 + 1.4e-5*a3_7 + 1.3e-5*a3_8 + 1.1e-5*a3_9 + 1.6e-5*a4_5 + 1.6e-5*a4_6 + 1.6e-5*a4_7 + 1.5e-5*a4_8 + 1.3e-5*a4_9 + 1.5e-5*a5_6 + 1.6e-5*a5_7 + 1.5e-5*a5_8 + 1.3e-5*a5_9 + 1.6e-5*a6_7 + 1.4e-5*a6_8 + 1.2e-5*a6_9 + 1.5e-5*a7_8 + 1.3e-5*a7_9 + 1.2e-5*a8_9 - 5.2e-5*a1_10 + 1.1e-5*a2_10 + 1.1e-5*a3_10 + 1.3e-5*a4_10 + 1.3e-5*a5_10 + 1.2e-5*a6_10 + 1.3e-5*a7_10 + 1.2e-5*a8_10 + 1.0e-5*a9_10)/(4.6e-6*a2_3 - 1.8e-5*a1_3 - 1.8e-5*a1_4 - 1.8e-5*a1_5 - 1.8e-5*a1_6 - 1.9e-5*a1_7 - 1.8e-5*a1_8 - 1.7e-5*a1_9 - 1.8e-5*a1_2 + 4.3e-6*a2_4 + 4.4e-6*a2_5 + 4.5e-6*a2_6 + 4.5e-6*a2_7 + 4.4e-6*a2_8 + 4.6e-6*a2_9 + 4.3e-6*a3_4 + 4.4e-6*a3_5 + 4.4e-6*a3_6 + 4.5e-6*a3_7 + 4.4e-6*a3_8 + 4.6e-6*a3_9 + 4.2e-6*a4_5 + 4.2e-6*a4_6 + 4.2e-6*a4_7 + 4.2e-6*a4_8 + 4.3e-6*a4_9 + 4.3e-6*a5_6 + 4.3e-6*a5_7 + 4.3e-6*a5_8 + 4.4e-6*a5_9 + 4.3e-6*a6_7 + 4.3e-6*a6_8 + 4.4e-6*a6_9 + 4.3e-6*a7_8 + 4.4e-6*a7_9 + 4.4e-6*a8_9 - 1.7e-5*a1_10 + 4.6e-6*a2_10 + 4.6e-6*a3_10 + 4.3e-6*a4_10 + 4.4e-6*a5_10 + 4.4e-6*a6_10 + 4.4e-6*a7_10 + 4.4e-6*a8_10 + 4.6e-6*a9_10) - 2.8) + 1.0
Where the coefficients of a(i,j) are different for each equation. So the system of linear inequalities will be constructed as follows:
eqn_nonlin=sym(zeros(10,1));
for i=1:10
eqn_nonlin(i)=mean(abs(eqn_sym{i}/2));
end
c=matlabFunction(vertcat(eqn_nonlin-1,-eqn_nonlin+0.8));
ceq=[];
where I've attached the following output because it exceeds the character limit
>> vpa(eqn_nonlin(1)-1,2)
ans =

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

採用された回答

Matt J
Matt J 2020 年 3 月 25 日
編集済み: Matt J 2020 年 3 月 25 日
Create a wrapper function like the one below. To make it visible from the workspace where patternsearch is called, you can make it a local function or a nested function in the same file, rather than placing it in a separate mfile. Pass the function handle generated by matlabFunction to the wrapper as a fixed parameter:
cFun=matlabFunction(vertcat(eqn_nonlin-1,-eqn_nonlin+0.8));
nonlcon = @(a) nonlconWrapper(a,cFun);
a_optimal = patternsearch(fun,a_Initial,A,b,Aeq,beq,lb,ub, nonlcon );
function [c,ceq]=nonlconWrapper(a,cFun) %This can be a local function
aCell=num2cell(a);
c=cFun(aCell{:});
ceq=[];
end
  1 件のコメント
Ash Ash
Ash Ash 2020 年 3 月 27 日
Thank you!! That's some matlab wizardry that I would have never been able to figure out by myself.

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

その他の回答 (1 件)

darova
darova 2020 年 3 月 25 日
If understood you correctly: you have symbolic expression and wants to convert it to matlab function:
syms a b c
f = b - a - c - 1;
vars = symvar(f);
[A,b] = equationsToMatrix(f,vars)
F = @(x) double(A).*x(1:length(A)) - double(b)
F([1 2 3])
  2 件のコメント
Ash Ash
Ash Ash 2020 年 3 月 25 日
Hi, yes you're right that I have a symbolic expression and I want to convert it to matlabfunction but I have now edited my original post to clarify that it is used for the "nonlcon" input in the function "patternsearch". I apologise for the lack of clarity.
I'm able to convert a symbolic expression into a matlabfunction for my objective function but I don't know how to do it for the nonlinear inequality (nonlcon).
darova
darova 2020 年 3 月 25 日
I think it's too difficult for me. Maybe someone else will have any idea

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

カテゴリ

Help Center および File ExchangeIntroduction to Installation and Licensing についてさらに検索

製品


リリース

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by