I do not understand exit message given by lsqnonlin,

Hello everyone, I'm trying to do an estimation of parameter based on simulink electric circuit. My goal is minimize the error between simulated voltage and real one.
I wrote a code that runs different simulations in an iterative way in order to find parameter that are able to fit different measurements. I'm using lsqnonlin. I tried with fmincon, but since my object function is sum((Vsim-Vreal).^2) it seems to make more sense use lsqnonlin and change object function in (V_sim-V_real). The code runs and the cost function decreases (while remaining very high).
The optimization stop with this message: "fmincon stopped because the size of the current step is less than the value of the step size tolerance and constraints are satisfied to within the value of the constraint tolerance." but I can't understand why it refers to fmincon and why it says that about the current step since step tolerance is setted at 1e-8, and display iter shows 5.088e+01 as norm of step.
I also noticed that sometimes it stops because it evaluates a negative parameter (as resistance, and simulink automatically stop everything) also if i set boundaries and constraints in order to avoid that
I attach here the main code, avoiding all the import data and the initializations of different variables that runs with no problem .Hope someone is able to help me solving this. Thank you in advance for your time
while true
x0=x_in; %set initial guess
V_sim_tot=cell(length(data_sets)); %Initialize the vector in order to save all the V simulated
for i=1:length(data_sets) %Performing the optimization for the number of datasets I'm working with
I=[data_sets{i}.time,data_sets{i}.current]; %take into consideration current of the actual dataset. This will be input for simulink model
V_real=data_sets{i}.V_real; %Take into consideration real voltage for each datasets in order to perform optimization
assignin('base','V_0',v_in_C0(i)); %it assign the right initial voltage to C0 of the simulink model
%Define nested function
y = @(x) objectiveFunction(x, V_real);
cfun = @(x) myNonlinearConstraints(x);
% call optimization lsqnonlin
[x, exitflag, output] = lsqnonlin(y, x0,lb,ub,A , b, [], [], cfun, opts);
x0=x;
V_sim_tot{i}=V_sim; %Save final voltage for each datasets
end
iter=iter+1; %advance with iterstions
%Evaluating different conditions for stopping criteria
if ( (iter>min_iter) && (norm(x_in-x0)<=tol) ) %if the code have done enough iteration(>min_iter) and if the n
x_opt=x0;
disp('Optimal vector is not changing')
break
elseif (iter>max_iter)
x_opt=x0;
disp('Maximum iterations reached')
break
else
x_in=x0;
end
end
function [c1,c2,c3,c4,c5,c6,ceq] = myNonlinearConstraints(x)
V_sim= evalin('base','V_sim');
Vsim_max = max(V_sim);
c1 = x(1).*x(4)-120;
c2= x(2).*x(5)-1800;
c3= 120- x(2).*x(5);
c4= x(3).*x(6)-5400;
c5= 1800-x(3).*x(6);
c6= V_sim-105;
ceq = [];
end
function V_sim = mySimulation(x)
assignin('base', 'R0', x(1));
assignin('base', 'R1', x(2));
assignin('base', 'R2', x(3));
assignin('base', 'C0', x(4));
assignin('base', 'C1', x(5));
assignin('base', 'C2', x(6));
sim('RC_branch');
end
function y = objectiveFunction(x,V_real)
V_sim=mySimulation(x);
assignin('base', 'V_sim', V_sim);
y= (V_sim - V_real);
end

 Accepted Answer

