How to optimize parameters in the following equation

12 visualizaciones (últimos 30 días)
Mitchell Morningstar
Mitchell Morningstar el 21 de Mayo de 2019
Editada: Matt J el 21 de Mayo de 2019
Hi there,
I have the following block of code to model the concentration of ethanol in a blood sample and would like to automatically optimize the parameters V, z and m for different doses of ethanol that I have collected empirical data for (so far I only have 1 g/kg and 2 g/kg). I've been exploring the function lsqcurvefit and have yet to have any success in formatting and running it.
V = 48; %Parameter
z = 1.25; %Parameter
m = 2.8; %Parameter
x(1) = V(1);
x(2) = z(1);
x(3) = m(1);
t = [1:120];
Be = 1:length(t); %Variable 1
B = 1:length(t); %Variable 2
Bd = 1:length(t); %Variable 3
Bec = 1:length(t);%Output variable desired
x0 = [1 1 1];
m_AB1 = [0 mean(AB_1)]; %Data I would like to fit
m_AB2 = [0 mean(AB_2)]; %More data I would like to fit
times = [0 5 15 30 60 90]; %Timepoints corresponding to that data
for t = 1:length(t)
Bec(t+1) = (1 + log(Be(t))*V) + (1+log(t^2 + B(t)/z)^2) + (-m*t + Bd(t) * z); %Equation to model BEC.
end
%
% Bec_fn = @(x,t)(1 + log(Be(t))*x(1)) + (1+log(t^2 + B(t)/x(2))^2) + (-x(3)*t + Bd(t) * x(2));
% fcn = lsqcurvefit(Bec_fn,x0,times,m_AB1);
plot(Bec)
hold on
times = [0 5 15 30 60 90];
scatter(times,[0 mean(AB_2)])
It works fairly well when I manually adjust the paramters V, z and m. I mainly have to adjust them when looking at different doses of ethanol. I've spent the better part of the day trying to get the lsqcurvefit function to work for me, however, I haven't had any luck so far. I think the lsqcurvefit is the proper function for the job, but am open to other suggestions. The output of me manually messing around with the parameters looks like this and gives moderately satisfying results.
example_figure.jpg
The error message that is currently haunting me is the following:
Array indices must be positive integers or logical values.
Error in
fit>@(x,t)(1+log(Be(t))*x(1))+(1+log(t^2+B(t)/x(2))^2)+(-x(3)*t+Bd(t)*x(2))
Error in lsqcurvefit (line 213)
initVals.F =
feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Error in fit (line 26)
fcn = lsqcurvefit(Bec_fn,x0,times,m_AB1);
Caused by:
Failure in initial objective function evaluation. LSQCURVEFIT
cannot continue.
My main question is if I am on the right path here, and how can I optimize the equation above in order to produce a tighter set of results?

Respuestas (1)

Matt J
Matt J el 21 de Mayo de 2019
Editada: Matt J el 21 de Mayo de 2019
Leave lsqcurvefit aside for the moment. First, get your model function to work! It cannot even be evaluated at your initial point, x0.
>> Bec_fn(x0,times)
Array indices must be positive integers or logical values.
Error in @(x,t)(1+log(Be(t))*x(1))+(1+log(t^2+B(t)/x(2))^2)+(-x(3)*t+Bd(t)*x(2))
  2 comentarios
Mitchell Morningstar
Mitchell Morningstar el 21 de Mayo de 2019
Good advice. I redefined it as a function looking like this:
function Bec = get_bec(x,t)
t = 1:t;
Be = 1:length(t);
B = 1:length(t);
Bd = 1:length(t);
Bec = 1:length(t);
Bec(t+1) = (1 + log(Be(t))*x(1)) + (1+log(t.^2 + B(t)/x(2)).^2) + (-x(3)*t + Bd(t) * x(2));
end
It outputs the same values I had in the scripts above.
I was able to move forward a little bit.
Bec_fn = @get_bec;
fcn = lsqcurvefit(Bec_fn,x0,times,m_AB1);
Returns
Error using lsqcurvefit (line 262)
Function value and YDATA sizes are not equal.
Error in fit_bec (line 28)
fcn = lsqcurvefit(Bec_fn,x0,times,m_AB1);
I'm assuming this is happening because my data isn't a line per se and doesn't have the same amount of data points?
Matt J
Matt J el 21 de Mayo de 2019
Editada: Matt J el 21 de Mayo de 2019
Yes, your model function output and the 4th input argument of lsqcurvefit must be arrays of the same size.

Iniciar sesión para comentar.

Community Treasure Hunt

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

Start Hunting!

Translated by