How to fit kinetic model to estimate kinetic parameter from experimental data

95 vues (au cours des 30 derniers jours)
Alfred
Alfred le 15 Août 2024
Commenté : Star Strider le 9 Nov 2024 à 21:28
I am getting errors in the output. Please help be solve the problem. I have attached the Excel file of the experimental data.
Thank you.
%Fermentation data
Xdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','e2:e13');
Gdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','b2:b13');
Bdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','c2:c13');
Edata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','d2:d13');
% Group all data into yariable y
yinv =[Xdata'; Gdata'; Bdata'; Edata'];
%Data for time
timeex = readmatrix('batch1.xlsx','Sheet','sheet1','Range','a2:a13');
%Set ODE solver
% Initial cell biomass concentration (Initial condition)
y0=[1.04 0.78 0.00 0.00];
%Fermentation time
tspan = linspace(0,72);
%Set optimization problem
%Let b = matrix of paramters to be determined
% b= [um ks k1 K1G K1B k2 K2G YXG m k3]
b = optimvar('b',10,"LowerBound",0,"UpperBound",72);
%Set functions for ODE solver for solving ODE
function solferment = toODE(b,tspan,y0)
sol = ode45(@(t,y)batchferment(t,y,b),tspan,y0);
solferment = deval(sol,tspan);
end
%Convert function for ODE solving to optimization expression
%To use RtoODE in an objective function, convert the function to an
%optimization expression by using fcn2optimexpr.
myfcn = fcn2optimexpr(@toODE,b,timeex,y0);
%Express the objective function as the sum of squared differences between
%the ODE solution and the solution with true parameters.
SSE = sum(sum((myfcn-yinv).^2));
%Create an optimization problem with the objective function SSE.
prob = optimproblem ("Description","Fit ODE parameters",'ObjectiveSense','min');
%Objective function (to be minimized)
prob.Objective = SSE;
%Show structure of problem
show(prob)
%Solve Problem
%To find the best-fitting parameters x, give an initial guess
%x0 for the solver and call solve.
% Set initial guesses of parameters
initialGuess.b = [0.18 1.0 0.61 0.18 5.85 3.20 16.25 0.11 3.40 3.02];
%Solve optimization problem
[sol,optval] = solve(prob,initialGuess);
%Extract the results
%Fitted Parameters
bfinal =sol.b;
%Sum of square Error
SSEfinal = optval;
%Plot the simulated data and experimental data
%Call ODE to solve an equation using Final Fitted Parameters (bfinal)
solysim = ode45(@(t,y)batchferment(t,y,bfinal),tspan,y0);
%Evaluate the simulated results at specified tspan
ysim = deval(solysim,tspan);
%Plot graphs
figure;
plot(timeex,Xdata,'*r',tspan,ysim(1,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('X (g/L)')
figure;
plot(timeex,Gdata','*r',tspan,ysim(2,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('G (g/L)')
figure;
plot(timeex,Bdata','*r',tspan,ysim(3,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('B (g/L)')
figure;
plot(timeex,Edata','*r',tspan,ysim(4,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('E (g/L)')
%Equations for Batch
%y(1) = X = Biomass Concentration (g/l)
%y(2) = G = Glucose Concentration (g/l)
%y(3) = B = Cellobiose Concentration (g/L)
%y(4) = E = Ethanol Concentration (g/l)
function dydt = batchferment(t,y,b)
y(1) = X;
y(2) = G;
y(3) = B;
y(4) = E;
%%%Growth equations
%dx/dt = (um*X*G)/(KG+G)
u = (b(1)*y(1)*y(2))/(b(2)+y(2));
%u = (b(1)*X*G)/(b(2)+G);
%parameters
b(1) = um (1/h);
b(2) = ks (g/L);
%%%Cellobiose equations
C = b(11)-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04));
r1 = (b(3)*C)/(1+(y(2)/b(4))+(y(3)/b(5)));
r2 = (b(6)*y(3))/(1+(y(2)/b(7)));
b(3) = k1;
b(4) = K1G;
b(5) = K1B;
b(6) = k2;
b(7) = K2G;
%C = Cellulose concentration (g/l)
%C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
%r1 = (k1*C)/(1+(G/K1G)+(B/K1B))
%r2 = (k2*B)/(1+(G/K2G)
%C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
%C = 83.65-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04))
%%% Glucose equations
rG = ((1/b(8))*(dx/dt))-(b(9)*y(1));
b(8) = YXG;
b(9) = m;
%rG = ((1/YXG)*(dX/dt))-(m*X)
%%% Ethanol Concentration
Et = k3*(u*X)*(1/YXG);
b(10) = k3;
%Material balance equations
dXdt = u*X;
dGdt = (r2/0.95)-rG;
dBdt = (r1/0.947)-r2;
dEdt = Et;
dydt = [dXdt;dGdt;dBdt;dEdt];
end
This is the output after running:
>> Batch1
Unrecognized function or variable 'X'.
Error in Batch1>batchferment (line 110)
y(1) = X;
Error in Batch1>@(t,y)batchferment(t,y,b) (line 30)
sol = ode45(@(t,y)batchferment(t,y,b),tspan,y0);
Error in odearguments (line 92)
f0 = ode(t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 104)
odearguments(odeIsFuncHandle,odeTreatAsMFile, solver_name, ode, tspan, y0, options, varargin);
Error in Batch1>toODE (line 30)
sol = ode45(@(t,y)batchferment(t,y,b),tspan,y0);
Error in optim.problemdef.fcn2optimexpr
Error in optim.problemdef.fcn2optimexpr
Error in fcn2optimexpr
Error in Batch1 (line 38)
myfcn = fcn2optimexpr(@toODE,b,timeex,y0);
Caused by:
Function evaluation failed while attempting to determine output size. The function might contain an error, or might not be well-defined at
the automatically-chosen point. To specify output size without function evaluation, use 'OutputSize'.
>>

Réponse acceptée

Star Strider
Star Strider le 15 Août 2024
Modifié(e) : Star Strider le 15 Août 2024
I got this to run (there were a number of coding errors, most of which I corrected). However it takes too long to run here, so there could be some coding errors I have not yet caught, although the rest of the code looks to me to be correct. I will try running it on MATLAB Online and post any further corrections (ir any are needed) as EDIT notes.
Try this —
%Fermentation data
Xdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','e2:e13');
Gdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','b2:b13');
Bdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','c2:c13');
Edata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','d2:d13');
% Group all data into yariable y
yinv =[Xdata'; Gdata'; Bdata'; Edata'];
%Data for time
timeex = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','a2:a13');
%Set ODE solver
% Initial cell biomass concentration (Initial condition)
y0=[1.04 0.78 0.00 0.00];
%Fermentation time
tspan = linspace(0,72);
%Set optimization problem
%Let b = matrix of paramters to be determined
% b= [um ks k1 K1G K1B k2 K2G YXG m k3]
b = optimvar('b',10,"LowerBound",0,"UpperBound",72);
%Set functions for ODE solver for solving ODE
function solferment = toODE(b,tspan,y0)
sol = ode45(@(t,y)batchferment(t,y,b),tspan,y0);
solferment = deval(sol,tspan);
end
%Convert function for ODE solving to optimization expression
%To use RtoODE in an objective function, convert the function to an
%optimization expression by using fcn2optimexpr.
myfcn = fcn2optimexpr(@toODE,b,timeex,y0);
%Express the objective function as the sum of squared differences between
%the ODE solution and the solution with true parameters.
SSE = sum(sum((myfcn-yinv).^2));
%Create an optimization problem with the objective function SSE.
prob = optimproblem ("Description","Fit ODE parameters",'ObjectiveSense','min');
%Objective function (to be minimized)
prob.Objective = SSE;
%Show structure of problem
show(prob)
%Solve Problem
%To find the best-fitting parameters x, give an initial guess
%x0 for the solver and call solve.
% Set initial guesses of parameters
initialGuess.b = [0.18 1.0 0.61 0.18 5.85 3.20 16.25 0.11 3.40 3.02];
%Solve optimization problem
[sol,optval] = solve(prob,initialGuess);
%Extract the results
%Fitted Parameters
bfinal =sol.b;
%Sum of square Error
SSEfinal = optval;
%Plot the simulated data and experimental data
%Call ODE to solve an equation using Final Fitted Parameters (bfinal)
solysim = ode45(@(t,y)batchferment(t,y,bfinal),tspan,y0);
%Evaluate the simulated results at specified tspan
ysim = deval(solysim,tspan);
%Plot graphs
figure;
plot(timeex,Xdata,'*r',tspan,ysim(1,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('X (g/L)')
figure;
plot(timeex,Gdata','*r',tspan,ysim(2,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('G (g/L)')
figure;
plot(timeex,Bdata','*r',tspan,ysim(3,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('B (g/L)')
figure;
plot(timeex,Edata','*r',tspan,ysim(4,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('E (g/L)')
%Equations for Batch
%y(1) = X = Biomass Concentration (g/l)
%y(2) = G = Glucose Concentration (g/l)
%y(3) = B = Cellobiose Concentration (g/L)
%y(4) = E = Ethanol Concentration (g/l)
function dydt = batchferment(t,y,b)
% y(1) = X;
% y(2) = G;
% y(3) = B;
% y(4) = E;
X = y(1);
G = y(2);
B = y(3);
E = y(4);
%%%Growth equations
%dx/dt = (um*X*G)/(KG+G)
u = (b(1)*y(1)*y(2))/(b(2)+y(2));
%u = (b(1)*X*G)/(b(2)+G);
%parameters
% b(1) = um (1/h);
% b(2) = ks (g/L);
um = b(1);
ks = b(2);
%%%Cellobiose equations
C = b(1)-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04));
r1 = (b(3)*C)/(1+(y(2)/b(4))+(y(3)/b(5)));
r2 = (b(6)*y(3))/(1+(y(2)/b(7)));
% b(3) = k1;
% b(4) = K1G;
% b(5) = K1B;
% b(6) = k2;
% b(7) = K2G;
k1 = b(3);
K1G = b(4);
K1B = b(5);
k2 = b(6);
k2G = b(7);
%C = Cellulose concentration (g/l)
%C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
%r1 = (k1*C)/(1+(G/K1G)+(B/K1B))
%r2 = (k2*B)/(1+(G/K2G)
%C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
%C = 83.65-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04))
%%% Glucose equations
% rG = ((1/b(8))*(dx/dt))-(b(9)*y(1));
% b(8) = YXG;
% b(9) = m;
YXG = b(8)
m = b(9);
%rG = ((1/YXG)*(dX/dt))-(m*X)
%%% Ethanol Concentration
% b(10) = k3;
k3 = b(10);
Et = k3*(u*X)*(1/YXG);
%Material balance equations
dXdt = u*X;
rG = ((1/b(8))*(dXdt))-(b(9)*y(1));
dGdt = (r2/0.95)-rG;
dBdt = (r1/0.947)-r2;
dEdt = Et;
dydt = [dXdt;dGdt;dBdt;dEdt];
end
EDIT — (15 Aug 2024 at 03:00)
Unfortunately, I cannot run your code in MATLAB Online. About two minutes after starting it, it produces:
Error using cat
Requested 4x7x23738800 (5.0GB) array exceeds maximum array size preference (5.0GB). This might cause MATLAB to become
unresponsive.
Error in
ode45 (line 425)
f3d = cat(3,f3d,zeros(neq, 7, chunk, 'like', prototype));
Error in
Alfred_2024_08_15>toODE (line 48)
sol = ode45(@(t,y)batchferment(t,y,b),tspan,y0);
Error in optim.problemdef.fcn2optimexpr
Error in optim.problemdef.fcn2optimexpr
Error in fcn2optimexpr
Error in
Alfred_2024_08_15 (line 56)
myfcn = fcn2optimexpr(@toODE,b,timeex,y0);
Since you will likely be able to run your code (I am not certain I would be able to, for the same reason MATLAB Online cannot), please post back any subsequent errors that your code may throw. It may be possible to correct them without actually running your code.
.
  23 commentaires
Alfred
Alfred le 8 Nov 2024 à 4:19
Yes, that is what I used. I used the parameters published as initial guesses. Yet, getting such curves.
Star Strider
Star Strider le 9 Nov 2024 à 21:28
This produces output that matches the input matrix, and produces reasonable reaults, however I am having problems getting it to converge.
I re-derived the differenttial equations using your p[rovided PDF and the Symbolic Math Toolbox witth this code:
clear all
close all
syms C(t) B(t) G(t) X(t) E(t) YXG k1prime k1 k2 k3 KG K1B K1G K2G m um T Y
r1 = k1prime * C / (1 + B/K1B + G/K1G)
r2 = k2 * B / (1 + G/K2G)
rx = um * X * G / (K1G + G)
rG = rx/YXG + m * X
Eq1 = diff(C) == -r1
Eq2 = diff(B) == r1/0.947 - r2
Eq3 = diff(G) == r2/0.95 - rG
Eq4 = diff(X) == um * X * G / (KG + G)
Eq5 = diff(E) == k3 * um * X * G / ((KG + G) * YXG)
[VF,Subs] = odeToVectorField(Eq1, Eq2, Eq3, Eq4, Eq5)
DEfcn = matlabFunction(VF, 'Vars',{t,Y,K1B,K1G,K2G,KG,YXG,k2,k3,k1prime,m,um})
t = 1:10;
[t,Y] = ode45(@(t,Y)DEfcn(t,Y,rand,rand,rand,rand,rand,rand,rand,rand,rand,rand),t,rand(1,5))
figure
plot(t,Y)
grid
I invite you to check that to see if there are any errors, correct them as necessary, then run it. (I did not see any errors, however I was working from your PDF, so the code is as good as those equations.) I then used ‘DEfcn’ in the code to fit the data. (II adapted my original ‘kinetics’ code for this problem, since I understand it.) The ‘Subs’ comments are returned by the odeToVectorField function, and correspond to the order of the differential equations in ‘DEfcn’.
I integrated the code using random parameters to be certain that it produces results resembling the original data, and it seems to provide a reasonable result. I just have problems fitting it.
So I invite you to check it, make any necessary corrections, and post back with results.
The ‘Arrays have incompatible sizes for this operation’ error means that the integratiion encountered a singluarity and did not complete, so the comparison inn the ‘ftns’ function fails. If it does not encounter the singularity, the matrices will be the same size, and the code will continue.
%Fermentation data
Xdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','e2:e13');
Gdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','b2:b13');
Bdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','c2:c13');
Edata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','d2:d13');
% Group all data into yariable y
yinv =[Xdata Gdata Bdata Edata];
c = yinv;
%Data for time
timeex = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','a2:a13');
t = timeex;
% % [theta,Rsdnrm,Rsd,ExFlg,OptmInfo,Lmda,Jmat]=lsqcurvefit(@kinetics,theta0,t,c);
ftns = @(theta) norm(c-kinetics(theta,t));
PopSz = 50;
Parms = 15;
optsAns = optimoptions('ga', 'PopulationSize',PopSz, 'InitialPopulationMatrix',randi(1E+4,PopSz,Parms)*1E-3, 'MaxGenerations',5E3, 'FunctionTolerance',1E-10); % Options Structure For 'Answers' Problems
% opts = optimoptions('ga', 'PopulationSize',PopSz, 'InitialPopulationMatrix',randi(1E+4,PopSz,Parms)*1E-3, 'MaxGenerations',5E3, 'FunctionTolerance',1E-10, 'PlotFcn',@gaplotbestf, 'PlotInterval',1);
t0 = clock;
fprintf('\nStart Time: %4d-%02d-%02d %02d:%02d:%07.4f\n', t0)
Start Time: 2024-11-09 21:27:54.7683
[theta,fval,exitflag,output,population,scores] = ga(ftns, Parms, [],[],[],[],zeros(Parms,1),Inf(Parms,1),[],[],optsAns);
Warning: Failure at t=3.009454e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.
Arrays have incompatible sizes for this operation.

Error in solution>@(theta)norm(c-kinetics(theta,t)) (line 20)
ftns = @(theta) norm(c-kinetics(theta,t));

Error in createAnonymousFcn>@(x)fcn(x,FcnArgs{:}) (line 11)
fcn_handle = @(x) fcn(x,FcnArgs{:});

Error in makeState (line 58)
firstMemberScore = FitnessFcn(state.Population(initScoreProvided+1,:));

Error in galincon (line 24)
state = makeState(GenomeLength,FitnessFcn,Iterate,output.problemtype,options);

Error in ga (line 420)
[x,fval,exitFlag,output,population,scores] = galincon(FitnessFcn,nvars, ...

Caused by:
Failure in initial user-supplied fitness function evaluation. GA cannot continue.
t1 = clock;
fprintf('\nStop Time: %4d-%02d-%02d %02d:%02d:%07.4f\n', t1)
GA_Time = etime(t1,t0)
DT_GA_Time = datetime([0 0 0 0 0 GA_Time], 'Format','HH:mm:ss.SSS');
fprintf('\nElapsed Time: %23.15E\t\t%s\n\n', GA_Time, DT_GA_Time)
fprintf('Fitness value at convergence = %.4f\nGenerations \t\t\t\t = %d\n\n',fval,output.generations)
fprintf(1,'\tRate Constants:\n')
for k1 = 1:length(theta)
fprintf(1, '\t\tTheta(%2d) = %8.5f\n', k1, theta(k1))
end
tv = linspace(min(t), max(t));
Cfit = kinetics(theta, tv);
figure
hd = plot(t, c, 'p');
for k1 = 1:size(c,2)
CV(k1,:) = hd(k1).Color;
hd(k1).MarkerFaceColor = CV(k1,:);
end
hold on
hlp = plot(tv, Cfit);
for k1 = 1:size(c,2)
hlp(k1).Color = CV(k1,:);
end
hold off
grid
xlabel('Time')
ylabel('Concentration')
legend(hlp, compose('C_%d',1:size(c,2)), 'Location','N')
t = timeex;
function C=kinetics(theta,t)
c0 = theta(11:15);
% [um,KG,k1prime,K1G,K1B,k2,K2G,YXG,m,k3] = num2cell(theta(1:10))
um = theta(1);
KG = theta(2);
k1prime = theta(3);
K1G = theta(4);
K1B = theta(5);
k2 = theta(6);
K2G = theta(7);
YXG = theta(8);
m = theta(9);
k3 = theta(10);
DEfcn = @(t,Y,K1B,K1G,K2G,KG,YXG,k2,k3,k1prime,m,um)[-(k2.*Y(1))./(Y(3)./K2G+1.0)+(k1prime.*Y(2).*(1.0e+3./9.47e+2))./(Y(1)./K1B+Y(3)./K1G+1.0);-(k1prime.*Y(2))./(Y(1)./K1B+Y(3)./K1G+1.0);-m.*Y(4)+(k2.*Y(1).*(2.0e+1./1.9e+1))./(Y(3)./K2G+1.0)-(um.*Y(3).*Y(4))./(YXG.*(K1G+Y(3)));(um.*Y(3).*Y(4))./(KG+Y(3));(k3.*um.*Y(3).*Y(4))./(YXG.*(KG+Y(3)))];
% Y = rand(5,1);
%
% QQ = DEfcn(t,Y,K1B,K1G,K2G,KG,YXG,k2,k3,k1prime,m,um)
[t,Cv] = ode15s(@(t,Y)DEfcn(t,Y,K1B,K1G,K2G,KG,YXG,k2,k3,k1prime,m,um),t,c0);
C = Cv(:,[4,3,1,5]);
% Subs =
%
% B
% C
% G
% X
% E
end
% return
%
% % Subs =
% %
% % B
% % C
% % G
% % X
% % E
% % c0 = theta(7:10);
% % % c0=[1;0;0;0];
% % [T,Cv]=ode45(@DifEq,t,c0);
% % %
% % function dC=DifEq(t,c)
% % dcdt=zeros(4,1);
% % dcdt(1)=-theta(1).*c(1)-theta(2).*c(1);
% % dcdt(2)= theta(1).*c(1)+theta(4).*c(3)-theta(3).*c(2)-theta(5).*c(2);
% % dcdt(3)= theta(2).*c(1)+theta(3).*c(2)-theta(4).*c(3)+theta(6).*c(4);
% % dcdt(4)= theta(5).*c(2)-theta(6).*c(4);
% % dC=dcdt;
% % end
% % C=Cv;
%
%
% return
%
% %Set ODE solver
% % Initial cell biomass concentration (Initial condition)
% y0=[1.04 0.78 0.00 0.00];
%
% %Fermentation time
% tspan = linspace(0,72);
%
% %Set optimization problem
% %Let b = matrix of paramters to be determined
% % b= [um ks k1 K1G K1B k2 K2G YXG m k3]
% b = optimvar('b',10,"LowerBound",0,"UpperBound",72);
%
% %Set functions for ODE solver for solving ODE
% function solferment = toODE(b,tspan,y0)
% sol = ode45(@(t,y)batchferment(t,y,b),tspan,y0);
% solferment = deval(sol,tspan);
% end
%
% %Convert function for ODE solving to optimization expression
%
% %To use RtoODE in an objective function, convert the function to an
% %optimization expression by using fcn2optimexpr.
% myfcn = fcn2optimexpr(@toODE,b,timeex,y0);
%
% %Express the objective function as the sum of squared differences between
% %the ODE solution and the solution with true parameters.
% SSE = sum(sum((myfcn-yinv).^2));
%
% %Create an optimization problem with the objective function SSE.
% prob = optimproblem ("Description","Fit ODE parameters",'ObjectiveSense','min');
%
% %Objective function (to be minimized)
% prob.Objective = SSE;
%
% %Show structure of problem
% show(prob)
%
% %Solve Problem
% %To find the best-fitting parameters x, give an initial guess
% %x0 for the solver and call solve.
% % Set initial guesses of parameters
% initialGuess.b = [0.18 1.0 0.61 0.18 5.85 3.20 16.25 0.11 3.40 3.02];
%
% %Solve optimization problem
% [sol,optval] = solve(prob,initialGuess);
%
% %Extract the results
% %Fitted Parameters
% bfinal =sol.b;
%
% %Sum of square Error
% SSEfinal = optval;
%
%
% %Plot the simulated data and experimental data
% %Call ODE to solve an equation using Final Fitted Parameters (bfinal)
% solysim = ode45(@(t,y)batchferment(t,y,bfinal),tspan,y0);
% %Evaluate the simulated results at specified tspan
% ysim = deval(solysim,tspan);
%
% %Plot graphs
% figure;
% plot(timeex,Xdata,'*r',tspan,ysim(1,:),'-b')
% legend('exp','sim')
% xlabel('Time (h)')
% ylabel('X (g/L)')
%
% figure;
% plot(timeex,Gdata','*r',tspan,ysim(2,:),'-b')
% legend('exp','sim')
% xlabel('Time (h)')
% ylabel('G (g/L)')
%
% figure;
% plot(timeex,Bdata','*r',tspan,ysim(3,:),'-b')
% legend('exp','sim')
% xlabel('Time (h)')
% ylabel('B (g/L)')
%
% figure;
% plot(timeex,Edata','*r',tspan,ysim(4,:),'-b')
% legend('exp','sim')
% xlabel('Time (h)')
% ylabel('E (g/L)')
%
%
% %Equations for Batch
% %y(1) = X = Biomass Concentration (g/l)
% %y(2) = G = Glucose Concentration (g/l)
% %y(3) = B = Cellobiose Concentration (g/L)
% %y(4) = E = Ethanol Concentration (g/l)
%
% function dydt = batchferment(t,y,b)
%
% % y(1) = X;
% % y(2) = G;
% % y(3) = B;
% % y(4) = E;
% X = y(1);
% G = y(2);
% B = y(3);
% E = y(4);
%
% %%%Growth equations
% %dx/dt = (um*X*G)/(KG+G)
% u = (b(1)*y(1)*y(2))/(b(2)+y(2));
% %u = (b(1)*X*G)/(b(2)+G);
% %parameters
% % b(1) = um (1/h);
% % b(2) = ks (g/L);
% um = b(1);
% ks = b(2);
%
%
% %%%Cellobiose equations
% C = b(1)-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04));
% r1 = (b(3)*C)/(1+(y(2)/b(4))+(y(3)/b(5)));
% r2 = (b(6)*y(3))/(1+(y(2)/b(7)));
% % b(3) = k1;
% % b(4) = K1G;
% % b(5) = K1B;
% % b(6) = k2;
% % b(7) = K2G;
% k1 = b(3);
% K1G = b(4);
% K1B = b(5);
% k2 = b(6);
% k2G = b(7);
%
% %C = Cellulose concentration (g/l)
% %C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
% %r1 = (k1*C)/(1+(G/K1G)+(B/K1B))
% %r2 = (k2*B)/(1+(G/K2G)
%
% %C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
% %C = 83.65-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04))
%
%
% %%% Glucose equations
% % rG = ((1/b(8))*(dx/dt))-(b(9)*y(1));
% % b(8) = YXG;
% % b(9) = m;
% YXG = b(8)
% m = b(9);
% %rG = ((1/YXG)*(dX/dt))-(m*X)
%
%
% %%% Ethanol Concentration
%
% % b(10) = k3;
% k3 = b(10);
% Et = k3*(u*X)*(1/YXG);
%
% %Material balance equations
% dXdt = u*X;
% rG = ((1/b(8))*(dXdt))-(b(9)*y(1));
% dGdt = (r2/0.95)-rG;
% dBdt = (r1/0.947)-r2;
% dEdt = Et;
% dydt = [dXdt;dGdt;dBdt;dEdt];
% end
.

Connectez-vous pour commenter.

Plus de réponses (1)

Torsten
Torsten le 15 Août 2024
Modifié(e) : Torsten le 15 Août 2024
I replaced
C = b(11)-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04));
by
C = b(1)-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04));
in your code. b(11) does not exist.
And I was not sure what to insert for dx/dt in
rG = ((1/b(8))*(dx/dt))-(b(9)*y(1));
I used
rG = 1/b(8)*u-b(9)*y(1);
Maybe it must be
rG = 1/b(8)*u*X-b(9)*y(1);
The ODE integrator has problems with your differential equations at t = 6.19.
And to restrict all your parameters to be between 0 and 72 is quite strange - especially because tspan ends at 72.
%Fermentation data
Xdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','e2:e13');
Gdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','b2:b13');
Bdata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','c2:c13');
Edata = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','d2:d13');
% Group all data into yariable y
yinv =[Xdata'; Gdata'; Bdata'; Edata'];
%Data for time
timeex = readmatrix('Batch1.xlsx','Sheet','sheet1','Range','a2:a13');
%Set ODE solver
% Initial cell biomass concentration (Initial condition)
y0=[1.04 0.78 0.00 0.00];
%Fermentation time
tspan = linspace(0,72);
%Set optimization problem
%Let b = matrix of paramters to be determined
% b= [um ks k1 K1G K1B k2 K2G YXG m k3]
%b = optimvar('b',10,"LowerBound",0,"UpperBound",72);
%Convert function for ODE solving to optimization expression
%To use RtoODE in an objective function, convert the function to an
%optimization expression by using fcn2optimexpr.
%myfcn = fcn2optimexpr(@toODE,b,timeex,y0);
%Express the objective function as the sum of squared differences between
%the ODE solution and the solution with true parameters.
%SSE = sum(sum((myfcn-yinv).^2));
%Create an optimization problem with the objective function SSE.
%prob = optimproblem ("Description","Fit ODE parameters",'ObjectiveSense','min');
%Objective function (to be minimized)
%prob.Objective = SSE;
%Show structure of problem
%show(prob)
%Solve Problem
%To find the best-fitting parameters x, give an initial guess
%x0 for the solver and call solve.
% Set initial guesses of parameters
b0 = [0.18 1.0 0.61 0.18 5.85 3.20 16.25 0.11 3.40 3.02];
%Solve optimization problem
%[sol,optval] = solve(prob,initialGuess);
[bfinal,SSEfinal] = lsqcurvefit(@(b,xdata)toODE(b,xdata,y0),b0,timeex,yinv)
Warning: Failure at t=6.192305e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.421085e-14) at time t.
Error using lsqcurvefit (line 312)
Function value and YDATA sizes are not equal.
%Extract the results
%Fitted Parameters
%bfinal =sol.b;
%Sum of square Error
%SSEfinal = optval;
%Plot the simulated data and experimental data
%Call ODE to solve an equation using Final Fitted Parameters (bfinal)
[~,ysim] = ode15s(@(t,y)batchferment(t,y,bfinal),tspan,y0);
%Evaluate the simulated results at specified tspan
%ysim = deval(solysim,tspan);
%Plot graphs
figure;
plot(timeex,Xdata,'*r',tspan,ysim(1,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('X (g/L)')
figure;
plot(timeex,Gdata','*r',tspan,ysim(2,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('G (g/L)')
figure;
plot(timeex,Bdata','*r',tspan,ysim(3,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('B (g/L)')
figure;
plot(timeex,Edata','*r',tspan,ysim(4,:),'-b')
legend('exp','sim')
xlabel('Time (h)')
ylabel('E (g/L)')
%Set functions for ODE solver for solving ODE
function solferment = toODE(b,timeex,y0)
[~,solferment] = ode15s(@(t,y)batchferment(t,y,b),timeex,y0);
%solferment = deval(sol,tspan);
end
%Equations for Batch
%y(1) = X = Biomass Concentration (g/l)
%y(2) = G = Glucose Concentration (g/l)
%y(3) = B = Cellobiose Concentration (g/L)
%y(4) = E = Ethanol Concentration (g/l)
function dydt = batchferment(t,y,b)
X=y(1) ;
G=y(2) ;
B=y(3) ;
E=y(4) ;
%%%Growth equations
%dx/dt = (um*X*G)/(KG+G)
u = (b(1)*y(1)*y(2))/(b(2)+y(2));
%u = (b(1)*X*G)/(b(2)+G);
%parameters
um=b(1); % (1/h);
ks=b(2); % (g/L);
%%%Cellobiose equations
C = b(1)-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04));
r1 = (b(3)*C)/(1+(y(2)/b(4))+(y(3)/b(5)));
r2 = (b(6)*y(3))/(1+(y(2)/b(7)));
k1=b(3) ;
K1G=b(4) ;
K1B=b(5) ;
k2=b(6) ;
K2G=b(7) ;
%C = Cellulose concentration (g/l)
%C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
%r1 = (k1*C)/(1+(G/K1G)+(B/K1B))
%r2 = (k2*B)/(1+(G/K2G)
%C = C0-(0.9*G)-(0.947*B)-(0.9*E/0.511)-(1.137*(X-X0))
%C = 83.65-(0.9*y(2))-(0.947*y(3))-(0.9*y(4)/0.511)-(1.137*(y(1)-1.04))
%%% Glucose equations
rG = 1/b(8)*u-b(9)*y(1);
YXG=b(8) ;
m=b(9) ;
%rG = ((1/YXG)*(dX/dt))-(m*X)
%%% Ethanol Concentration
k3=b(10) ;
Et = k3*(u*X)*(1/YXG);
%Material balance equations
dXdt = u*X;
dGdt = (r2/0.95)-rG;
dBdt = (r1/0.947)-r2;
dEdt = Et;
dydt = [dXdt;dGdt;dBdt;dEdt];
end
  2 commentaires
Alfred
Alfred le 26 Août 2024
Thanks @Torsten. I am still facing errors.
Alfred
Alfred le 26 Août 2024
I chose the tspan to end at 72 because the time in the works ends at 72 hours. Is there something I don't understand with tspan? Kindly explain to me.
Thanks

Connectez-vous pour commenter.

Catégories

En savoir plus sur Fit Postprocessing dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by