# "fmincon" optimization with nonlinear constraints: colon error

3 views (last 30 days)
Amalia Diaz on 29 Jul 2019
Edited: Matt J on 30 Jul 2019
Hello!
This is my second post for the same topic (solar production with an hourly resolution over 15 years), but I have a different question this time. Thanks in advance for the help! Here's the issue:
I have an objective function that I can solve with fmincon (I think), only one nonlinear equality constraint and variable bounds. My variable is Cpv and it will be a single number, not an array.
Function = @ObjFun3; %Saved in the same directory with filename=function name
nonlinconst = @PVnonlincon; %Saved in the same directory with filename=function name
[Cpv,fval] = fmincon(Function,10000,[],[],[],[],0,10000,nonlinconst);
If I eliminate the nonlincon arguement, fmincon finds a solution (which is obviously not sufficient, I just wanted to check where the problem is). The error I am getting is:
Input arguments to function include colon operator. To input the colon
Error in fmincon (line 651)
initVals.nceq = ceqtmp(:);
Error in Opt3 (line 29)
[Cpv,fval] = fmincon(Function,10000,[],[],[],[],0,10000,nonlinconst);
Do I have a conceptual error somewhere, or a command that I cannot use when declaring a function, or an argument that fmincon doesn't accept?
ObjFun3 is defined as:
function [OF] = ObjFun3(Cpv)
Cn = 10000;
r = size(DataW,1);
Pw = DataW(r,1,1);
N = Cn .* ones(size(Pw));
NinjaPV = DataPV(r,1,Loc);
function F = Fed_pv(Cpv)
F = min((NinjaPV.*Cpv/1000), (N-Pw));
end
OF = sum(N - Pw - Fed_pv(Cpv), 'all');
end
And PVnonlincon is defined as:
function [c_ineq,c_eq] = PVnonlincon(Cpv)
Cn = 10000;
r = size(DataW,1);
Pw = DataW(r,1,1);
N = Cn .* ones(size(Pw));
NinjaPV = DataPV(r,1,Loc);
c_ineq = [ ];
Anonymous = @(Cpv) Fed_Pv(Cpv) + NotFed(Cpv) - NinjaPV*(Cpv);
c_eq = Anonymous;
function NF = NotFed(Cpv)
NF = max(0,(NinjaPV*Cpv/1000)+Pw-N);
end
function F = Fed_Pv(Cpv)
F = min((NinjaPV*Cpv/1000), (N-Pw));
end
end

#### 1 Comment

Matt J on 29 Jul 2019
My variable is Cpv and it will be a single number, not an array.
If Cpv is a scalar, then fmincon is overkill. You should really just use fminbnd.
Also, I think there must be a mistake in your nonlinear constraints. Your equality constraint function "Anonymous" is piecewise linear in Cpv, which means it can only have a finite number of roots (at most 3 in this case) unless the slope of some piece is zero over some interval. But that doesn't look possible here unless you really meant,
Anonymous = @(Cpv) Fed_Pv(Cpv) + NotFed(Cpv) - NinjaPV*(Cpv)/1000;

Matt J on 29 Jul 2019
Edited: Matt J on 29 Jul 2019
You are returning a function handle in c_eq, when really you should be evaluating the function at Cpv,
c_eq = Anonymous(Cpv);
Aside from that, however, both your objective and constraints are non-differentiable functions, and so are outside the scope of what fmincon can handle. You should probably use ga() instead.

Amalia Diaz on 30 Jul 2019
Thank you! That fixed the colon error. And I also corrected the mistake you pointed out in the comment. It is sometimes frustrating to start using a new software, but at least you guys are there to point out the not-so-obvious-obvious things.
fminbnd is perhaps not an option, given the non-differentiable functions. I will try with ga(), although it's taking very long to find a solution with the same inputs and results in:
Optimization terminated: average change in the fitness value less than options.
FunctionTolerance and constraint violation is less than options.ConstraintTolerance.
Matt J on 30 Jul 2019
fminbnd is perhaps not an option
No, actually fminbnd shouldn't care about differentiability.
ga() can struggle with non-linear equality constraints, I seem to recall, and that may be why you see slow behavior. But there is no reason you should have non-linear constraints in a 1D minimization problem. In 1D, all relevant constraints can be expressed as simple upper and lower bounds, a<=x<=b.