Bad optimization of an objective nonlinear fitting

1 view (last 30 days)
I have a bad understanding why this optimization does not work. I have a raw signal which is the convolution between a signal X (which I would like to find by a fitting) and signal 2 which is known.
I need to optimize a convolution between a three-exponential terms function with signal sig2 (which is a response function that should not change, only the three-exponential fitting that shpould be optimized so that its convolution with sig2 should match the raw signal "sig1").
Data = xlsread('rawdata.xlsx','Sheet1','A2:C119000');
time = Data(:,1) ;
sig1 = Data(:,2) ;
sig2 = Data(:,3) ;
% Define signal 3 (three exponential terms fitting function)
modelFun = @(p,time) - 1.8785e-01*exp(-6E6 *time) - p(2)*exp(-p(3)*time) + (1.8785e-01+p(2))*exp(-p(1)*time);
Now I give very good starting points for the fitting
% Define initial values for the parameters for the three-exponential terms
% fitting to be optimized
p0 = [1.4531e+03 3.5868e-01 1.9509e+05];
No I use lsqcurvefit to construct the final target function which should optimize the final fitting so that the convolution of the fitting with sig2 should reproduce well the raw data (sig1).
[params,resnorm,residual,exitflag,output,lambda,jacobian] = lsqcurvefit(@(p,time) conv(sig2,modelFun(p,time), 'same'),p0,time,sig1);
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
Now if I display the output of this optimization (I display only the three-exponential term function):
tesfunc1 = - 1.8785e-01*exp(-6E6 *time) - params(2)*exp(-params(3)*time) + (1.8785e-01+params(2))*exp(-params(1)*time);
figure
plot(time,sig1,'DisplayName' ,'raw signal' )
hold on
plot(time, tesfunc1, 'DisplayName' ,'optimized fitting')
xlabel('Time');
ylabel('Intensity');
legend
It is defenitely a bad optmization, if I do convolution with sig2, it does not reproduce theraw data at all:
Objective = conv(sig2,tesfunc1);
figure
plot(time,sig1,'DisplayName' ,'raw signal' )
hold on
plot(time,Objective(1:length(time))*(max(sig2)/max(Objective)),'DisplayName' ,'objective function' ) % the max operation is only to scale as the convolution takes the total amplitude to a high level
xlabel('Time');
ylabel('Intensity');
legend
However, if I use exactly the initial parameters, it should be a very good fitting (apart fron the convolution changes the overall amplitude that I still do not know how to fix).:
tesfunc2 = - 1.8785e-01*exp(-6E6 *time) - p0(2)*exp(-p0(3)*time) + (1.8785e-01+p0(2))*exp(-p0(1)*time);
% objective function if the optimization found parameters like in p0
% (declared initial points)
Objective = conv(sig2,tesfunc2);
figure
plot(time,sig1,'DisplayName' ,'raw signal' )
hold on
plot(time,Objective(1:length(time))*(max(sig2)/max(Objective))*1.1,'DisplayName' ,'objective function' ) % again I do the rescaling manually
xlabel('Time');
ylabel('Intensity');
legend
Of course for this testfunction I knew the parameters, and in reality I would like to find them. for the lsqcurvefit, even if I spoiled it with very good parameters giving the function above, it still missed the fitting completely!
I am wondering what can make this optimization better. And I have seen some use "fminunc" with a cost function that would be in my case (costFunction = @(params) mean((rawData - conv(signal2, fittingfunction(:, params))).^2);)), but I do not really know how to implement it in my case.
Many thanks in advance.
  1 Comment
HamzaChem
HamzaChem on 7 Jun 2023
Edited: HamzaChem on 7 Jun 2023
I rewrote the code using fmincon (which is faster) but same fitting outputs:
% Use fmincon to fit signal 1 with the convolution of signals 2 and 3
[params,resnorm,residual,exitflag,output,lambda,jacobian] = fmincon(@(p) mean((sig1-conv(sig2,modelFun(p,time),'same')).^2),p0);
% comparing the optimized fitting with a "should be good" fitting
% optimized three-exponential fitting function
tesfunc1 = - 1.8785e-01*exp(-6E6 *time) - params(2)*exp(-params(3)*time) + (1.8785e-01+params(2))*exp(-params(1)*time);
% three-exponential fitting which should be good
tesfunc2 = - 1.8785e-01*exp(-6E6 *time) - p0(2)*exp(-p0(3)*time) + (1.8785e-01+p0(2))*exp(-p0(1)*time);
figure
plot(time,sig1,'DisplayName' ,'raw signal' )
hold on
plot(time, tesfunc1, 'DisplayName' ,'optimized fitting')
hold on
plot(time, tesfunc2, 'DisplayName' ,'a good fit (known)' )
xlabel('Time');
ylabel('Intensity');
legend

Sign in to comment.

Answers (0)

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!