# Linears equations summation+combination optimization

4 views (last 30 days)
Jordan Verhofstadt on 18 Oct 2019
Edited: Alberto Chavez on 21 Mar 2020
Hello, I'm trying to create a code which can optimize a function of type :
Where , , a, b are all known constants ; t is the time vector which is given for a certain length ; are both parameters vectors I want to optimize. u() is the heaviside function.
The point is to minimize "subplus(diff(V))" with constraints, in other words minimize the slope of the function while I'm keeping it between two values Vmin and Vmax
In this example (which is the kind not wanted after the optimization) the B and E point's X coordinates are the values in the vector and D, H the . Vmax is equal to 120 and Vmin = 20.
I know the optimization of this function here isn't useful (only need to put all points of and as late as possible) but I did not present you the whole equation to optimize (don't need it).
My problem is where to begin on matlab.. ga, fmincon, fminbnd... How to translate constraints with Vmax and Vmin with matlab. Could someone help ?
Edit:
I tried that :
clear;close;clc;
Param=[2.86 148 2 90 120];
t=linspace(1,7000,7000);
conso=Param(1);
Ttour=Param(2);
Travit=Param(3);
Tpit=Param(4);
Reservoir=Param(5);
global t conso Ttour Travit Tpit Reservoir
p1=[];
p2=[];
optim=fmincon(@(p1,p2)ObjFun,[3600,3800],[],[],[],[],[],[],@constraintsFun);
function f_v = ObjFun(p1,p2)
global t conso Ttour Travit Tpit Reservoir
Ess=zeros(1,length(t));
Rem=zeros(1,length(t));
for i=1:length(p1) %conso/Ttour = delta(V) 1/Travit=a Tpit=b
Ess=Ess+conso/Ttour.*(t-p1(i)).*heaviside(t-p1(i))+1/Travit.*(t-(p1(i)+Tpit)).*heaviside(t-(p1(i)+Tpit));
end
for i=1:length(p2)
Rem=Rem+1/Travit.*(t-p2(i)).*heaviside(t-p2(i))+conso/Ttour.*(t-p2(i)).*heaviside(t-p2(i));
end
f_v=subplus(diff(Reservoir-conso/Ttour.*t+Ess-Rem));
end
function [c,ceq]=constraintsFun(p1,p2)
global Reservoir
vol=ObjFun(p1,p2);
for i=1:length(vol)
c=[];
ceq=[6-vol(i),vol(i)-Reservoir];
end
end
But I got
Not enough input arguments.
Error in Volt>ObjFun (line 29)
for i=1:length(p1)
Error in Volt>@(p1,p2)ObjFun
Error in fmincon (line 546)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in Volt (line 23)
optim=fmincon(@(p1,p2)ObjFun,[3600,3800],[],[],[],[],[],[],@constraintsFun);
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
I know the problem comes from the x0 initial point and I suppose it's because p1 and p2 are vectors with variable length but I don't know how to resolve this.
Hope someone can help me.

#### 1 Comment

John D'Errico on 19 Oct 2019

John D'Errico on 21 Mar 2020
Let me see. The use of globals here is unecessary, better would have been to use anonymous functions. Globals just complicate how variables get passed around, and make debugging code more difficult. But global variables did not cause the problem. It is just a programming style thing that people learn to dispose of when they learn to use functions properly.
Next, there is the problem that by creating a function with break points, as they move around the problem becomes non-differentiable. And fmincon does not perform well on non-differentiable problems. It can survive, but GA might be a better choice. Again, this is not a major problem, but possibly a minor one.
That all still leave the question begging an answer. Why did fmincon get upset and fail? The failure is a simple one. Fmincon was told there was an unknown vector, of length 2. And this is how fmincon works, as do all optimizers. If you have two unknowns, then you need to have a VECTOR of length 2 as the set of unknown parameters.
But the objective function was written as a function of TWO variables, p1 and p2, NOT a VECTOR of length 2, which would be one variable.
So what was the error message?
"Not enough input arguments."
fmincon understands the function will be passed ONE argument, here, a vector of length 2. How you want to use that vector is up to you.
When you have a problem like this, you need to write the objective function like this:
function f_v = ObjFun(P12)
p1 = P12(1);
p2 = P12(2);
% stuff done here to compute f_v
...
end
And that is why fmincon failed, at least that was the immediate cause of failure. There may indeed be other problems in the code, but to completely debug it would require knowledge of what the code should be doing. It would force me to spend a great deal of time to get into the head of the OP, to understand what they wanted to do, to unravel how they were writing this code, and what they wanted to do, and how to fix it to compute what they wanted to see. Sorry, but that is a great deal of depth.

Jordan Verhofstadt on 21 Mar 2020
Hi, thanks for answering my question.
But since I posted it on this forum in october, I've made a lot of changes.
I don't use fmincon anymore but the genetic algorithm. The code starts to do what I'm asking but I'm still having some issues when the number of parameters increases too much. I didn't work on this code for a while (I'm a student and it doesn't fit into my studies so I don't have a lot of time for it..) but if you want I can explain what I did.
Maybe someone will be able to help me now.
Alberto Chavez on 21 Mar 2020
The problem with GA is that they don't perform very well with higher complexity, specially with the Pm because you have more elements subjected to mutation; among other things. But for example, if you could provide a sufficient optimized answer with a GA, maybe try to combine it with another optimization solver and provide it with a starting point derived from the GA, an hybrid method so to speak.

Alberto Chavez on 21 Mar 2020
Edited: Alberto Chavez on 21 Mar 2020
It is possible that the lack of input arguments comes from:
p1=[];
p2=[];
There, you have nothing to optimize, perhaps if you rewrite your code so that everything you need as an input it's already established and then run the solver.
Edit: But if that is the way the algorithm must be wrotten then instead of providing the initial point as is: [3600,3800], perhaps running a script to consider the lenght of p1 and p2 like:
initial_point=[3600*ones(length(p1)),3800*ones(length(p2))]
and then make the "fmincon" function to call that initial point?

#### 1 Comment

John D'Errico on 21 Mar 2020
No. That is not at all the problem, but the problem is a complicated one to explain, so probably why nobody ever decided to try an answer.
In fact, the code has many issues that are causing it to fail. I'll see if I can offer a few of them in an answer, that is too late to be of any real help to the OP.