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