Note that when you have problems that are more than just bounded variables, so any other set of constraints, then it appears lsqnonlin is just a wrapper for a call to fmincon, which does handle those other classes of constraints. I'm not sure when that change happened, but it was not too many years ago. I could check of course, but knowing exactly when seems irrelevant, so I won't. As such, when it terminates, the termination statement was generated by fmincon.
If you look at the code, you can see that under some circumstances, lsqnonlin calls cnls, which then calls fmincon.
And the step tolerance is not the same thing as the norm of the step taken. For example, I'll optimize the Rosenbrock function.
fun = @(x)(100*(x(2) - x(1)^2)^2 + (1 - x(1))^2);
options = optimset('Display','iter');
x0 = [-1.9,2];
[x,fval,eflag,output] = fmincon(fun,x0,[],[],[],[],[],[],[],options)
First-order Norm of Iter F-count f(x) Feasibility optimality step 0 3 2.676200e+02 0.000e+00 1.229e+03 1 11 5.399245e+01 0.000e+00 3.363e+02 7.071e-01 2 15 2.549503e+01 0.000e+00 1.845e+02 7.071e-01 3 22 8.107311e+00 0.000e+00 6.097e+01 1.414e+00 4 25 4.521620e+00 0.000e+00 3.249e+01 6.602e-01 5 28 3.106712e+00 0.000e+00 2.978e+00 1.961e-01 6 31 3.033717e+00 0.000e+00 7.646e+00 6.275e-02 7 34 3.023002e+00 0.000e+00 6.981e+00 1.419e-03 8 37 2.956355e+00 0.000e+00 5.867e+00 2.762e-02 9 40 2.643547e+00 0.000e+00 6.670e+00 1.668e-01 10 44 2.607284e+00 0.000e+00 1.596e+01 3.597e-01 11 47 2.263394e+00 0.000e+00 5.159e+00 1.842e-01 12 50 2.083186e+00 0.000e+00 4.916e+00 8.557e-02 13 54 1.825023e+00 0.000e+00 7.057e+00 1.828e-01 14 57 1.618087e+00 0.000e+00 7.646e+00 1.036e-01 15 60 1.210486e+00 0.000e+00 2.158e+00 1.131e-01 16 64 1.097792e+00 0.000e+00 8.941e+00 1.615e-01 17 67 9.548026e-01 0.000e+00 2.016e+00 4.074e-02 18 70 7.999646e-01 0.000e+00 1.581e+00 8.210e-02 19 74 6.947835e-01 0.000e+00 7.549e+00 1.497e-01 20 77 5.621667e-01 0.000e+00 1.859e+00 2.805e-02 21 80 4.151717e-01 0.000e+00 2.486e+00 1.301e-01 22 83 3.924103e-01 0.000e+00 8.153e+00 1.922e-01 23 86 2.611520e-01 0.000e+00 1.207e+00 3.581e-02 24 89 2.023144e-01 0.000e+00 6.711e-01 8.700e-02 25 94 1.594746e-01 0.000e+00 3.023e+00 1.124e-01 26 97 1.272491e-01 0.000e+00 3.141e+00 7.080e-02 27 100 6.953867e-02 0.000e+00 9.526e-01 1.241e-01 28 104 4.898509e-02 0.000e+00 3.591e+00 1.333e-01 29 107 3.447358e-02 0.000e+00 1.272e+00 1.817e-02 30 110 1.480809e-02 0.000e+00 1.757e+00 1.394e-01 First-order Norm of Iter F-count f(x) Feasibility optimality step 31 113 6.088884e-03 0.000e+00 7.584e-01 7.385e-02 32 116 2.452859e-03 0.000e+00 1.307e+00 8.390e-02 33 119 1.135680e-03 0.000e+00 1.232e+00 5.012e-02 34 122 4.973373e-05 0.000e+00 2.541e-01 3.621e-02 35 125 3.014874e-06 0.000e+00 4.470e-02 1.014e-02 36 128 7.476703e-08 0.000e+00 1.946e-03 2.396e-03 37 131 7.785132e-09 0.000e+00 2.374e-03 4.558e-04 38 134 1.526312e-10 0.000e+00 4.535e-04 1.337e-04 39 137 1.601044e-11 0.000e+00 2.578e-05 2.708e-06 40 148 1.595382e-11 0.000e+00 3.789e-07 6.752e-08 Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
x = 1×2
1.0000 1.0000
fval = 1.5954e-11
eflag = 1
output = struct with fields:
iterations: 40 funcCount: 148 constrviolation: 0 stepsize: 6.7520e-08 algorithm: 'interior-point' firstorderopt: 3.7887e-07 cgiterations: 14 message: 'Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 3.788681e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.' bestfeasible: [1×1 struct]
If you look at the iterative results, the step norm decreases, eventually getting tiny. Totally different from the step tolerance though.

2 Comments

