Nonlinear fitting: how do I split the linear and the nonlinear problems?
Show older comments
I am fitting a function to some data I simulated. I managed to get intelligent constraints that help the fit quite a bit, even with a lot of noise.
This is the function and as you can see, c(1) and c(2) are linear, while lam(1), lam(2), lam(3) and lam(4) are nonlinear. I am following the procedure explained here (https://it.mathworks.com/help/optim/ug/nonlinear-data-fitting-problem-based-example.html#NonlinearDataFittingProblemBasedExample-4) to split linear and nonlinear parameters.
% Create a function that computes the value of the response at times t when the parameters are c and lam
diffun = ((c(1)) .* ((1 - exp(-t / lam(1))) .* exp(-t / lam(2))) * (Vm - (-70)) + ...
((c(2)) .* ((1 - exp(-t / lam(3))) .* exp(-t / lam(4))) * -30));
This is the code that I came up with, but for some reason it's not working. To generate the data:
function [EPSC, IPSC, CPSC, t] = generate_current(G_max_chl, G_max_glu, EGlu, EChl, Vm, tau_rise_In, tau_decay_In, tau_rise_Ex, tau_decay_Ex,tmax)
dt = 0.1; % time step duration (ms)
t = 0:dt:tmax-dt;
% Compute compound current
IPSC = ((G_max_chl) .* ((1 - exp(-t / tau_rise_In)) .* exp(-t / tau_decay_In)) * (Vm - EChl));
EPSC = ((G_max_glu) .* ((1 - exp(-t / tau_rise_Ex)) .* exp(-t / tau_decay_Ex)) * (Vm - EGlu));
CPSC = IPSC + EPSC;
end
To fit the function:
% Simulated data
[EPSC,IPSC,CPSC,t] = generate_current(80,15,0,-70,-30,0.44,15,0.73,3,120);
ydata = awgn(CPSC,25,'measured'); % Add white noise
% Values
Vm = -30;
% Initial values for fitting
gmc = 40; gmg = 20; tde = 0.2; tdi = 8; tre = 1.56; tri = 3;
% Objective function
c = optimvar('c',2); % Linear parameters
lam = optimvar('lam',4); % Nonlinear parameters
% Bounds
c.LowerBound = [0, 0];
c.UpperBound = [200, 200];
lam.LowerBound = [0.16,7.4,1.1,2.6];
lam.UpperBound = [0.29,8.4,2.3,3.3];
x0.c = [gmc,gmg]; % Starting values
x0.lam = [tri,tdi,tre,tde]; % Starting values
% Create a function that computes the value of the response at times t when the parameters are c and lam
diffun = ((c(1)) .* ((1 - exp(-t / lam(1))) .* exp(-t / lam(2))) * (Vm - (-70)) + ...
((c(2)) .* ((1 - exp(-t / lam(3))) .* exp(-t / lam(4))) * -30));
%Solve the problem using solve starting from initial point x02
x02.lam = x0.lam;
%To do so, first convert the fitvector function to an optimization expression using fcn2optimexpr.
F2 = fcn2optimexpr(@(x) fitvector(x,t,ydata),lam,'OutputSize',[length(t),1]);
% Create a new optimization problem with objective as the sum of squared differences between the converted fitvector function and the data y
ssqprob2 = optimproblem('Objective',sum((F2' - ydata).^2));
[sol2,fval2,exitflag2,output2] = solve(ssqprob2,x02)
% Plot
resp = evaluate(diffun,sol2);
hold on
plot(t,resp)
hold off
The error is:
Solving problem using lsqnonlin.
Error using optim.problemdef.OptimizationProblem/solve
Matrix dimensions must agree.
Error in SplittFit (line 37)
[sol2,fval2,exitflag2,output2] = solve(ssqprob2,x02)
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue.
Not sure why.
Accepted Answer
More Answers (0)
Categories
Find more on Quadratic Programming and Cone Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!