# Error using fmincon. Supplied objective function must return a scalar value.

8 views (last 30 days)
AeroEng on 8 Dec 2021
Commented: AeroEng on 11 Dec 2021
The following is my code. I am getting the error shown at the end. I cannot figure out why its displaying this error.
Please help me understand this error. Ive tried alot of things and none of them work. Thank you!
clc;
clear;
close all;
% x = lhsdesign(20,4);% Run at the beginning screen shot result and don't need that anymore
x=[ 13.5870 248.6600 16.4220 15.8350
14.1440 231.7500 15.0310 16.6400
13.7170 233.7000 16.1970 16.9600
14.0000 241.6100 15.6310 15.2910
14.2650 236.0400 15.9950 15.0130
14.6370 237.2000 15.5410 15.5040
14.3380 235.3300 16.6010 15.1400
13.4440 234.6400 16.5310 16.1600
14.8520 247.2200 15.8160 16.7920
13.0300 232.0800 16.7990 16.2290
14.5480 246.9800 15.4450 15.7550
14.4010 242.2100 16.8550 15.9780
13.2170 245.9800 15.1260 15.3330
13.3300 244.6100 15.7880 15.6100
13.9740 249.2500 16.9100 16.0440
14.7580 230.5200 15.3820 16.5030
14.9700 239.7100 15.2430 16.4680
13.8800 240.2600 16.0920 15.4110
13.1850 238.1100 16.3530 16.3200
13.6120 243.5500 16.2870 16.8530];
ub = [15 250 17 17];% determine before FEA
lb = [13 230 15 15];% determine before FEA
x_in = lb+(ub-lb).*x; % Train LHSdesign results so we can control
% parameters in appropriate range
% x_in(:,1) = lb(1) + (ub(1)-lb(1))*x(:,1);
% x_in(:,2) = lb(2) + (ub(2)-lb(2))*x(:,2);
% x_in(:,3) = lb(3) + (ub(3)-lb(3))*x(:,3);
% x_in(:,4) = lb(4) + (ub(4)-lb(4))*x(:,4);
% Creating Random Y-Vector
Deformation_mm = [2.17 1.468 1.687 1.779 1.520 1.665 1.486 1.867 ...
1.489 2.017 1.701 1.660 2.387 2.288 1.965 1.260 ...
1.335 1.860 2.085 1.982]'; % Y_out2
Mass_kg = [1.095 1.0826 1.08058 1.08326 1.08422 1.09308 1.08531 ...
1.07737 1.09688 1.07289 1.09167 1.09018 1.07647 1.07821 ...
1.08759 1.08892 1.09446 1.08253 1.07586 1.08255]'; % Y_out2
rho = 0.9;
%rbf_coeff = [rbf_coeff1,rbf_coeff2]
x0 = lb;
Aeq = [];
beq = [];
A = [];
b = [];
options = optimoptions('fmincon','Algorithm','sqp','Display', ...
'iter-detailed','PlotFcn',@optimplotfval);
k=1;
for w1 = rbf_coeff1
w2 = rbf_coeff2;
[xopt3,fopt3] = fmincon(@objfun,x0,A,b,Aeq,beq,lb,ub, ...
@nonlcon,options,x_in,w1,w2);
[AOF,f] = objfun(xopt3,1,1);
f1(k) = f(1);
f2(k) = f(2);
k = k+1
fprintf('iter: %d,\t f1: %f,\t f2: %f \n',k,f(1),f(2))
end
plot(f1,f2,'o');
xlabel('f1');
ylabel('f2');
xopt = [xopt1; xopt2]';
fopt = [fopt1 fopt2];
Mass_X = xopt(:,1);
Deformation_X = xopt(:,2);
Mass_F = fopt(:,1);
Deformation_F = fopt(:,2);
Design_Vars = {'Beam Diameter';'Beam Length';'Motor Mnt Height';'Motor Mnt Diameter'};
Set_Number = (1:length(x_in))';
Beam_Diameter = x_in(:,1);
Beam_Length = x_in(:,2);
Motor_Mnt_Height = x_in(:,3);
Motor_Mnt_Diameter = x_in(:,4);
FEA_Results = table(Set_Number, Deformation_mm, Mass_kg)
Optimization_for_X = table(Design_Vars, Mass_X, Deformation_X)
Optimization_for_F = table(Mass_F, Deformation_F)
Surrogate_Training = table(Set_Number,Beam_Diameter,Beam_Length, ...
Motor_Mnt_Height, Motor_Mnt_Diameter)
function [aof,f] = objfun(x,x_in,rbf_coeff1,rbf_coeff2)
rho=0.9;
aof = rbf_coeff1*f(1) + rbf_coeff2*f(2);
end
function [c,ceq]=nonlcon(x,x_in,rbf_coeff1, rbf_coeff2)
c(1)=x(1)-5;
c(2)=x(2)-6;
c(3)=x(3)-7;
c(4)=x(4)-8;
% c(5)=x(5)-9;
ceq=[];
end
This is my error:
Error using fmincon (line 640)
Supplied objective function must return a scalar value.
Error in ProjectCode (line 80)
[xopt3,fopt3] = fmincon(@objfun3,x0,A,b,Aeq,beq,lb,ub, ...

Walter Roberson on 8 Dec 2021
for w1 = rbf_coeff1
w2 = rbf_coeff2;
That is not a dual "for" loop !! It does not simultaneously iterate through rbf_coeff1 and rbf_coeff2. It does not iterate through all possible pairs of the two, and it does not iterate through "corresponding" values -- the K'th iteration has w1 = rbf_coeff1(K) but will not have w2 = rbf_coeff2(K) .
MATLAB has no "multiple" for loop. Not anywhere.
Instead, your code is iterating over rbf_coeff1 values into w1, but w2 is being set to be all of the vector rbf_coeff2 .
[xopt3,fopt3] = fmincon(@objfun,x0,A,b,Aeq,beq,lb,ub, ...
@nonlcon,options,x_in,w1,w2);
You are using a syntax that has not been documented in at least 15 years.
In fmincon() and ode*() calls, if you pass in extra parameters after the options, then every call to a user-specified function will have the extra parameters passed in to it. That includes when nonlcon is called -- and it includes when @optimplotfval is called.
Exception: there are some options that need more control parameters than usual, and those control parameters go after the options structure. So in some cases that w1 option would be interpreted as a parameter to some of the work specified by the options. fmincon() and ode*() do not care and will not try to warn you that you might have messed that up: since the ability to pass in extra parameters has not been documented for a long long time, Mathworks considers it to be your fault if something goes wrong when you use it.
Anyhow... with w2 being the full rbf_coeff2 vector, your code
aof = rbf_coeff1*f(1) + rbf_coeff2*f(2);
is going to create a vector because rbf_coeff2 is a vector.
AeroEng on 11 Dec 2021
So i did completely remove the for loop and i am still running into this issue. Any ideas why? I am very confused.
My new code:
clc;
clear;
close all;
x=[ 13.5870 248.6600 16.4220 15.8350
14.1440 231.7500 15.0310 16.6400
13.7170 233.7000 16.1970 16.9600
14.0000 241.6100 15.6310 15.2910
14.2650 236.0400 15.9950 15.0130
14.6370 237.2000 15.5410 15.5040
14.3380 235.3300 16.6010 15.1400
13.4440 234.6400 16.5310 16.1600
14.8520 247.2200 15.8160 16.7920
13.0300 232.0800 16.7990 16.2290
14.5480 246.9800 15.4450 15.7550
14.4010 242.2100 16.8550 15.9780
13.2170 245.9800 15.1260 15.3330
13.3300 244.6100 15.7880 15.6100
13.9740 249.2500 16.9100 16.0440
14.7580 230.5200 15.3820 16.5030
14.9700 239.7100 15.2430 16.4680
13.8800 240.2600 16.0920 15.4110
13.1850 238.1100 16.3530 16.3200
13.6120 243.5500 16.2870 16.8530];
ub = [15 250 17 17];% determine before FEA
lb = [13 230 15 15];% determine before FEA
x_in = lb+(ub-lb).*x; % Train LHSdesign results so we can control
% parameters in appropriate range
% Creating Random Y-Vector
Deformation_mm = [2.17 1.468 1.687 1.779 1.520 1.665 1.486 1.867 ...
1.489 2.017 1.701 1.660 2.387 2.288 1.965 1.260 ...
1.335 1.860 2.085 1.982]'; % Y_out2
Mass_kg = [1.095 1.0826 1.08058 1.08326 1.08422 1.09308 1.08531 ...
1.07737 1.09688 1.07289 1.09167 1.09018 1.07647 1.07821 ...
1.08759 1.08892 1.09446 1.08253 1.07586 1.08255]'; % Y_out2
rho = 0.9;
x0 = lb;
Aeq = [];
beq = [];
A = [];
b = [];
options = optimoptions('fmincon','Algorithm','sqp','Display', ...
'iter-detailed','PlotFcn',@optimplotfval);
[xopt3,fopt3] = fmincon(@objfun3,x0,A,b,Aeq,beq,lb,ub, ...
@nonlcon3,options,x_in,rbf_coeff1,rbf_coeff2);
[AOF,f] = objfun3(xopt3,1,1);
xopt = [xopt1; xopt2]';
fopt = [fopt1 fopt2];
Mass_X = xopt(:,1);
Deformation_X = xopt(:,2);
Mass_F = fopt(:,1);
Deformation_F = fopt(:,2);
Design_Vars = {'Beam Diameter';'Beam Length';'Motor Mnt Height';'Motor Mnt Diameter'};
Set_Number = (1:length(x_in))';
Beam_Diameter = x_in(:,1);
Beam_Length = x_in(:,2);
Motor_Mnt_Height = x_in(:,3);
Motor_Mnt_Diameter = x_in(:,4);
FEA_Results = table(Set_Number, Deformation_mm, Mass_kg)
Optimization_for_X = table(Design_Vars, Mass_X, Deformation_X)
Optimization_for_F = table(Mass_F, Deformation_F)
Surrogate_Training = table(Set_Number,Beam_Diameter,Beam_Length, ...
Motor_Mnt_Height, Motor_Mnt_Diameter)
function [aof,f] = objfun3(x,x_in,rbf_coeff1,rbf_coeff2)
rho=0.9;
rbf_coeff = [rbf_coeff1 rbf_coeff2];
aof = rbf_coeff1*f + rbf_coeff2*f;
end
function [c,ceq]=nonlcon3(x,x_in,rbf_coeff1, rbf_coeff2)
c(1)=x(1)-5;
c(2)=x(2)-6;
c(3)=x(3)-7;
c(4)=x(4)-8;
ceq=[];
end
Thank you so much for your help

R2021a

### Community Treasure Hunt

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

Start Hunting!