Error Not enough input arguments using Fmincon with nlcon and linear constraints
Show older comments
I am trying to minimize a function say fun using fmincon, it has 18 elements, having linear and non-linear constraints. linear constraints are applied on solution s, s(1) to s(7). and 2 nonlcon constraints are applied on solution s(8) to s(18).optimization is good for linear constraints but shows error using nonlcon function(@test3), not enough input arguments.
C_test_43.csv, file is required to run this code, it is attached with.
% code
clc
clear
M = csvread('C_test_43.csv');
time=50;
C=M(1:time);
Cmax=max(C);
T=10;
n=time/T;
X=zeros(1,n);
X(1,1)=8;
x=zeros(1,time);
x(1,1)=8;
E=1+(25-1).*rand(1,time);
batcharg=1;
Ve=(25-(2*batcharg))/Cmax;
Vt=(25-(2*batcharg))/Cmax;
V=(25-(2*batcharg))/Cmax;
m=11;
fr = 0 + (16.8*10^9-0).*rand(m,time);
fmax=max(fr);
fmax=max(fmax);
p = 0 + (2*10^-3-0).*rand(m,time);
pmax=max(p);
pmax=max(pmax);
Q=rand(1,time);
QD=rand(1,time);
a=0.1;
bb=0.025;
k=7.8*10^-21;
L=6400;
Hm=-50 + (-75-50).*rand(m,time);
phi=0.1;
w=1*10^6;
N=-174;
tau=1;
DL=tau.*fr./L;
D=w.*tau.*log2(1+(Hm.*p)/N.*w);
Td=0+(20-0).*rand(1,time);
vlb=zeros(1,m+7);
vub=zeros(1,m+7);
num=m+7;
energy_ub=1500;
f=zeros(1,num);
% code
fun=@(s)f;
for t=1:time
n=ceil(t/T);
freq=fr(1:m,t);
f(1,1)=X(n);
f(1,2)=x(t);
f(1,3)=V.*C(n);
f(1,4)=Q(t);
f(1,5)=QD(t);
f(1,6)=Ve;
f(1,7)=Vt;
for u=8:m+7
f(1,u)=min(DL(u-7,t)+D(u-7,t),D(u-7,t)+D(u-7,t));
end
i=1;
j=m+7;
Aeq=ones(i,j);
for j=8:m+7
Aeq(i,j)=-1;
end
beq=1;
for j=8:m+7
vlb(j)=0;
vub(j)=fmax;
end
vlb(1)=-batcharg;
vub(1)=batcharg;
vlb(2)=-1;
vub(2)=1;
vub(3)=energy_ub;
vlb(4)=-1;
vub(4)=1;
vlb(5)=-1;
vub(5)=1;
vlb(6)=0;
vub(6)=1000;
vlb(7)=0;
vub(7)=20;
if X(n)>-V*C(n)
vub(1)=1;
else
vlb(1)=-1;
end
if x(t)>-V*C(t)
vub(2)=1;
else
vlb(2)=-1;
end
if Q(t)>-Ve*E(t)
vub(4)=1;
else
vlb(4)=0;
end
if QD(t)>-Vt*Td(t)
vub(5)=1;
else
vlb(5)=0;
end
nonlcon = @test3;
[s,fval]=fmincon(fun,freq,[],[],Aeq,beq,vlb,vub,nonlcon(tau,L,m));
% function for 2 non linear constraints
function [c,ceq] = test3(s,tau,L,m)
for n=8:m+7
ceq(1) =tau.*(s(n)/L);
ceq(2)=w(n).*tau.*log2(1+(Hm.*p)/N.*w(n));
end
c = [];
end
1 Comment
Walter Roberson
on 1 Nov 2018
Search for Paramaterizing Functions
Answers (1)
Nicolas Schmit
on 2 Nov 2018
1 vote
There are several problems in your code
- You must pass the optimization variable as a argument to the nonlinear constraints.
- The size of Aeq, Beq, vlb and vub do not match the size of the freq vector.
- The cost function must return a scalar.
I suggest you have a look at the examples in the documentation of fmincon.
5 Comments
ikram shahzad
on 2 Nov 2018
Walter Roberson
on 2 Nov 2018
You have
f=zeros(1,num); %for m apps,1 row and 4m coloumns, variables to be found.
fun=@(s)f; %to use non linear constraint
This says that no matter what the input is, a vector of zeros is to be returned.
You then store other things into f, but those will be ignored: when you define an anonymous function with reference to a variable, then the value of the variable is captured as of the time the anonymous function is defined.
If you were to move the
fun=@(s)f; %to use non linear constraint
to just before
[s,fval]=fmincon(fun,xo,[],[],Aeq,beq,vlb,vub,nonlcon(xo,tau,L,m)); %s=[Rn,Rtau,Hn,DL,DO,Bn,bt,Pm]
then the changed value of f would be captured and returned when the function was invoked. However, fmincon requires that the function return a scalar value.
You also have
nonlcon = @test3; %non linear constraints
and you have
[s,fval]=fmincon(fun,xo,[],[],Aeq,beq,vlb,vub,nonlcon(xo,tau,L,m)); %s=[Rn,Rtau,Hn,DL,DO,Bn,bt,Pm]
so test3 will be invoked once with xo, tau, L, m and would be expected to return a function handle that could be invoked each time to test whether the current variables met the constraints. However, test3 returns a numeric value, not a function handle.
You could try
fun = @(s) 0;
[s,fval]=fmincon(fun, xo, [], [], Aeq, beq, vlb, vub, @(s) nonlcon(s,tau,L,m)); %s=[Rn,Rtau,Hn,DL,DO,Bn,bt,Pm]
This will at least execute, though ignoring all of the values you carefully placed into f.
Note: we also see in ctp3 that you have
sum=0;
and we see in test3 that you have
ceq = sum(ceq.^2);
Was the intention that ceq should result in 0? Since you defined sum as 0?
It is not a syntax error to define sum as a variable, but you can be very sure that defining sum as a variable will confuse people reading your code. If you continue to use sum as the name of a variable, sooner or later you will encounter a situation where you try to use sum as a function in the context where it is a variable, and then you will get rather confused as you try to figure out what is happening.
ikram shahzad
on 3 Nov 2018
Edited: Walter Roberson
on 3 Nov 2018
Walter Roberson
on 3 Nov 2018
You still have
fun=@(s)f;
which tells it to ignore the input s and to always return the content of f, a constant vector. Are you sure that is what you want to do? Is your purpose to try to find a point that violates the constraints the least -- that you do not actually care about the return value of myfun and only want to try to figure out where some points are that (nearly) satisfy the constraints?
Perhaps you want something like
fun = @(s) f*s;
??
ikram shahzad
on 4 Nov 2018
Categories
Find more on Linear Predictive Coding in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!