fmincon should return a scalar value error

Hello,
I am trying to do an optimization for a function using a "fmincon". I have got an error and couldn't solve it. Error is
Error using fmincon (line 619)
Supplied objective function must return a scalar value.
Error in PVL_TestScript (line 8)
xopt= fmincon(@objective, x0, [],[],[],[],[],[],@constraint)
My whole program is as follows:
%Define Initial Guess
TiltGuess = 1
%Load Guess values into the array
x0 = [TiltGuess];
%Call solver to minimize the objective function
xopt= fmincon(@objective, x0, [],[],[],[],[],[],@constraint) %Line 8
%Retrieve Optimized sizing values for power
ACPoweropt = TestScript(xopt)
%Define function to calculate AC Power
function ACPower = TestScript(x)
ModuleParameters = pvl_sapmmoduledb(123,'SandiaModuleDatabase_20120925.xlsx');
load('SandiaInverterDatabaseSAM2014.1.14.mat');
Inverter = SNLInverterDB(793);
clear InverterNames SNLInverterDB
Tilt = x(1); % Array tilt angle (deg)
Azimuth = 180; %Array azimuth (180 deg indicates array faces South)
Ms = 10; %Number of modules in series
Mp = 1; %Number of paralell strings
a = -3.56;
b = -0.075;
TMYData = pvl_readtmy3('723650TY.csv');
TimeMatlab = TMYData.DateNumber;
Time = pvl_maketimestruct(TimeMatlab, ones(size(TimeMatlab))*TMYData.SiteTimeZone);
DNI = TMYData.DNI;
DHI = TMYData.DHI;
GHI = TMYData.GHI;
Location = pvl_makelocationstruct(TMYData.SiteLatitude,TMYData.SiteLongitude,TMYData.SiteElevation) %Altitude is optional
PresPa = TMYData.Pressure*100; %Convert pressure from mbar to Pa
[SunAz, SunEl, AppSunEl, SolarTime] = pvl_ephemeris(Time,Location,PresPa,TMYData.DryBulb);
AMa = pvl_absoluteairmass(pvl_relativeairmass(90-AppSunEl),PresPa);
AOI = pvl_getaoi(Tilt, Azimuth, 90-AppSunEl, SunAz);
Eb = 0*AOI; %Initiallize variable
Eb(AOI<90) = DNI(AOI<90).*cosd(AOI(AOI<90)); %Only calculate when sun is in view of the plane of array
EdiffSky = pvl_isotropicsky(Tilt,DHI);
Albedo = 0.2;
EdiffGround = pvl_grounddiffuse(Tilt,GHI, Albedo);
E = Eb + EdiffSky + EdiffGround; % Total incident irradiance (W/m^2)
Ediff = EdiffSky + EdiffGround; % Total diffuse incident irradiance (W/m^2)
SF=0.98;
E0 = 1000; %Reference irradiance (1000 W/m^2)
celltemp = pvl_sapmcelltemp(E, E0, a, b, TMYData.Wspd, TMYData.DryBulb, ModuleParameters.delT);
F1 = max(0,polyval(ModuleParameters.a,AMa)); %Spectral loss function
F2 = max(0,polyval(ModuleParameters.b,AOI)); % Angle of incidence loss function
Ee = F1.*((Eb.*F2+ModuleParameters.fd.*Ediff)/E0)*SF; %Effective irradiance
Ee(isnan(Ee))=0; % Set any NaNs to zero
mSAPMResults = pvl_sapm(ModuleParameters, Ee, celltemp);
aSAPMResults.Vmp = Ms *mSAPMResults.Vmp;
aSAPMResults.Imp = Mp *mSAPMResults.Imp;
aSAPMResults.Pmp = aSAPMResults.Vmp .* aSAPMResults.Imp;
ACPower = pvl_snlinverter(Inverter, mSAPMResults.Vmp*Ms, mSAPMResults.Pmp*Ms*Mp);
end
% Define a objective function for optimization
function obj = objective (x)
obj = -TestScript(x);
end
%Define constriant for optimization
function [c,ceq] = constraint (x)
c = [];
ceq = [];
end
I'd appreciate if somebody would help with this issue.
Thank you.

8 commentaires