Thank you! But now I'm not sure I understand: what's the point having lsqnonlin and fmincon as two distinct function?
For least-squares problems the setup is different and the behavior of the algorithm differs as well. Let's solve Rosenbrock's function constrained to lie inside a unit circle by lsqnonlin and by fmincon, even knowing that lsqnonlin calls fmincon internally.
fun = @(x)[10*(x(2) - x(1)^2),1 - x(1)]; % vector objective for lsqnonlin
x0 = [1/2,1/2];
[x,res,~,eflag,outpt] = lsqnonlin(fun,x0,[],[],[],[],[],[],@nlcon)
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
x = 1×2
0.7864 0.6177
res = 0.0457
eflag = 1
outpt = struct with fields:
iterations: 13 funcCount: 43 constrviolation: 0 stepsize: 8.6417e-06 algorithm: 'interior-point' firstorderopt: 1.5982e-07 cgiterations: 0 message: 'Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 1.598235e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.' bestfeasible: [1×1 struct]
fun2 = @(x)sum(fun(x).^2);
[x2,fv2,ef2,outpt2] = fmincon(fun2,x0,[],[],[],[],[],[],@nlcon)
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
x2 = 1×2
0.7864 0.6177
fv2 = 0.0457
ef2 = 1
outpt2 = struct with fields:
iterations: 21 funcCount: 74 constrviolation: 0 stepsize: 6.9161e-06 algorithm: 'interior-point' firstorderopt: 2.0709e-08 cgiterations: 4 message: 'Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 2.070944e-08,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.' bestfeasible: [1×1 struct]
function [c,ceq] = nlcon(x)
c = x(1)^2 + x(2)^2 - 1;
ceq = [];
end
In this case, lsqnonlin is more efficient than fmincon on the exact same problem. However, if you set a different initial point, fmincon can be more efficient.
Alan Weiss
MATLAB mathematical toolbox documentation

Sign in to comment.

More Answers (1)

Should be
function [c,ceq] = myNonlinearConstraints(x)
V_sim= evalin('base','V_sim');
Vsim_max = max(V_sim);
c(1) = x(1).*x(4)-120;
c(2)= x(2).*x(5)-1800;
c(3)= 120- x(2).*x(5);
c(4)= x(3).*x(6)-5400;
c(5)= 1800-x(3).*x(6);
c(6)= Vsim_max-105;
ceq = [];
end
instead of
function [c1,c2,c3,c4,c5,c6,ceq] = myNonlinearConstraints(x)
V_sim= evalin('base','V_sim');
Vsim_max = max(V_sim);
c1 = x(1).*x(4)-120;
c2= x(2).*x(5)-1800;
c3= 120- x(2).*x(5);
c4= x(3).*x(6)-5400;
c5= 1800-x(3).*x(6);
c6= V_sim-105;
ceq = [];
end
And the actual V_sim is not available in "myNonlinearConstraints", is it ? Why didn't you stick to the embedded function solution suggested before ?
And concerning "fmincon", I don't have an explanation. Maybe you should start MATLAB anew or at least clear your workspace when rerunning your code.

18 Comments

