Use of fmincon with objective function as m-file

4 views (last 30 days)
I am finding parameters for a model. I thought the best thing was to define the objective function that I wiah to minimise as
function y=objective_fn(V_exp,V_calc,t)
%This is the objective function
N=length(t); %gets length of vectors
%define the weight of the objective function to concentrate on a particular
%feature
w=ones(1,N);
y=trapz(t,(V_exp.*w-V_calc).^2);
So the minimum is where the V_calc is very close to V_exp, which is experimental data we have. Now V_calc is given by:
function V=volt(O_plus,O_minus,X,L_a,L_c,I_app,t)
%Compute the lithium concentration in each of the
r=linspace(0,1,100);
D_a=X(1);
D_c=X(2);
u_0_a=X(3);
u_0_c=X(4);
k_a=X(5);
k_c=X(6);
alpha_a=X(7);
alpha_c=X(8);
c_a_max=X(7);
c_c_max=X(8);
c_a_full=spherical_fd(u_0_a,I_app/L_a,D_a,D_a,r,t);
c_a=c_a_full(:,end);
c_c_full=spherical_fd(u_0_c,I_app/L_c,D_c,D_c,r,t);
c_c=c_c_full(:,end);
%Compute Voltage
V=O_plus(c_c)+eta_SPM(c_c,k_c,c_c_max,T,-alpha_c*I_app/L_c)-(O_minus(c_a)+eta_SPM(c_a,k_a,c_a_max,T,alpha_a*I_app/L_a));
To use this objective function, would I need to incorporate them into one big function? The parameters I wish to optimise are contained in the vector X, O_plus/O_minus are fixed rational functions of c_c, and c_a, t is time, I_app, L_a and L_c are constant. I'm a bit confused how to fit these functions into fmincon.

Accepted Answer

John D'Errico
John D'Errico on 23 Jan 2023
Easy enough. The simple way, assuming all of the variables: {O_plus,O_minus,L_a,L_c,I_app,t} are defined in your workspace, is to create a function handle. So we could do this:
Vcalcfun = @(X) volt(O_plus,O_minus,X,L_a,L_c,I_app,t);
You should see that we can now evaluate this function handle as a function of the only unknown vector X. It will return a vector V, I assume? That should be true from your statements.
Now, your objective function is not how you have written it. The objective to fmincon should have only one unknown (vector) in it.
Why you feel the need to use a weight vector of ALL ones is pretty strange to me. But you can feel free to waste CPU cycles I guess. Your money.
Vobj = @(X) trapz(t,(V_exp.*ones(1,length(t))-Vcalcfun(X)).^2);
Now just call fmincon with Vobj as the objective. EVERYTHING it needs is encapsulated in those two function handles. I assume there is some reason why you want to use fmincon, else you would just be using other tools, perhaps fminunc. So I presume there are equality or inequality constraints between the parameters in X. Again, your choice to write inefficient code otherwise.
  2 Comments
Matthew Hunt
Matthew Hunt on 23 Jan 2023
I don't consider code to be efficient or inefficient, only clear or unclear. Many cases of efficient code is unreadable code, so it only is usable by the guy who wrote it. When you need to share your code around, you need clear code.
John D'Errico
John D'Errico on 23 Jan 2023
How is it more clear to have additional variables that perform no purpose at all? In that case, you should probably define dozens of meaningless variables, serving no purpose at all. But it would make your code more clear?
Whatever floats your boat, I guess. :)

Sign in to comment.

More Answers (1)

Matt J
Matt J on 23 Jan 2023
Edited: Matt J on 23 Jan 2023
One way is to wrap the functions in an anonymous function:
fun=@(X) objective_fn(V_exp, volt(O_plus,O_minus,X,L_a,L_c,I_app,t) ,t); %anonymous function
x=fmincon(fun,x0,...)

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!