MATLAB: I have two problems in the code: 1 – Genetic algorithm gets “stuck” in the first generation. 2 – lsqcurvefit is unable to fix it. Can anyone, please, help me

gaoptimsetoptimset

Hello, I am trying to minimize the error between 2 curves using the least squares method. To accomplish that I am using a two-step fitting procedure with the GA and the lsqcurvefit. I have some kind of issue that I cannot fix: The genetic algorithm gets stuck in the first generation, i.e. the stopping criteria is always the stall generation number, no matter the changes I make in my code. As for the lsqcurvefit, I was hoping that this procedure could go around this GA issue but I was mistaken. Probably I am badly using the gaoptimset and optimset options, but I can’t figure it out what is missing. Many thanks in advance for any help.
I have 9 variables that I need to optimize. For each variable I have gave it a lower and an upper bound.
% Lower bound
LB = horzcat(15,5,20,1E5,1,1E7,0,0,0);
% Upper bound
UB = horzcat(25,15,40,1E7,1E2,1E8,1,1,1);
I am trying in a test case and I know that the optimal values are, in the same order:
19.1, 10.0, 31.0, 2E6, 4, 6.5E7, 0, 1, 0
GA code:
delta = @FittingObj.Fitting_GA;
nvars = numel(LB);
options_GA = gaoptimset('PlotFcn',{@gaplotrange,@gaplotbestf,@gaplotdistance});
options_GA = gaoptimset(options_GA,'PopInitRange',[LB;UB]);
options_GA = gaoptimset(options_GA,'Generations',150,'StallGenLimit',20);
options_GA = gaoptimset(options_GA,'PopulationSize',20);
% I tried both the 'StallGenLimit' and the 'PopulationSize' with 100 and the result is the same
options_GA = gaoptimset(options_GA,'SelectionFcn',{@selectiontournament,4});
options_GA = gaoptimset(options_GA,'CrossoverFcn',{@crossoverscattered});
options_GA = gaoptimset(options_GA,'MutationFcn',{@mutationuniform,0.10});
options_GA = gaoptimset(options_GA,'Display','iter');
% Run the GA solver.
[y,opt_delta_GA] = ga(delta,nvars,[],[],[],[],LB,UB,[],options_GA);
% And my objective function is:

function delta_GA = Fitting_GA(fit,y)
fE2 = y(1);
fE3 = y(2);
fE4 = y(3);
fA2 = y(4);
fA3 = y(5);
fA4 = y(6);
fb2 = y(7);
fb3 = y(8);
fb4 = y(9);
fit.ReWriteFile(fE2,fE3,fE4,fA2,fA3,fA4,fb2,fb3,fb4);
fit.pyr.InitPyrolysis();
fit.pyr.RunPyrolysis();
fit.RearrangeDimensions();
delta_2D = zeros(1,fit.pyr.NI);
delta_2D(1:fit.pyr.NI) = (fit.wt_loss_ref(1:fit.pyr.NI)-fit.pyr.wt_loss(1:fit.pyr.NI)).^2;
delta_1D = sum(delta_2D);
fit.delta_wt_loss = (fit.pyr.NI^(-1)*delta_1D)^(1/2);
delta_GA = log(1+10*fit.delta_wt_loss);
end
lsqcurvefit code:
% Run LSQ solver.
X0 = y(1:nvars);
options_LSQ = optimset('MaxFunEvals',1E5,'MaxIter',1E5);
[x,fit_error] = lsqcurvefit(@FittingObj.Fitting_LSQ,X0,PyrolysisObj.solver.x,FittingObj.wt_loss_ref,LB,UB,options_LSQ);
opt_delta = sqrt(fit_error/PyrolysisObj.NI);
% And my objective function is:
function mp = Fitting _LSQ(fit,x,~)
fE2 = x(1);
fE3 = x(2);
fE4 = x(3);
fA2 = x(4);
fA3 = x(5);
fA4 = x(6);
fb2 = x(7);
fb3 = x(8);
fb4 = x(9);
fit.ReWrite(fE2,fE3,fE4,fA2,fA3,fA4,fb2,fb3,fb4);
fit.pyr.InitPyrolysis();
fit.pyr.RunPyrolysis();
mp = fit.pyr.wt_loss(1:fit.pyr.NI);
end
and I get:
Initial point is a local minimum. Optimization completed because the size of the gradient at the initial point is less than the default value of the function tolerance.
And this is both the GA and lsqcurvefit optimum result:
15, 5, 20, 1E5,1,1E7,0,0.5528,1 (the first variables set chosen by GA)
I saved all the GA data in a .txt file that is attached.

Best Answer

It is possible that lsqcurvefit gets stuck because you are trying to optimize a simulation: the tiny finite difference steps that lsqcurvefit makes in trying to estimate a gradient can lead to the simulation not changing its results at all. For suggestions about optimizing a simulation, see Optimizing a Simulation or ODE, especially the suggestions on finite differences.
Of course, I am just guessing, you didn't say that you were trying to optimize a simulation, it just looks that way to me.
And might I suggest that once you get lsqcurvefit working, ditch ga, and to find a global minimum, just run lsqcurvefit starting from multiple random points in the bounds, such as
x0 = lb + rand(size(lb)).*(ub-lb);
You could even just use MultiStart to do that.
Good luck,
Alan Weiss
MATLAB mathematical toolbox documentation