When MathWorks decided to allow lsqnonlin to use general constraints beyond just bounds, they did so by making it a wrapper to then call fmincon. So the termination statement was generated by fmincon.
Thank you. About your question: The code was a lot slower, so I thought about this solution. At first when it's inside lsqnonlin, it goes to my object function, save V_sim on workspace thank to "assignin" so myconstraint can take the value from workspace.
At first when it's inside lsqnonlin, it goes to my object function, save V_sim on workspace thank to "assignin" so myconstraint can take the value from workspace.
This assumes that lsqnonlin calls objective and constraints alternately. This is not true in general.
I'm not sure what you mean. How it should work?
Also if I set constraints as you suggested this err appears
Unable to perform assignment because the left and right sides have a different number of elements.
Error in multidata_lsqnonlin>myNonlinearConstraints (line 109)
c(6)= V_sim-105;
Error in multidata_lsqnonlin>@(x)myNonlinearConstraints(x) (line 69)
cfun = @(x) myNonlinearConstraints(x);
Error in cnls/nonlconExt (line 431)
[cinOrJac,ceqOrJac] = feval(NONLCON, Xk);
Error in cnls>@(x)nonlconExt(x,false) (line 157)
confun = @(x) nonlconExt(x, false);
Error in fmincon (line 688)
[ctmp,ceqtmp] = feval(confcn{3},X,varargin{:});
Error in cnls (line 215)
[X,~,EXITFLAG,OUTPUT,LAMBDA] = fmincon({fun,fungrad},X(:),...
Error in lsqnonlin (line 220)
[xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = cnls(caller, FUN,xCurrent,A,B,Aeq,Beq,LB,UB,NONLCON, ...
Error in multidata_lsqnonlin (line 72)
[x, exitflag, output] = lsqnonlin(y, x0,lb,ub,A , b, [], [], cfun, opts);
Caused by:
Failure in initial nonlinear constraint function evaluation. FMINCON cannot continue.
lsqnonlin cannot continue.
I'm not sure what you mean. How it should work?
Both functions (objective and constraint function) must work with the V_sim that is deduced from the actual x transfered to these functions. This is not guaranteed with your new code, I guess.
c(6)= V_sim-105;
Please copy my code correctly.
When MathWorks decided to allow lsqnonlin to use general constraints beyond just bounds, they did so by making it a wrapper to then call fmincon. So the termination statement was generated by fmincon.
Thank you for the info. I thought it is a real improvement :-)
My fault, thank you for your patient.
I'm trying to implement again the embedded function as you suggested me, following https://it.mathworks.com/help/optim/ug/objective-and-nonlinear-constraints-in-the-same-function.html, but I have no idea how to set together the "for cycle" (that allows me to do all the simulations in sequence, taking the x0 the optimal x of the previous one) with the function "runobjconstr". Can you please give me an hint? Thank you very much
norm(x_in-x0)<=tol
You know that you only check this condition for the last data set, don't you ? This seems incorrect. It seems it has to be validated for all data sets.
My idea was to stop the iterations once the output of last dataset has not changed from the first one.
My idea was to stop the iterations once the output of last dataset has not changed from the first one.
But usually this won't happen - unless first and last dataset are equal. And the datasets in between don't matter ?
The idea behind this is:
I have to find a set of parameter that fit all the datasets. So I start optimization with the first dataset, when it's ended the output of this one will be initial point for dataset 2 and so on.
If there's no change between the first and the last one, it means the optimizator is not able to make a better fit, so it will stop.
The datasets in between matter but if it does not change from dataset1 to dataset2, does not mean that would not change from dataset2 to dataset3.
Hope I explained myself.
Your approach does not make sense. First of all, you will never get parameters that will be valid for all your datasets separately. Second, imagine you want to fit one parameter and for x_in = 3, you get in your loop over the datasets x = 245, x = -105, x = 2145 and x = 3.0000001. Now you accept a parameter that is nonsense for datasets 1, 2 and 3.
The usual way to handle this is:
Use all your datasets V_real{i} at once, determine the corresponding V_sim{i} and return sum_i sum_j (V_real{i}(j)-V_sim{i}(j))^2 to "fmincon" - all in only one call to the optimizer.
So you basically are saying to collect the data of n different data set in one vector, so V_real{i} will be the concatenation of V_real{1},V_real{2},..., V_real{n}. The optimization will run now on a "virtual dataset" that is the concatenation of n real datasets.
If this is right, what should be the index j that you define sum_i sum_j (V_real{i}(j)-V_sim{i}(j))^2 ?
Do you mean something like this?
clc;clear
% file Excel
excelFiles = {'data_1.xls', 'data_2.xls', 'data_3.xls','data_4.xls'};
% Initialize array to memorize data
data_sets = cell(1, length(excelFiles));
% Read files and memorize data
V_real_con=[];
for i = 1:length(excelFiles)
data = readtable(excelFiles{i});
current= data{:, 6} .* 10^-3; % converti da mA a A
V_real = data{:, 7};
time = (0:1:(length(V_real) - 1))';
% Set data in a structure
data_sets{i} = struct('current', current, 'V_real', V_real, 'time', time);
V_real_con= [V_real_con;data_sets{i}.V_real];
end
% Boundaries
lb = []; % lower boundaries for your parameters
ub = []; % upper boundaries for your parameters
% Initial guess
x0 = [10, 20, 35, 100, 400,600 ];
% Initialize cell to memorize V_sim for each dataset
% all_V_sim = cell(1, length(data_sets));
%Set options for fmincon
Step = 1e-8;
Tolerance = 1e-8;
opts = optimoptions ('fmincon', 'Display', 'iter',...
'EnableFeasibilityMode',true,...
'SubproblemAlgorithm','cg',...
'StepTolerance', Step, ...
'OptimalityTolerance', Tolerance);
%Define nested function
y = @(x) objectiveFunction(x, V_real_con,data_sets);
cfun = @(x) myNonlinearConstraints(x);
% call fmincon
[x, fval, exitflag, output] = fmincon(y, x0, [],[],[],[],lb,ub, cfun, opts);
%define constraint function.function [c,ceq] = myNonlinearConstraints(x)
function [c,ceq] = myNonlinearConstraints
V_sim= evalin('base','V_sim');
c(1) = x(1).*x(4)-120;
c(2)= x(2).*x(5)-1800;
c(3)= 120- x(2).*x(5);
c(4)= x(3).*x(6)-5400;
c(5)= 1800-x(3).*x(6);
c(6)= V_sim-105;
ceq = [];
end
function V_sim_con = mySimulation(x,data_sets)
assignin('base', 'R0', x(1));
assignin('base', 'R1', x(2));
assignin('base', 'R2', x(3));
assignin('base', 'C0', x(4));
assignin('base', 'C1', x(5));
assignin('base', 'C2', x(6));
V_sim_con=[];
for i=1:length(data_sets)
I = [data_sets{i}.time, data_sets{i}.current];
assignin('base', 'I', I);
sim('RC_branch');
V_sim_con=[V_sim_con;V_sim];
end
end
function y = objectiveFunction(x,V_real_con,data_sets)
V_sim_con=mySimulation(x,data_sets);
assignin('base', 'V_sim_con', V_sim_con);
y= sum((V_sim_con - V_real_con).^2);
end
So you basically are saying to collect the data of n different data set in one vector, so V_real{i} will be the concatenation of V_real{1},V_real{2},..., V_real{n}. The optimization will run now on a "virtual dataset" that is the concatenation of n real datasets.
Yes.
If this is right, what should be the index j that you define sum_i sum_j (V_real{i}(j)-V_sim{i}(j))^2 ?
The index to sum over the elements of V_real{i} (and V_sim{i}) (j = 1:numel(V_real{i}))
But the problem remains that in "myNonlinearConstraints", you don't work with the actual "V_sim" in most cases.
And again you have c(6)= V_sim-105;
And there are no inputs to "myNonlinearConstraints"
And you don't assign sim('RC_branch') to V_sim in "mySimulation".
But the problem remains that in "myNonlinearConstraints", you don't work with the actual "V_sim" in most cases.
I'm sorry but I still do not understand why you say that and how it should be solved.
And there are no inputs to "myNonlinearConstraints" And again you have c(6)= V_sim-105;
My fault coping the code, input is x
And you don't assign sim('RC_branch') to V_sim in "mySimulation".
If I set V_sim=sim('RC_branch'), V_sim returns the simulation time. On simulink I have a "to workspace" that after each simulations return the vector "V_sim".
But the problem remains that in "myNonlinearConstraints", you don't work with the actual "V_sim" in most cases.
I'm sorry but I still do not understand why you say that and how it should be solved.
The variable vector x you receive from "fmincon" in function "myNonlinearConstraints" needn't be the same vector with which you calculated V_sim in function "objectiveFunction" before. So it may happen that all inequalities or equalities that use V_sim in function "myNonlinearConstraints" get formulated with an array V_sim that does not correspond to the x that is input to this function.
The problem can be solved by either calling your Simulink simulation in both functions ("myNonlinearConstraints" and "objectiveFunction") or - in order to save calls - by using the embedded functions approach derived earlier. MATLAB engineers don't suggest this rather complicated approach if the problem could be solved as easily as you try it in your code ...
If I set V_sim=sim('RC_branch'), V_sim returns the simulation time. On simulink I have a "to workspace" that after each simulations return the vector "V_sim".
So in the assignment
V_sim_con=[V_sim_con;V_sim];
MATLAB knows of an array V_sim although it is nowhere assigned in the function ? I didn't know of this before.
function V_sim_con = mySimulation(x,data_sets)
assignin('base', 'R0', x(1));
assignin('base', 'R1', x(2));
assignin('base', 'R2', x(3));
assignin('base', 'C0', x(4));
assignin('base', 'C1', x(5));
assignin('base', 'C2', x(6));
V_sim_con=[];
for i=1:length(data_sets)
I = [data_sets{i}.time, data_sets{i}.current];
assignin('base', 'I', I);
sim('RC_branch');
V_sim_con=[V_sim_con;V_sim];
end
end
Ok. So I tried the approach with the embedded function, here is the code. Do you think it should read in a proper way the right V_sim when evaluating the constraint? I also noticed that there was an option not enabled on Simulink that's why it gave me problem saving the V_sim.
Again, thanks a lot for your patience and time.
% SCRIPT TO RUN
clc;clear
% file Excel
excelFiles = {'data_1.xls', 'data_2.xls', 'data_3.xls','data_4.xls'};
% Memorize data
data_sets = cell(1, length(excelFiles));
V_real_con=[];
I_in=[];
for i = 1:length(excelFiles)
data = readtable(excelFiles{i});
current= data{:, 6} .* 10^-3; % converti da mA a A
V_real = data{:, 7};
time = (0:1:(length(V_real) - 1))';
% Memorizza questi dati in una struttura
data_sets{i} = struct('current', current, 'V_real', V_real, 'time', time);
V_real_con= [V_real_con;data_sets{i}.V_real];
I_in = [I_in;data_sets{i}.current];
I=[(0:1:(length(V_real_con) - 1))',I_in];
end
% Boundaries
lb = [0.01, 5, 10, 10, 40, 100, 100 ]; % lower boundaries for your parameters
ub = [0.8, 300, 300, 300, 1100, 1100]; % upper boundaries for your parameters
% Initial guess
x0 = [0.025, 20, 35, 50, 100, 400,600 ];
%Set options for fmincon
opts = optimoptions('fmincon', 'Display', 'iter');
tic
[x,fval,exitflag,output] = runobjconstr(x0,V_real_con,lb,ub,opts);
toc
function [x,f,eflag,outpt] = runobjconstr(x0,V_real_con,lb,ub,opts)
if nargin == 4 % No options supplied
opts = [];
end
xLast = []; % Last place computeall was called
myf = []; % Use for objective at xLast
myc = []; % Use for nonlinear inequality constraint
myceq = []; % Use for nonlinear equality constraint
fun = @(x)objfun(x,V_real_con); % The objective function, nested below
cfun = @(x)constr(x,V_real_con); % The constraint function, nested below
% Call fmincon
[x,f,eflag,outpt] = fmincon(fun,x0,[],[],[],[],lb,ub,cfun,opts);
function y = objfun(x,V_real_con)
if ~isequal(x,xLast) % Check if computation is necessary
[myf,myc,myceq] = computeall(x,V_real_con);
xLast = x;
end
% Now compute objective function
y = myf;
end
function [c,ceq] = constr(x,V_real_con)
if ~isequal(x,xLast) % Check if computation is necessary
[myf,myc,myceq] = computeall(x,V_real_con);
xLast = x;
end
% Now compute constraint function
c = myc;
ceq = myceq;
end
end
%This function compute objective and constraints
function [f1,c,ceq,out] = computeall(x,V_real_con)
out = mySimulation(x);
V_sim=out.V_sim;
f1 = sum((V_sim- V_real_con).^2);
Vsim_max = max(V_sim);
c(1) = x(1).*x(4)-120;
c(2)= x(2).*x(5)-1800;
c(3)= 120- x(2).*x(5);
c(4)= x(3).*x(6)-5400;
c(5)= 1800-x(3).*x(6);
c(6)= Vsim_max-105;
ceq = [];
end
function out = mySimulation(x)
assignin('base', 'R0', x(1));
assignin('base', 'R1', x(2));
assignin('base', 'R2', x(3));
assignin('base', 'C0', x(4));
assignin('base', 'C1', x(5));
assignin('base', 'C2', x(6));
out=sim('RC_branch');
V_sim=out.V_sim;
end
I don't know about your Simulink settings, but does
out=sim('RC_branch');
V_sim=out.V_sim;
really give you back an array of size V_real_con that is the simulated equivalent of your measurement data ? Don't you have to call Simulink for each data set separately to get back the equivalent of data_sets{i}.V_real ?
Since you don't use it anywhere, you can skip "out" as an output argument from "computeall":
function [f1,c,ceq] = computeall(x,V_real_con)
instead of
function [f1,c,ceq,out] = computeall(x,V_real_con)

Sign in to comment.

Asked:

on 28 Aug 2023

Edited:

on 29 Aug 2023

Community Treasure Hunt

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

Start Hunting!