Alan Weiss
Alan Weiss le 16 Mai 2019
I didn't test anything, but what do you get when your run objective(x0)?
Alan Weiss
MATLAB mathematical toolbox documentation
After changing objective (x) to objective (x0), I'm still receiving the same error.
This looks like it might require PV_LIB from sandia.gov ? (Which requires registration)
PV_LIB Toolbox is open source code.
Thank you for your quick reply.
Matt J
Matt J le 16 Mai 2019
Modifié(e) : Matt J le 16 Mai 2019
What is Testscript(x) (which we don't have) supposed to return? Is it a scalar, or not?
Laxmikant Radkar
Laxmikant Radkar le 16 Mai 2019
Modifié(e) : Laxmikant Radkar le 16 Mai 2019
Actually initially myfile name was similar to the function name, however matlab showed the error that it shouldn't be the same so I changed it to just Testscript(x). I'm expecting it to return ACPower = pvl_snlinverter(Inverter, mSAPMResults.Vmp*Ms, mSAPMResults.Pmp*Ms*Mp);
AC Power reetuns 8760*1 value
I have been faily new with the optimization toolbox and functions. So if I'm have done any mistakes please let me know.
I am not "Commercial/Industry", "Government", "University", or "National Lab" and so cannot fill out the registration form.
No problem Walter. I appreciate your quick responses. I'm trying to figure out what's wrong and once I cmplete it I'll let you know. Thanks again

Connectez-vous pour commenter.

 Réponse acceptée

Matt J
Matt J le 17 Mai 2019
Modifié(e) : Matt J le 17 Mai 2019

0 votes

AC Power reetuns 8760*1 value
If you know that your objective function code is returning a 8760x1 value, it should be pretty clear what is wrong. The error message has told you that it should be returning a scalar instead. What does it even mean to "minimize" a 8760x1 value?

1 commentaire

In this case when I take a mean of AC Power, MATLAB returns me a single value and program runs smoothly without any error by providing me the expected results.
Thanks for the help and you quicj reponses.

Connectez-vous pour commenter.

Plus de réponses (1)

Nazam Ali
Nazam Ali le 15 Oct 2020
Hello, I am new to MATLAB coding and I am trying to do optimization using fmincon function and I am receiving following error:
years =
[]
Error using fmincon (line 619)
Supplied objective function must return a scalar value.
Error in Main_code3 (line 47)
[x,fval,exitflag] = fmincon(operator_profit,x0,A,b,Aeq,beq,lb,ub,confunxval);
While my whole code is as follows:
clear
clc
% -----------------------------------------------------------------------%
% Parameters Setting
theta = 0.1;
demand = 5000;
alpha = 500;
beta = 400;
bus_fare = 100;
bus_fuel_cost = 200;
distance_travelled = 10;
a0 = 4000;
x = [];
% Calculation of Mathematical Expressions
% -----------------------------------------------------------------------%
bus_probability = exp(-theta * (1./x) * alpha + beta);
passenger_flow = demand * bus_probability;
car_probability = 1 - bus_probability;
bus_operation_cost = a0 + distance_travelled * bus_fuel_cost;
% Objective Function to Maximize the Bus Operator Profit
% -----------------------------------------------------------------------%
operator_profit = @(x)...
(demand .*...
((exp(-theta * (1./x) * alpha + beta))...
/(exp (-theta * (1./x) * alpha + beta)) + (1 - car_probability))...
* (distance_travelled * bus_fare)...
- ((a0 + distance_travelled * bus_fuel_cost) *x));
real(operator_profit(20))
A = [];
b = [];
Aeq = [];
beq = [];
lb = 1;
ub = 200;
x0 = 4;
confunxval = @(x) confun(x,demand,theta,passenger_flow,alpha,car_probability,beta,a0,distance_travelled, bus_fare,bus_fuel_cost);
[x,fval,exitflag] = fmincon(operator_profit,x0,A,b,Aeq,beq,lb,ub,confunxval);
I will really appreciate if someone can help. Thank you!
Nazam

9 commentaires

Stephen23
Stephen23 le 15 Oct 2020
Modifié(e) : Stephen23 le 15 Oct 2020
This should be a very big clue:
>> operator_profit(20)
ans = []
Given a scalar input your function returns an empty array. These lines need to be checked:
x = []; % most likely this is not useful.
...
bus_probability = exp(-theta * (1./x) * alpha + beta);% returns an empty array
% ^ oh no, empty!
Because bus_probability is empty all of your calculations using it will return empty arrays.
Nazam Ali
Nazam Ali le 16 Oct 2020
Modifié(e) : Nazam Ali le 16 Oct 2020
@Stephen. Thank you so much for your comment. But, all other inputs in bus_probability are not empty. So, don't know why it is returning empty value??
Stephen23
Stephen23 le 16 Oct 2020
Modifié(e) : Stephen23 le 16 Oct 2020
"But, all other inputs in bus_probability are not empty. So, don't know why it is returning empty value??"
As I wrote in my last comment, the function operator_profit returns an empty output because x is empty... which means that bus_probability is empty, which means that passenger_flow is empty and car_probability is also empty. Of course you don't need me to tell you this, you can easily check them yourself.
The MATLAB documentation specifies what happens when arrays of different sizes are used in arithemtic operations:
For binary operators given one scalar input and one non-scalar input the output will take the size of the non-scalar input. Hence the operation using empty x returns empty array, and this size gets passed down through the rest of your operations.
Thank you for your comment, I checked the code again. There were some other issues as well in the code. However, "x" is the varible around which I want to optimize my function. Therefore, I put it empty in the start, because it is necessary to define a variable before it is input in the main function. Here is the revised code line:
operator_profit = @(x)...
(demand .*...
(exp(-theta * ((1./x) * alpha + beta + bus_fare))...
/(exp(-theta * ((1./x) * alpha + beta + bus_fare)) + exp(-theta * car_travelling_cost_const)))...
* (distance_travelled * bus_fare)...
- ((a0 + distance_travelled * bus_fuel_cost) *x));
Still it is showing this error:
ans =
4880000
Not enough input arguments.
Error in confun (line 9)
+ distance_car * bus_fuel_cost + car_parking_fee)));
Error in
Main_code3>@(x)confun(x,demand,theta,passenger_flow,alpha,car_probability,beta,a0,distance_travelled,bus_fare,bus_fuel_cost,car_travelling_cost_const)
Error in fmincon (line 633)
[ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
Error in Main_code3 (line 50)
[x,fval,exitflag] = fmincon(operator_profit,x0,A,b,Aeq,beq,lb,ub,confunxval);
Caused by:
Failure in initial nonlinear constraint function evaluation. FMINCON cannot continue.
Stephen23
Stephen23 le 16 Oct 2020
Modifié(e) : Stephen23 le 16 Oct 2020
"However, "x" is the varible around which I want to optimize my function."
But confusingly you used x twice in your code:
  1. as a variable in your script which is used to define bus_probability (this is the empty x).
  2. as an input argument to the anonymous function operator_profit (its value is defined by the ODE solver routine).
These are quite unrelated to each other.
"Therefore, I put it empty in the start, because it is necessary to define a variable before it is input in the main function."
No, that is not required. Inputs to functions can be simply defined/supplied when the function is called.
"Still it is showing this error:"
If you show the complete code then someone can probably help to debug it.
Nazam Ali
Nazam Ali le 16 Oct 2020
Modifié(e) : Nazam Ali le 16 Oct 2020
Stephen,
Thank you so much for your comment. Here is the complete code for your kind reference.
clear
clc
% -----------------------------------------------------------------------%
% Parameters Setting
theta = 0.1;
demand = 5000;
alpha = 500;
beta = 400;
bus_fare = 100;
bus_fuel_cost = 200;
car_travelling_cost_const = 1000;
distance_travelled = 10;
a0 = 4000;
x = [];
% Calculation of Mathematical Expressions
% -----------------------------------------------------------------------%
bus_probability = exp(-theta * ((1./x) * alpha + beta + bus_fare))...
/(exp(-theta * ((1./x) * alpha + beta + bus_fare)) + exp(-theta * car_travelling_cost_const));
car_probability = exp(-theta * car_travelling_cost_const)./(exp(-theta * car_travelling_cost_const)...
+ exp(-theta * ((1./x) * alpha + beta + bus_fare)));
passenger_flow = demand * bus_probability;
bus_operation_cost = a0 + distance_travelled * bus_fuel_cost;
% Objective Function to Maximize the Bus Operator Profit
% -----------------------------------------------------------------------%
operator_profit = @(x)...
(demand .*...
(exp(-theta * ((1./x) * alpha + beta + bus_fare))...
/(exp(-theta * ((1./x) * alpha + beta + bus_fare)) + exp(-theta * car_travelling_cost_const)))...
* (distance_travelled * bus_fare)...
- ((a0 + distance_travelled * bus_fuel_cost) *x));
real(operator_profit(20))
A = [];
b = [];
Aeq = [];
beq = [];
lb = 1;
ub = 200;
x0 = 4;
confunxval = @(x) confun(x,demand,theta,passenger_flow,alpha,car_probability,beta,a0,distance_travelled, bus_fare,bus_fuel_cost, car_travelling_cost_const);
[x,fval,exitflag] = fmincon(operator_profit,x0,A,b,Aeq,beq,lb,ub,confunxval);
Please let me know if you still any further information. Thank you!
Stephen23
Stephen23 le 16 Oct 2020
Modifié(e) : Stephen23 le 16 Oct 2020
@Nazam Ali: you still define x=[], which is the (main obvious) bug in your code.
As I wrote in my first comment, most likey that x is not useful. Judging by the changes you made to your code, it is possible that anything with an x term in it should be a function in x (just like operator_profit). But only you know the algorithm that you are trying to encode (I certainly don't).
@Stephen,
I agree with you. But, I put "x" as a replacement of another term to make it simple. If I don't define x = []; it shows the following error:
Undefined function or variable 'x'.
Error in Main_code3 (line 19)
bus_probability = exp(-theta * ((1./x) * alpha + beta + bus_fare))...
Which means that I need to define "x" to debugg this error.
Thank you!
Stephen23
Stephen23 le 16 Oct 2020
"Which means that I need to define "x" to debugg this error."
Or, as I wrote in my previous comment, you need to define all of those formulas as anonymous functions.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Linear Programming and Mixed-Integer Linear Programming dans Centre d'aide et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by