I want to fit my ode model to experimental data and derive parameters using lsqcurevfit and fmincon

% Experimental data
t2=[6 12 18 36 48];
t20=[ 6 12 18 24];
nfe20=[ 3.83 3.88 6.27 5.25 ];
nfe2=[ 1.57 2.87 3.9 5.16 4.25];
t=0:1:48;
% ODE equation
ode_eqn = @(x, t) integrate_a(x, t) .* t; %ODE equation to fit
x0 = [1 1 11]; % Initial guess for the parameters
% Least squares curve fitting using lsqcurvefit
x_fit1 = lsqcurvefit(ode_eqn, x0, t2, nfe2);
Unable to perform assignment because the left and right sides have a different number of elements.

Error in solution>integrate_a (line 61)
inf(i) = inf(i-1)+ (f.*x(1) - inf(i-1).*x(2));

Error in solution>@(x,t)integrate_a(x,t).*t (line 9)
ode_eqn = @(x, t) integrate_a(x, t) .* t; %ODE equation to fit

Error in lsqcurvefit (line 251)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});

Caused by:
Failure in initial objective function evaluation. LSQCURVEFIT cannot continue.
disp("Fitted parameters using lsqcurvefit:")
disp(x_fit1)
% Nonlinear programming using fmincon
options = optimoptions('fmincon', 'Algorithm', 'interior-point');
x_fit1_constrained = fmincon(@(x) sum((ode_eqn(x, t2) - nfe2).^2), x0,[],[],[],[],[0 0 0],[10 10 3],[],options);
disp("Fitted parameters using fmincon:")
disp(x_fit1_constrained)
% Plotting results
t_fit1 = 0:1:48; % Time points for plotting fitted curve
figure;
plot(t2, nfe2, 'bo', 'MarkerSize', 8, 'LineWidth', 1.5); % Plot experimental data
hold on;
plot(t_fit1, ode_eqn(x_fit1, t_fit1), 'r-', 'LineWidth', 2); % Plot fitted curve using lsqcurvefit
plot(t_fit1, ode_eqn(x_fit1_constrained, t_fit1), 'g--', 'LineWidth', 2); % Plot fitted curve using fmincon
hold off;
legend('Experimental Data', 'lsqcurvefit', 'fmincon');
xlabel('Time');
ylabel('Data');
title('Fitting Experimental Data to ODE Equation');
%%
%{
function [a,b] = nonlcon(x)
f=1:1:6;
a=[];
b=[];
inf=0.9;
for t=0:1:48
if t > x(3)
a = a + (f*x(1) - a.*x(2));
end
end
inf=a-1;
end
%}
function a_int = integrate_a(x, t)
f=[99 38 9 .015 0.06];
inf=0.9;
a_int = zeros;
inf = 0.9;
for i = 1:numel(t)
if t(i) >= x(3)
inf(i) = inf(i-1)+ (f.*x(1) - inf(i-1).*x(2));
end
end
end

Answers (2)

There are some examples in the documentation of fitting ODE parameters to data:
Discretized Optimal Trajectory, Problem-Based (maybe not relevant, but might be)
If these don't help, feel free to ask again.
Alan Weiss
MATLAB mathematical toolbox documentation

Categories

Asked:

on 13 Jun 2023

Answered:

on 15 Jun 2023

Community Treasure Hunt

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

Start Hunting!