How to optimize parameters in the following equation

9 views (last 30 days)
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?

Answers (1)

Matt J
Matt J on 21 May 2019
Edited: Matt J on 21 May 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 Comments
Mitchell Morningstar
Mitchell Morningstar on 21 May 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 on 21 May 2019
Edited: Matt J on 21 May 2019
Yes, your model function output and the 4th input argument of lsqcurvefit must be arrays of the same size.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!