MATLAB: Lsqnonlin with multistart on complex valued function

complex valued functionscurve fittinglsqnonlinMATLABmultistart

Hello everyone,
I am trying to fit a model to a complex valued function using lsqnonlin, multistart and function handles. For a very simple trial problem (appended below) with a narrow range of low and upper bounds, the solver requires a significant number of repetitions (more than 1e3) to approach the coefficient vector of the atificial data, producing a larger error than the lsqnonlin function with no multistart. Considering the repetitions required (less than 50) in the example presented in the relevant topic (https://uk.mathworks.com/help/gads/multistart-using-lsqcurvefit-or-lsqnonlin.html) and the rather wide lb – ub range used in that case, I suspect that there might be something in the code causing the solver to "delay".
% function to be assigned to the function handle
function [Zcap] = randles_cap(c,xdata)
Zcap = c(1)+(1./(1i.*xdata.*c(2)));
% artificial data
xdata = logspace(5,-1,50)';
c0 = [5 1e-4]; % coefficient vector
cplxydata = c0(1)+(1./(1i.*xdata.*c0(2)));
% fit to model using lsqnonlin
x0 = [4.5 1e-5]; %initial guess
objfcn = @(c)randles_cap(c,xdata)-cplxydata;
[lb] = [4 1e-5]; ub = [6 1e-3];
opts = optimoptions(@lsqnonlin,'Display','off');
[xlsqnonlin,errorlsqnonlin] = lsqnonlin(objfcn,x0,lb,ub)
% solving

>> [xlsqnonlin,errorlsqnonlin] = lsqnonlin(objfcn,x0,lb,ub)
Solver stopped prematurely.
lsqnonlin stopped because it exceeded the function evaluation limit,
options.MaxFunctionEvaluations = 200 (the default value).
xlsqnonlin =
4.500000000000000 0.000010000000000
errorlsqnonlin =
1.879291932590291e+12
% using multistart
ms = MultiStart('PlotFcns',@gsplotbestf);
problem = createOptimProblem('lsqnonlin','x0',x0,'objective',objfcn,...
'lb',lb,'ub',ub');
[xmultinonlin,errormultinonlin] = run(ms,problem,1e3)
% solving
MultiStart stopped without completing the runs from all start points.
1000 out of 1000 local solver runs exceeded the iteration limit (problem.options.MaxIterations) or
the function evaluation limit (problem.options.MaxFunctionEvaluations).
None of the 1000 local solver runs converged with a positive local solver exit flag.
xmultinonlin =
5.873582782074172 0.000100201110854
errormultinonlin =
9.350018095406295e+04
Any help/suggestions on the issue will be highly appreciated.
Thank you in advance for your time.
Regards,
Thanos

Best Answer

Well the answer is that someone has to split real and imaginary parts and use lsqcurvefit instead.
e.g. based on the above example (requires less than 5 iterations with wider bounds and less accurate initial guess)
Cheers
% function to be assigned to the function handle
function [Zcap] = randles_cap(c,xdata)
Zcap = zeros(length(xdata),2);
Ztotal = c(1)+(1./(1i.*xdata.*c(2)));
Zcap(:,1) = real(Ztotal); Zcap(:,2) = imag(Ztotal);
%% fit model to artificial data
% artificial data generation
xdata = logspace(5,-1,50)';
c0 = [5 1e-4];
cplxydata = c0(1)+(1./(1i.*xdata.*c0(2)));
ydata2 = [real(cplxydata),imag(cplxydata)];
% initial values, bounds and function handle
x0 = [0.01 5e-8]; % initial guess
fitfcn = @(c,xdata)randles_cap(c,xdata);
[lb] = [1e-2 1e-9]; ub = [1e2 1e-3];
% fit model using lsqcurvefit (optional)
opts = optimoptions(@lsqcurvefit,'Display','off');
[vestimated,resnorm,residuals,exitflag,output] = ...
lsqcurvefit(@cplxreal,x0,xdata,ydata2,lb,ub);
vestimated,resnorm,exitflag,output.firstorderopt;
% fit model using lsqcurvefit with multistart
problem = createOptimProblem('lsqcurvefit','x0',x0,'objective',fitfcn,...
'lb',lb,'ub',ub,'xdata',xdata,'ydata',ydata2);
ms = MultiStart('PlotFcns',@gsplotbestf);
[xmulti,errormulti] = run(ms,problem,500)
%% result
MultiStart completed the runs from all start points.
All 500 local solver runs converged with a positive local solver exit flag.
xmulti =
5.000000000000000 0.000100000000000
errormulti =
0