Nonlinear fitting: how do I split the linear and the nonlinear problems?
이전 댓글 표시
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.
채택된 답변
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Quadratic Programming and Cone Programming에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!